Issue-1020 Add full name option for AdminUser and UserAdd

This commit is contained in:
vijaykiran 2012-07-23 23:23:43 +02:00
parent 6016272486
commit 7227d70c4e
8 changed files with 88 additions and 16 deletions

View File

@ -109,6 +109,7 @@ public class AdminAccess implements Statement {
} }
private String adminUsername; private String adminUsername;
private String adminFullName;
private String adminHome; private String adminHome;
private String adminPublicKey; private String adminPublicKey;
private File adminPublicKeyFile; private File adminPublicKeyFile;
@ -127,6 +128,12 @@ public class AdminAccess implements Statement {
return this; return this;
} }
public AdminAccess.Builder adminFullName(String adminFullName) {
this.adminFullName = adminFullName;
return this;
}
public AdminAccess.Builder adminHome(String adminHome) { public AdminAccess.Builder adminHome(String adminHome) {
this.adminHome = adminHome; this.adminHome = adminHome;
return this; return this;
@ -211,7 +218,7 @@ public class AdminAccess implements Statement {
String adminPrivateKey = this.adminPrivateKey; String adminPrivateKey = this.adminPrivateKey;
if (adminPrivateKey == null && adminPrivateKeyFile != null) if (adminPrivateKey == null && adminPrivateKeyFile != null)
adminPrivateKey = Files.toString(adminPrivateKeyFile, UTF_8); adminPrivateKey = Files.toString(adminPrivateKeyFile, UTF_8);
return new Config(adminUsername, adminHome, adminPublicKey, adminPrivateKey, adminPassword, loginPassword, return new Config(adminUsername, adminFullName, adminHome, adminPublicKey, adminPrivateKey, adminPassword, loginPassword,
lockSsh, grantSudoToAdminUser, authorizeAdminPublicKey, installAdminPrivateKey, resetLoginPassword, lockSsh, grantSudoToAdminUser, authorizeAdminPublicKey, installAdminPrivateKey, resetLoginPassword,
cryptFunction); cryptFunction);
} catch (IOException e) { } catch (IOException e) {
@ -222,6 +229,7 @@ public class AdminAccess implements Statement {
protected static class Config { protected static class Config {
private final String adminUsername; private final String adminUsername;
private final String adminFullName;
private final String adminHome; private final String adminHome;
private final String adminPublicKey; private final String adminPublicKey;
private final String adminPrivateKey; private final String adminPrivateKey;
@ -235,11 +243,12 @@ public class AdminAccess implements Statement {
private boolean authorizeAdminPublicKey; private boolean authorizeAdminPublicKey;
private boolean lockSsh; private boolean lockSsh;
protected Config(@Nullable String adminUsername, @Nullable String adminHome, @Nullable String adminPublicKey, protected Config(@Nullable String adminUsername, @Nullable String adminFullName, @Nullable String adminHome, @Nullable String adminPublicKey,
@Nullable String adminPrivateKey, @Nullable String adminPassword, @Nullable String loginPassword, @Nullable String adminPrivateKey, @Nullable String adminPassword, @Nullable String loginPassword,
boolean lockSsh, boolean grantSudoToAdminUser, boolean authorizeAdminPublicKey, boolean lockSsh, boolean grantSudoToAdminUser, boolean authorizeAdminPublicKey,
boolean installAdminPrivateKey, boolean resetLoginPassword, Function<String, String> cryptFunction) { boolean installAdminPrivateKey, boolean resetLoginPassword, Function<String, String> cryptFunction) {
this.adminUsername = adminUsername; this.adminUsername = adminUsername;
this.adminFullName = adminFullName;
this.adminHome = adminHome; this.adminHome = adminHome;
this.adminPublicKey = adminPublicKey; this.adminPublicKey = adminPublicKey;
this.adminPrivateKey = adminPrivateKey; this.adminPrivateKey = adminPrivateKey;
@ -267,6 +276,10 @@ public class AdminAccess implements Statement {
return adminUsername; return adminUsername;
} }
public String getAdminFullName() {
return adminFullName;
}
public String getAdminHome() { public String getAdminHome() {
return adminHome; return adminHome;
} }
@ -318,7 +331,8 @@ public class AdminAccess implements Statement {
@Override @Override
public String toString() { public String toString() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append("Config [adminUsername=").append(adminUsername).append(", adminHome=").append(adminHome) builder.append("Config [adminUsername=").append(adminUsername).append(", adminFullName=").append(adminFullName)
.append(", adminHome=").append(adminHome)
.append(", adminPublicKey=").append(adminPublicKey == null ? "null" : "present") .append(", adminPublicKey=").append(adminPublicKey == null ? "null" : "present")
.append(", adminPrivateKey=").append(adminPrivateKey == null ? "null" : "present") .append(", adminPrivateKey=").append(adminPrivateKey == null ? "null" : "present")
.append(", adminPassword=").append(adminPassword == null ? "null" : "present") .append(", adminPassword=").append(adminPassword == null ? "null" : "present")
@ -368,6 +382,7 @@ public class AdminAccess implements Statement {
Builder builder = AdminAccess.builder(configuration.cryptFunction()); Builder builder = AdminAccess.builder(configuration.cryptFunction());
builder.adminUsername(config.getAdminUsername() != null ? config.getAdminUsername() : configuration builder.adminUsername(config.getAdminUsername() != null ? config.getAdminUsername() : configuration
.defaultAdminUsername().get()); .defaultAdminUsername().get());
builder.adminFullName(config.getAdminFullName() != null ? config.getAdminFullName() : builder.adminUsername);
builder.adminHome(config.getAdminHome()); builder.adminHome(config.getAdminHome());
builder.adminPassword(config.getAdminPassword() != null ? config.getAdminPassword() : configuration builder.adminPassword(config.getAdminPassword() != null ? config.getAdminPassword() : configuration
.passwordGenerator().get()); .passwordGenerator().get());
@ -408,6 +423,7 @@ public class AdminAccess implements Statement {
ImmutableList.Builder<Statement> statements = ImmutableList.builder(); ImmutableList.Builder<Statement> statements = ImmutableList.builder();
UserAdd.Builder userBuilder = UserAdd.builder(); UserAdd.Builder userBuilder = UserAdd.builder();
userBuilder.login(config.getAdminUsername()); userBuilder.login(config.getAdminUsername());
userBuilder.fullName(config.getAdminFullName());
if (config.getAdminHome() != null) if (config.getAdminHome() != null)
userBuilder.home(config.getAdminHome()); userBuilder.home(config.getAdminHome());
if (config.shouldAuthorizeAdminPublicKey()) if (config.shouldAuthorizeAdminPublicKey())

View File

@ -25,6 +25,7 @@ import java.util.List;
import javax.inject.Named; import javax.inject.Named;
import com.google.common.base.*;
import org.jclouds.crypto.Sha512Crypt; import org.jclouds.crypto.Sha512Crypt;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.scriptbuilder.domain.OsFamily; import org.jclouds.scriptbuilder.domain.OsFamily;
@ -35,14 +36,11 @@ import org.jclouds.scriptbuilder.statements.ssh.AuthorizeRSAPublicKeys;
import org.jclouds.scriptbuilder.statements.ssh.InstallRSAPrivateKey; import org.jclouds.scriptbuilder.statements.ssh.InstallRSAPrivateKey;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.inject.Inject; import com.google.inject.Inject;
import org.jclouds.util.Strings2;
/** /**
* Creates a statement that will add a given user to a machine ("login"), with optional * Creates a statement that will add a given user to a machine ("login"), with optional
@ -69,6 +67,7 @@ public class UserAdd implements Statement {
private List<String> groups = Lists.newArrayList(); private List<String> groups = Lists.newArrayList();
private List<String> authorizeRSAPublicKeys = Lists.newArrayList(); private List<String> authorizeRSAPublicKeys = Lists.newArrayList();
private String shell = "/bin/bash"; private String shell = "/bin/bash";
private String fullName;
/** /**
* See --home in `man useradd`. * See --home in `man useradd`.
@ -128,18 +127,22 @@ public class UserAdd implements Statement {
return this; return this;
} }
public UserAdd.Builder fullName(String fullName) {
this.fullName = fullName;
return this;
}
public UserAdd build() { public UserAdd build() {
return new UserAdd(login, groups, password, RSAPrivateKey, authorizeRSAPublicKeys, home, defaultHome, shell); return new UserAdd(login, groups, password, RSAPrivateKey, authorizeRSAPublicKeys, home, defaultHome, shell, fullName);
} }
} }
public UserAdd(String login, List<String> groups, @Nullable String password, @Nullable String installRSAPrivateKey, public UserAdd(String login, List<String> groups, @Nullable String password, @Nullable String installRSAPrivateKey,
List<String> authorizeRSAPublicKeys, String defaultHome, String shell) { List<String> authorizeRSAPublicKeys, String defaultHome, String shell) {
this(login, groups, password, installRSAPrivateKey, authorizeRSAPublicKeys, null, defaultHome, shell); this(login, groups, password, installRSAPrivateKey, authorizeRSAPublicKeys, null, defaultHome, shell, login);
} }
public UserAdd(String login, List<String> groups, @Nullable String password, @Nullable String installRSAPrivateKey, public UserAdd(String login, List<String> groups, @Nullable String password, @Nullable String installRSAPrivateKey,
List<String> authorizeRSAPublicKeys, @Nullable String home, String defaultHome, String shell) { List<String> authorizeRSAPublicKeys, @Nullable String home, String defaultHome, String shell, String fullName) {
this.login = checkNotNull(login, "login"); this.login = checkNotNull(login, "login");
this.password = password; this.password = password;
this.groups = ImmutableList.copyOf(checkNotNull(groups, "groups")); this.groups = ImmutableList.copyOf(checkNotNull(groups, "groups"));
@ -149,6 +152,7 @@ public class UserAdd implements Statement {
this.home = home; this.home = home;
this.defaultHome = checkNotNull(defaultHome, "defaultHome"); this.defaultHome = checkNotNull(defaultHome, "defaultHome");
this.shell = checkNotNull(shell, "shell"); this.shell = checkNotNull(shell, "shell");
this.fullName = fullName;
} }
private final String home; private final String home;
@ -159,6 +163,7 @@ public class UserAdd implements Statement {
private final String installRSAPrivateKey; private final String installRSAPrivateKey;
private final List<String> authorizeRSAPublicKeys; private final List<String> authorizeRSAPublicKeys;
private final String shell; private final String shell;
private final String fullName;
private Function<String, String> cryptFunction = Sha512Crypt.function(); private Function<String, String> cryptFunction = Sha512Crypt.function();
@ -187,8 +192,13 @@ public class UserAdd implements Statement {
ImmutableMap.Builder<String, String> userAddOptions = ImmutableMap.builder(); ImmutableMap.Builder<String, String> userAddOptions = ImmutableMap.builder();
// Include the username as the full name for now. // Include the username as the full name for now.
userAddOptions.put("-c", login);
if (Strings.isNullOrEmpty(fullName)) {
userAddOptions.put("-c", login);
} else {
userAddOptions.put("-c", "'" + fullName + "'");
}
userAddOptions.put("-s", shell); userAddOptions.put("-s", shell);
if (groups.size() > 0) { if (groups.size() > 0) {
for (String group : groups) for (String group : groups)

View File

@ -52,15 +52,34 @@ public class AdminAccessTest {
try { try {
assertEquals( assertEquals(
AdminAccess.builder().adminPassword("bar").adminPrivateKey("fooPrivateKey") AdminAccess.builder().adminPassword("bar").adminPrivateKey("fooPrivateKey")
.adminPublicKey("fooPublicKey").adminUsername("foo").adminHome("/over/ridden/foo").build() .adminPublicKey("fooPublicKey").adminUsername("foo")
.adminHome("/over/ridden/foo").build()
.init(TestConfiguration.INSTANCE).render(OsFamily.UNIX), .init(TestConfiguration.INSTANCE).render(OsFamily.UNIX),
CharStreams.toString(Resources.newReaderSupplier( CharStreams.toString(Resources.newReaderSupplier(
Resources.getResource("test_adminaccess_params.sh"), Charsets.UTF_8))); Resources.getResource("test_adminaccess_params.sh"), Charsets.UTF_8)));
} finally { } finally {
TestConfiguration.INSTANCE.reset(); TestConfiguration.INSTANCE.reset();
} }
} }
public void testWithParamsAndFullNameUNIX() throws IOException {
TestConfiguration.INSTANCE.reset();
try {
assertEquals(
AdminAccess.builder().adminPassword("bar").adminPrivateKey("fooPrivateKey")
.adminPublicKey("fooPublicKey").adminUsername("foo").adminFullName("JClouds Foo")
.adminHome("/over/ridden/foo").build()
.init(TestConfiguration.INSTANCE).render(OsFamily.UNIX),
CharStreams.toString(Resources.newReaderSupplier(
Resources.getResource("test_adminaccess_params_and_fullname.sh"), Charsets.UTF_8)));
} finally {
TestConfiguration.INSTANCE.reset();
}
}
public void testOnlyInstallUserUNIX() throws IOException { public void testOnlyInstallUserUNIX() throws IOException {
TestConfiguration.INSTANCE.reset(); TestConfiguration.INSTANCE.reset();
try { try {

View File

@ -20,6 +20,7 @@ package org.jclouds.scriptbuilder.statements.login;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import org.jclouds.JcloudsVersion;
import org.jclouds.scriptbuilder.domain.OsFamily; import org.jclouds.scriptbuilder.domain.OsFamily;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -36,6 +37,12 @@ public class UserAddTest {
"mkdir -p /home/users\nuseradd -c me -s /bin/bash -m -d /home/users/me me\nchown -R me /home/users/me\n"); "mkdir -p /home/users\nuseradd -c me -s /bin/bash -m -d /home/users/me me\nchown -R me /home/users/me\n");
} }
public void testWithFullNameUNIX() {
assertEquals(UserAdd.builder().login("me").fullName("JClouds Guy").build().render(OsFamily.UNIX),
"mkdir -p /home/users\nuseradd -c 'JClouds Guy' -s /bin/bash -m -d /home/users/me me\nchown -R me /home/users/me\n");
}
public void testWithBaseUNIX() { public void testWithBaseUNIX() {
assertEquals(UserAdd.builder().login("me").defaultHome("/export/home").build().render(OsFamily.UNIX), assertEquals(UserAdd.builder().login("me").defaultHome("/export/home").build().render(OsFamily.UNIX),
"mkdir -p /export/home\nuseradd -c me -s /bin/bash -m -d /export/home/me me\nchown -R me /export/home/me\n"); "mkdir -p /export/home\nuseradd -c me -s /bin/bash -m -d /export/home/me me\nchown -R me /export/home/me\n");

View File

@ -5,7 +5,7 @@ END_OF_JCLOUDS_FILE
chmod 0440 /etc/sudoers chmod 0440 /etc/sudoers
mkdir -p /over/ridden mkdir -p /over/ridden
groupadd -f wheel groupadd -f wheel
useradd -c foo -s /bin/bash -g wheel -m -d /over/ridden/foo -p 'crypt(bar)' foo useradd -c 'foo' -s /bin/bash -g wheel -m -d /over/ridden/foo -p 'crypt(bar)' foo
mkdir -p /over/ridden/foo/.ssh mkdir -p /over/ridden/foo/.ssh
cat >> /over/ridden/foo/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE' cat >> /over/ridden/foo/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'
fooPublicKey fooPublicKey

View File

@ -0,0 +1,20 @@
cat > /etc/sudoers <<-'END_OF_JCLOUDS_FILE'
root ALL = (ALL) ALL
%wheel ALL = (ALL) NOPASSWD:ALL
END_OF_JCLOUDS_FILE
chmod 0440 /etc/sudoers
mkdir -p /over/ridden
groupadd -f wheel
useradd -c 'JClouds Foo' -s /bin/bash -g wheel -m -d /over/ridden/foo -p 'crypt(bar)' foo
mkdir -p /over/ridden/foo/.ssh
cat >> /over/ridden/foo/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'
fooPublicKey
END_OF_JCLOUDS_FILE
chmod 600 /over/ridden/foo/.ssh/authorized_keys
chown -R foo /over/ridden/foo
exec 3<> /etc/ssh/sshd_config && awk -v TEXT="PasswordAuthentication no
PermitRootLogin no
" 'BEGIN {print TEXT}{print}' /etc/ssh/sshd_config >&3
hash service 2>&- && service ssh reload 2>&- || /etc/init.d/ssh* reload
awk -v user=^${SUDO_USER:=${USER}}: -v password='crypt(0)' 'BEGIN { FS=OFS=":" } $0 ~ user { $2 = password } 1' /etc/shadow >/etc/shadow.${SUDO_USER:=${USER}}
test -f /etc/shadow.${SUDO_USER:=${USER}} && mv /etc/shadow.${SUDO_USER:=${USER}} /etc/shadow

View File

@ -1,5 +1,5 @@
mkdir -p /home/users mkdir -p /home/users
useradd -c defaultAdminUsername -s /bin/bash -m -d /home/users/defaultAdminUsername -p 'crypt(0)' defaultAdminUsername useradd -c 'defaultAdminUsername' -s /bin/bash -m -d /home/users/defaultAdminUsername -p 'crypt(0)' defaultAdminUsername
mkdir -p /home/users/defaultAdminUsername/.ssh mkdir -p /home/users/defaultAdminUsername/.ssh
cat >> /home/users/defaultAdminUsername/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE' cat >> /home/users/defaultAdminUsername/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'
publicKey publicKey

View File

@ -5,7 +5,7 @@ END_OF_JCLOUDS_FILE
chmod 0440 /etc/sudoers chmod 0440 /etc/sudoers
mkdir -p /home/users mkdir -p /home/users
groupadd -f wheel groupadd -f wheel
useradd -c defaultAdminUsername -s /bin/bash -g wheel -m -d /home/users/defaultAdminUsername -p 'crypt(0)' defaultAdminUsername useradd -c 'defaultAdminUsername' -s /bin/bash -g wheel -m -d /home/users/defaultAdminUsername -p 'crypt(0)' defaultAdminUsername
mkdir -p /home/users/defaultAdminUsername/.ssh mkdir -p /home/users/defaultAdminUsername/.ssh
cat >> /home/users/defaultAdminUsername/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE' cat >> /home/users/defaultAdminUsername/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'
publicKey publicKey