mirror of https://github.com/apache/jclouds.git
Issue 915: supports AdminAccess.adminHome, and UserAdd.home
Previously, UserAdd only supported 'defaultHome'. Now it supports 'home' as well. This involved changing the `mkdir` from making defaultHome to making the actual home (felt like easier production-code than getting the parent directory of 'home' to mkdir, but turned out to be a lot of test-code changes!). Added AdminAccess.adminHome, which is a direct pass-through to UserAdd.home.
This commit is contained in:
parent
2fef9008eb
commit
8b6af79214
|
@ -126,7 +126,7 @@ public class RunScriptOnNodeUsingSshTest {
|
|||
expect(sshClient.getUsername()).andReturn("tester");
|
||||
expect(sshClient.getHostAddress()).andReturn("somewhere.example.com");
|
||||
expect(
|
||||
sshClient.exec("sudo sh <<'RUN_SCRIPT_AS_ROOT_SSH'\n" + "mkdir -p /home/users\n"
|
||||
sshClient.exec("sudo sh <<'RUN_SCRIPT_AS_ROOT_SSH'\n" + "mkdir -p /home/users/testuser\n"
|
||||
+ "useradd -s /bin/bash -m -d /home/users/testuser testuser\n"
|
||||
+ "chown -R testuser /home/users/testuser\n" + "RUN_SCRIPT_AS_ROOT_SSH\n")).andReturn(
|
||||
new ExecResponse("done", null, 0));
|
||||
|
|
|
@ -244,9 +244,9 @@ public abstract class BaseComputeServiceLiveTest extends BaseComputeServiceConte
|
|||
checkNodes(nodes, group, "runScriptWithCreds");
|
||||
|
||||
// test adding AdminAccess later changes the default boot user, in this
|
||||
// case to foo
|
||||
// case to foo, with home dir /over/ridden/foo
|
||||
ListenableFuture<ExecResponse> future = client.submitScriptOnNode(node.getId(), AdminAccess.builder()
|
||||
.adminUsername("foo").build(), nameTask("adminUpdate"));
|
||||
.adminUsername("foo").adminHome("/over/ridden/foo").build(), nameTask("adminUpdate"));
|
||||
|
||||
response = future.get(3, TimeUnit.MINUTES);
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ END_OF_JCLOUDS_SCRIPT
|
|||
%wheel ALL = (ALL) NOPASSWD:ALL
|
||||
END_OF_JCLOUDS_FILE
|
||||
chmod 0440 /etc/sudoers
|
||||
mkdir -p /home/users
|
||||
mkdir -p /home/users/defaultAdminUsername
|
||||
groupadd -f wheel
|
||||
useradd -s /bin/bash -g wheel -m -d /home/users/defaultAdminUsername -p 'crypt(randompassword)' defaultAdminUsername
|
||||
mkdir -p /home/users/defaultAdminUsername/.ssh
|
||||
|
|
|
@ -182,7 +182,7 @@ END_OF_JCLOUDS_SCRIPT
|
|||
%wheel ALL = (ALL) NOPASSWD:ALL
|
||||
END_OF_JCLOUDS_FILE
|
||||
chmod 0440 /etc/sudoers
|
||||
mkdir -p /home/users
|
||||
mkdir -p /home/users/web
|
||||
groupadd -f wheel
|
||||
useradd -s /bin/bash -g wheel -m -d /home/users/web -p 'crypt(randompassword)' web
|
||||
mkdir -p /home/users/web/.ssh
|
||||
|
|
|
@ -89,15 +89,15 @@ END_OF_JCLOUDS_SCRIPT
|
|||
%wheel ALL = (ALL) NOPASSWD:ALL
|
||||
END_OF_JCLOUDS_FILE
|
||||
chmod 0440 /etc/sudoers
|
||||
mkdir -p /home/users
|
||||
mkdir -p /over/ridden/foo
|
||||
groupadd -f wheel
|
||||
useradd -s /bin/bash -g wheel -m -d /home/users/foo -p 'crypt(randompassword)' foo
|
||||
mkdir -p /home/users/foo/.ssh
|
||||
cat >> /home/users/foo/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'
|
||||
useradd -s /bin/bash -g wheel -m -d /over/ridden/foo -p 'crypt(randompassword)' foo
|
||||
mkdir -p /over/ridden/foo/.ssh
|
||||
cat >> /over/ridden/foo/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'
|
||||
publicKey
|
||||
END_OF_JCLOUDS_FILE
|
||||
chmod 600 /home/users/foo/.ssh/authorized_keys
|
||||
chown -R foo /home/users/foo
|
||||
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
|
||||
|
|
|
@ -109,6 +109,7 @@ public class AdminAccess implements Statement {
|
|||
}
|
||||
|
||||
private String adminUsername;
|
||||
private String adminHome;
|
||||
private String adminPublicKey;
|
||||
private File adminPublicKeyFile;
|
||||
private String adminPrivateKey;
|
||||
|
@ -126,6 +127,11 @@ public class AdminAccess implements Statement {
|
|||
return this;
|
||||
}
|
||||
|
||||
public AdminAccess.Builder adminHome(String adminHome) {
|
||||
this.adminHome = adminHome;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AdminAccess.Builder adminPassword(String adminPassword) {
|
||||
this.adminPassword = adminPassword;
|
||||
return this;
|
||||
|
@ -197,8 +203,8 @@ public class AdminAccess implements Statement {
|
|||
String adminPrivateKey = this.adminPrivateKey;
|
||||
if (adminPrivateKey == null && adminPrivateKeyFile != null)
|
||||
adminPrivateKey = Files.toString(adminPrivateKeyFile, UTF_8);
|
||||
return new Config(adminUsername, adminPublicKey, adminPrivateKey, adminPassword, loginPassword, lockSsh,
|
||||
grantSudoToAdminUser, authorizeAdminPublicKey, installAdminPrivateKey, resetLoginPassword,
|
||||
return new Config(adminUsername, adminHome, adminPublicKey, adminPrivateKey, adminPassword, loginPassword,
|
||||
lockSsh, grantSudoToAdminUser, authorizeAdminPublicKey, installAdminPrivateKey, resetLoginPassword,
|
||||
cryptFunction);
|
||||
} catch (IOException e) {
|
||||
throw Throwables.propagate(e);
|
||||
|
@ -208,6 +214,7 @@ public class AdminAccess implements Statement {
|
|||
|
||||
protected static class Config {
|
||||
private final String adminUsername;
|
||||
private final String adminHome;
|
||||
private final String adminPublicKey;
|
||||
private final String adminPrivateKey;
|
||||
private final String adminPassword;
|
||||
|
@ -220,11 +227,12 @@ public class AdminAccess implements Statement {
|
|||
private final Function<String, String> cryptFunction;
|
||||
private final Credentials adminCredentials;
|
||||
|
||||
protected Config(@Nullable String adminUsername, @Nullable String adminPublicKey,
|
||||
protected Config(@Nullable String adminUsername, @Nullable String adminHome, @Nullable String adminPublicKey,
|
||||
@Nullable String adminPrivateKey, @Nullable String adminPassword, @Nullable String loginPassword,
|
||||
boolean lockSsh, boolean grantSudoToAdminUser, boolean authorizeAdminPublicKey,
|
||||
boolean installAdminPrivateKey, boolean resetLoginPassword, Function<String, String> cryptFunction) {
|
||||
this.adminUsername = adminUsername;
|
||||
this.adminHome = adminHome;
|
||||
this.adminPublicKey = adminPublicKey;
|
||||
this.adminPrivateKey = adminPrivateKey;
|
||||
this.adminPassword = adminPassword;
|
||||
|
@ -245,6 +253,10 @@ public class AdminAccess implements Statement {
|
|||
return adminUsername;
|
||||
}
|
||||
|
||||
public String getAdminHome() {
|
||||
return adminHome;
|
||||
}
|
||||
|
||||
public String getAdminPublicKey() {
|
||||
return adminPublicKey;
|
||||
}
|
||||
|
@ -324,6 +336,7 @@ public class AdminAccess implements Statement {
|
|||
Builder builder = AdminAccess.builder(configuration.cryptFunction());
|
||||
builder.adminUsername(config.getAdminUsername() != null ? config.getAdminUsername() : configuration
|
||||
.defaultAdminUsername().get());
|
||||
builder.adminHome(config.getAdminHome());
|
||||
builder.adminPassword(config.getAdminPassword() != null ? config.getAdminPassword() : configuration
|
||||
.passwordGenerator().get());
|
||||
Map<String, String> adminSshKeys = (config.getAdminPublicKey() != null && config.getAdminPrivateKey() != null) ? ImmutableMap
|
||||
|
@ -363,6 +376,8 @@ public class AdminAccess implements Statement {
|
|||
ImmutableList.Builder<Statement> statements = ImmutableList.builder();
|
||||
UserAdd.Builder userBuilder = UserAdd.builder();
|
||||
userBuilder.login(config.getAdminUsername());
|
||||
if (config.getAdminHome() != null)
|
||||
userBuilder.home(config.getAdminHome());
|
||||
if (config.shouldAuthorizeAdminPublicKey())
|
||||
userBuilder.authorizeRSAPublicKey(config.getAdminPublicKey());
|
||||
userBuilder.password(config.getAdminPassword());
|
||||
|
|
|
@ -60,6 +60,7 @@ public class UserAdd implements Statement {
|
|||
|
||||
public static class Builder {
|
||||
private String defaultHome = "/home/users";
|
||||
private String home;
|
||||
private String login;
|
||||
private String password;
|
||||
private String RSAPrivateKey;
|
||||
|
@ -67,6 +68,17 @@ public class UserAdd implements Statement {
|
|||
private List<String> authorizeRSAPublicKeys = Lists.newArrayList();
|
||||
private String shell = "/bin/bash";
|
||||
|
||||
/**
|
||||
* See --home in `man useradd`.
|
||||
*/
|
||||
public UserAdd.Builder home(String home) {
|
||||
this.home = home;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* See --base-dir in `man useradd`.
|
||||
*/
|
||||
public UserAdd.Builder defaultHome(String defaultHome) {
|
||||
this.defaultHome = defaultHome;
|
||||
return this;
|
||||
|
@ -115,22 +127,29 @@ public class UserAdd implements Statement {
|
|||
}
|
||||
|
||||
public UserAdd build() {
|
||||
return new UserAdd(login, groups, password, RSAPrivateKey, authorizeRSAPublicKeys, defaultHome, shell);
|
||||
return new UserAdd(login, groups, password, RSAPrivateKey, authorizeRSAPublicKeys, home, defaultHome, shell);
|
||||
}
|
||||
}
|
||||
|
||||
public UserAdd(String login, List<String> groups, @Nullable String password, @Nullable String installRSAPrivateKey,
|
||||
List<String> authorizeRSAPublicKeys, String defaultHome, String shell) {
|
||||
this(login, groups, password, installRSAPrivateKey, authorizeRSAPublicKeys, null, defaultHome, shell);
|
||||
}
|
||||
|
||||
public UserAdd(String login, List<String> groups, @Nullable String password, @Nullable String installRSAPrivateKey,
|
||||
List<String> authorizeRSAPublicKeys, @Nullable String home, String defaultHome, String shell) {
|
||||
this.login = checkNotNull(login, "login");
|
||||
this.password = password;
|
||||
this.groups = ImmutableList.copyOf(checkNotNull(groups, "groups"));
|
||||
this.installRSAPrivateKey = installRSAPrivateKey;
|
||||
this.authorizeRSAPublicKeys = ImmutableList
|
||||
.copyOf(checkNotNull(authorizeRSAPublicKeys, "authorizeRSAPublicKeys"));
|
||||
this.home = home;
|
||||
this.defaultHome = checkNotNull(defaultHome, "defaultHome");
|
||||
this.shell = checkNotNull(shell, "shell");
|
||||
}
|
||||
|
||||
private final String home;
|
||||
private final String defaultHome;
|
||||
private final String login;
|
||||
private final List<String> groups;
|
||||
|
@ -159,10 +178,10 @@ public class UserAdd implements Statement {
|
|||
checkNotNull(family, "family");
|
||||
if (family == OsFamily.WINDOWS)
|
||||
throw new UnsupportedOperationException("windows not yet implemented");
|
||||
String homeDir = defaultHome + "{fs}" + login;
|
||||
String homeDir = (home != null) ? home : (defaultHome + "{fs}" + login);
|
||||
ImmutableList.Builder<Statement> statements = ImmutableList.builder();
|
||||
// useradd cannot create the default homedir
|
||||
statements.add(Statements.exec("{md} " + defaultHome));
|
||||
statements.add(Statements.exec("{md} " + homeDir));
|
||||
|
||||
ImmutableMap.Builder<String, String> userAddOptions = ImmutableMap.builder();
|
||||
userAddOptions.put("-s", shell);
|
||||
|
|
|
@ -52,8 +52,9 @@ public class AdminAccessTest {
|
|||
try {
|
||||
assertEquals(
|
||||
AdminAccess.builder().adminPassword("bar").adminPrivateKey("fooPrivateKey")
|
||||
.adminPublicKey("fooPublicKey").adminUsername("foo").build().init(TestConfiguration.INSTANCE)
|
||||
.render(OsFamily.UNIX), CharStreams.toString(Resources.newReaderSupplier(
|
||||
.adminPublicKey("fooPublicKey").adminUsername("foo").adminHome("/over/ridden/foo").build()
|
||||
.init(TestConfiguration.INSTANCE).render(OsFamily.UNIX),
|
||||
CharStreams.toString(Resources.newReaderSupplier(
|
||||
Resources.getResource("test_adminaccess_params.sh"), Charsets.UTF_8)));
|
||||
} finally {
|
||||
TestConfiguration.INSTANCE.reset();
|
||||
|
|
|
@ -33,41 +33,51 @@ public class UserAddTest {
|
|||
|
||||
public void testUNIX() {
|
||||
assertEquals(UserAdd.builder().login("me").build().render(OsFamily.UNIX),
|
||||
"mkdir -p /home/users\nuseradd -s /bin/bash -m -d /home/users/me me\nchown -R me /home/users/me\n");
|
||||
"mkdir -p /home/users/me\nuseradd -s /bin/bash -m -d /home/users/me me\nchown -R me /home/users/me\n");
|
||||
}
|
||||
|
||||
public void testWithBaseUNIX() {
|
||||
assertEquals(UserAdd.builder().login("me").defaultHome("/export/home").build().render(OsFamily.UNIX),
|
||||
"mkdir -p /export/home\nuseradd -s /bin/bash -m -d /export/home/me me\nchown -R me /export/home/me\n");
|
||||
"mkdir -p /export/home/me\nuseradd -s /bin/bash -m -d /export/home/me me\nchown -R me /export/home/me\n");
|
||||
}
|
||||
|
||||
public void testWithGroupUNIX() {
|
||||
assertEquals(UserAdd.builder().login("me").group("wheel").build().render(OsFamily.UNIX),
|
||||
"mkdir -p /home/users\ngroupadd -f wheel\nuseradd -s /bin/bash -g wheel -m -d /home/users/me me\nchown -R me /home/users/me\n");
|
||||
"mkdir -p /home/users/me\ngroupadd -f wheel\nuseradd -s /bin/bash -g wheel -m -d /home/users/me me\nchown -R me /home/users/me\n");
|
||||
}
|
||||
|
||||
public void testWithGroupsUNIX() {
|
||||
assertEquals(UserAdd.builder().login("me").groups(ImmutableList.of("wheel", "candy")).build().render(
|
||||
OsFamily.UNIX),
|
||||
"mkdir -p /home/users\ngroupadd -f wheel\ngroupadd -f candy\nuseradd -s /bin/bash -g wheel -G candy -m -d /home/users/me me\nchown -R me /home/users/me\n");
|
||||
"mkdir -p /home/users/me\ngroupadd -f wheel\ngroupadd -f candy\nuseradd -s /bin/bash -g wheel -G candy -m -d /home/users/me me\nchown -R me /home/users/me\n");
|
||||
}
|
||||
|
||||
public void testWithPasswordUNIX() {
|
||||
String userAdd = UserAdd.builder().login("me").password("foo").group("wheel").build().render(OsFamily.UNIX);
|
||||
assert userAdd.startsWith("mkdir -p /home/users\ngroupadd -f wheel\nuseradd -s /bin/bash -g wheel -m -d /home/users/me -p '$6$") : userAdd;
|
||||
assert userAdd.startsWith("mkdir -p /home/users/me\ngroupadd -f wheel\nuseradd -s /bin/bash -g wheel -m -d /home/users/me -p '$6$") : userAdd;
|
||||
assert userAdd.endsWith("' me\nchown -R me /home/users/me\n") : userAdd;
|
||||
}
|
||||
|
||||
public void testWithSshAuthorizedKeyUNIX() {
|
||||
assertEquals(
|
||||
UserAdd.builder().login("me").authorizeRSAPublicKey("rsapublickey").build().render(OsFamily.UNIX),
|
||||
"mkdir -p /home/users\nuseradd -s /bin/bash -m -d /home/users/me me\nmkdir -p /home/users/me/.ssh\ncat >> /home/users/me/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'\n\trsapublickey\nEND_OF_JCLOUDS_FILE\nchmod 600 /home/users/me/.ssh/authorized_keys\nchown -R me /home/users/me\n");
|
||||
"mkdir -p /home/users/me\nuseradd -s /bin/bash -m -d /home/users/me me\nmkdir -p /home/users/me/.ssh\ncat >> /home/users/me/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'\n\trsapublickey\nEND_OF_JCLOUDS_FILE\nchmod 600 /home/users/me/.ssh/authorized_keys\nchown -R me /home/users/me\n");
|
||||
}
|
||||
|
||||
public void testWithSshInstalledKeyUNIX() {
|
||||
assertEquals(
|
||||
UserAdd.builder().login("me").installRSAPrivateKey("rsaprivate").build().render(OsFamily.UNIX),
|
||||
"mkdir -p /home/users\nuseradd -s /bin/bash -m -d /home/users/me me\nmkdir -p /home/users/me/.ssh\nrm /home/users/me/.ssh/id_rsa\ncat >> /home/users/me/.ssh/id_rsa <<-'END_OF_JCLOUDS_FILE'\n\trsaprivate\nEND_OF_JCLOUDS_FILE\nchmod 600 /home/users/me/.ssh/id_rsa\nchown -R me /home/users/me\n");
|
||||
"mkdir -p /home/users/me\nuseradd -s /bin/bash -m -d /home/users/me me\nmkdir -p /home/users/me/.ssh\nrm /home/users/me/.ssh/id_rsa\ncat >> /home/users/me/.ssh/id_rsa <<-'END_OF_JCLOUDS_FILE'\n\trsaprivate\nEND_OF_JCLOUDS_FILE\nchmod 600 /home/users/me/.ssh/id_rsa\nchown -R me /home/users/me\n");
|
||||
}
|
||||
|
||||
public void testWithHomeUNIX() {
|
||||
assertEquals(UserAdd.builder().login("me").home("/myhome/myme").build().render(
|
||||
OsFamily.UNIX),
|
||||
"mkdir -p /myhome/myme\nuseradd -s /bin/bash -m -d /myhome/myme me\nchown -R me /myhome/myme\n");
|
||||
|
||||
assertEquals(UserAdd.builder().login("me").home("/myhome/myme").defaultHome("/ignoreddefault").build().render(
|
||||
OsFamily.UNIX),
|
||||
"mkdir -p /myhome/myme\nuseradd -s /bin/bash -m -d /myhome/myme me\nchown -R me /myhome/myme\n");
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = UnsupportedOperationException.class)
|
||||
|
|
|
@ -3,15 +3,15 @@ cat > /etc/sudoers <<-'END_OF_JCLOUDS_FILE'
|
|||
%wheel ALL = (ALL) NOPASSWD:ALL
|
||||
END_OF_JCLOUDS_FILE
|
||||
chmod 0440 /etc/sudoers
|
||||
mkdir -p /home/users
|
||||
mkdir -p /over/ridden/foo
|
||||
groupadd -f wheel
|
||||
useradd -s /bin/bash -g wheel -m -d /home/users/foo -p 'crypt(bar)' foo
|
||||
mkdir -p /home/users/foo/.ssh
|
||||
cat >> /home/users/foo/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'
|
||||
useradd -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 /home/users/foo/.ssh/authorized_keys
|
||||
chown -R foo /home/users/foo
|
||||
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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
mkdir -p /home/users
|
||||
mkdir -p /home/users/defaultAdminUsername
|
||||
useradd -s /bin/bash -m -d /home/users/defaultAdminUsername -p 'crypt(0)' defaultAdminUsername
|
||||
mkdir -p /home/users/defaultAdminUsername/.ssh
|
||||
cat >> /home/users/defaultAdminUsername/.ssh/authorized_keys <<-'END_OF_JCLOUDS_FILE'
|
||||
|
|
|
@ -3,7 +3,7 @@ cat > /etc/sudoers <<-'END_OF_JCLOUDS_FILE'
|
|||
%wheel ALL = (ALL) NOPASSWD:ALL
|
||||
END_OF_JCLOUDS_FILE
|
||||
chmod 0440 /etc/sudoers
|
||||
mkdir -p /home/users
|
||||
mkdir -p /home/users/defaultAdminUsername
|
||||
groupadd -f wheel
|
||||
useradd -s /bin/bash -g wheel -m -d /home/users/defaultAdminUsername -p 'crypt(0)' defaultAdminUsername
|
||||
mkdir -p /home/users/defaultAdminUsername/.ssh
|
||||
|
|
Loading…
Reference in New Issue