mirror of https://github.com/apache/jclouds.git
Issue 543: added ability to reset default login user's password
This commit is contained in:
parent
4b879402fd
commit
0c3a0ac7ee
|
@ -133,7 +133,7 @@ public class ScriptBuilder implements Statement {
|
||||||
new Function<Statement, Iterable<String>>() {
|
new Function<Statement, Iterable<String>>() {
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> apply(Statement from) {
|
public Iterable<String> apply(Statement from) {
|
||||||
return from.functionDependecies(osFamily);
|
return from.functionDependencies(osFamily);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
List<String> unresolvedFunctions = Lists.newArrayList(dependentFunctions);
|
List<String> unresolvedFunctions = Lists.newArrayList(dependentFunctions);
|
||||||
|
@ -144,7 +144,7 @@ public class ScriptBuilder implements Statement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> functionDependecies(OsFamily family) {
|
public Iterable<String> functionDependencies(OsFamily family) {
|
||||||
return ImmutableSet.<String> of();
|
return ImmutableSet.<String> of();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -64,7 +64,7 @@ public class AppendFile implements Statement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> functionDependecies(OsFamily family) {
|
public Iterable<String> functionDependencies(OsFamily family) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ public class Call implements Statement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> functionDependecies(OsFamily family) {
|
public Iterable<String> functionDependencies(OsFamily family) {
|
||||||
return ImmutableList.of(function);
|
return ImmutableList.of(function);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -69,7 +69,7 @@ public class CreateRunScript implements Statement {
|
||||||
"echo title {title}>>{file}\r\n");
|
"echo title {title}>>{file}\r\n");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> functionDependecies(OsFamily family) {
|
public Iterable<String> functionDependencies(OsFamily family) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ public class CreateRunScript implements Statement {
|
||||||
"echo set {export}={value}>>{file}\r\n");
|
"echo set {export}={value}>>{file}\r\n");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> functionDependecies(OsFamily family) {
|
public Iterable<String> functionDependencies(OsFamily family) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ public class CreateRunScript implements Statement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> functionDependecies(OsFamily family) {
|
public Iterable<String> functionDependencies(OsFamily family) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ public class InterpretableStatement implements Statement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> functionDependecies(OsFamily family) {
|
public Iterable<String> functionDependencies(OsFamily family) {
|
||||||
return ImmutableList.of();
|
return ImmutableList.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ public class Kill implements Statement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> functionDependecies(OsFamily family) {
|
public Iterable<String> functionDependencies(OsFamily family) {
|
||||||
return ImmutableList.of();
|
return ImmutableList.of();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -24,7 +24,7 @@ package org.jclouds.scriptbuilder.domain;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public interface Statement {
|
public interface Statement {
|
||||||
Iterable<String> functionDependecies(OsFamily family);
|
Iterable<String> functionDependencies(OsFamily family);
|
||||||
|
|
||||||
String render(OsFamily family);
|
String render(OsFamily family);
|
||||||
}
|
}
|
|
@ -51,10 +51,10 @@ public class StatementList implements Statement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> functionDependecies(OsFamily family) {
|
public Iterable<String> functionDependencies(OsFamily family) {
|
||||||
List<String> functions = Lists.newArrayList();
|
List<String> functions = Lists.newArrayList();
|
||||||
for (Statement statement : statements) {
|
for (Statement statement : statements) {
|
||||||
Iterables.addAll(functions, statement.functionDependecies(family));
|
Iterables.addAll(functions, statement.functionDependencies(family));
|
||||||
}
|
}
|
||||||
return functions;
|
return functions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ public class Statements {
|
||||||
return new Statement() {
|
return new Statement() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> functionDependecies(OsFamily family) {
|
public Iterable<String> functionDependencies(OsFamily family) {
|
||||||
return ImmutableList.of();
|
return ImmutableList.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,10 +126,10 @@ public class SwitchArg implements Statement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> functionDependecies(OsFamily family) {
|
public Iterable<String> functionDependencies(OsFamily family) {
|
||||||
List<String> functions = Lists.newArrayList();
|
List<String> functions = Lists.newArrayList();
|
||||||
for (Statement statement : valueToActions.values()) {
|
for (Statement statement : valueToActions.values()) {
|
||||||
Iterables.addAll(functions, statement.functionDependecies(family));
|
Iterables.addAll(functions, statement.functionDependencies(family));
|
||||||
}
|
}
|
||||||
return functions;
|
return functions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.jclouds.scriptbuilder.statements.login;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import org.jclouds.encryption.internal.JCECrypto;
|
||||||
|
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||||
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
|
import org.jclouds.scriptbuilder.domain.StatementList;
|
||||||
|
import org.jclouds.scriptbuilder.domain.Statements;
|
||||||
|
import org.jclouds.scriptbuilder.util.Sha512Crypt;
|
||||||
|
|
||||||
|
import com.google.common.base.Throwables;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class ReplaceShadowPasswordEntry implements Statement {
|
||||||
|
|
||||||
|
private final String login;
|
||||||
|
private final String password;
|
||||||
|
|
||||||
|
public ReplaceShadowPasswordEntry(String login, String password) {
|
||||||
|
this.login = checkNotNull(login, "login");
|
||||||
|
this.password = checkNotNull(password, "password");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<String> functionDependencies(OsFamily family) {
|
||||||
|
return ImmutableList.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String render(OsFamily family) {
|
||||||
|
checkNotNull(family, "family");
|
||||||
|
if (family == OsFamily.WINDOWS)
|
||||||
|
throw new UnsupportedOperationException("windows not yet implemented");
|
||||||
|
try {
|
||||||
|
String shadowPasswordEntry = Sha512Crypt.makeShadowLine(password, null, new JCECrypto());
|
||||||
|
String shadowFile = "/etc/shadow";
|
||||||
|
Statement replaceEntryInTempFile = Statements
|
||||||
|
.exec(String
|
||||||
|
.format(
|
||||||
|
"awk -v user=^%1$s: -v password='%2$s' 'BEGIN { FS=OFS=\":\" } $0 ~ user { $2 = password } 1' %3$s >%3$s.%1$s",
|
||||||
|
login, shadowPasswordEntry, shadowFile));
|
||||||
|
Statement replaceShadowFile = Statements.exec(String.format("test -f %2$s.%1$s && mv %2$s.%1$s %2$s", login,
|
||||||
|
shadowFile));
|
||||||
|
return new StatementList(ImmutableList.of(replaceEntryInTempFile, replaceShadowFile)).render(family);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((login == null) ? 0 : login.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
ReplaceShadowPasswordEntry other = (ReplaceShadowPasswordEntry) obj;
|
||||||
|
if (login == null) {
|
||||||
|
if (other.login != null)
|
||||||
|
return false;
|
||||||
|
} else if (!login.equals(other.login))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.jclouds.scriptbuilder.statements.login;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class ReplaceShadowPasswordEntryOfLoginUser extends ReplaceShadowPasswordEntry {
|
||||||
|
|
||||||
|
public ReplaceShadowPasswordEntryOfLoginUser(String password) {
|
||||||
|
super("${SUDO_USER:=${USER}}", password);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.jclouds.scriptbuilder.statements.login;
|
||||||
|
|
||||||
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Statements used to manipulate the shadow file
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class ShadowStatements {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* note must be run as root, and will either reset the root password, or
|
||||||
|
* whoever sudoed to root.
|
||||||
|
*/
|
||||||
|
public static Statement resetLoginUserPasswordTo(String password) {
|
||||||
|
return new ReplaceShadowPasswordEntryOfLoginUser(password);
|
||||||
|
}
|
||||||
|
}
|
|
@ -52,7 +52,7 @@ public class Sudoers implements Statement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> functionDependecies(OsFamily family) {
|
public Iterable<String> functionDependencies(OsFamily family) {
|
||||||
return ImmutableList.of();
|
return ImmutableList.of();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -128,7 +128,7 @@ public class UserAdd implements Statement {
|
||||||
private final String shell;
|
private final String shell;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> functionDependecies(OsFamily family) {
|
public Iterable<String> functionDependencies(OsFamily family) {
|
||||||
return ImmutableList.of();
|
return ImmutableList.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class AuthorizeRSAPublicKeys implements Statement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> functionDependecies(OsFamily family) {
|
public Iterable<String> functionDependencies(OsFamily family) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class InstallRSAPrivateKey implements Statement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> functionDependecies(OsFamily family) {
|
public Iterable<String> functionDependencies(OsFamily family) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class SshdConfig implements Statement {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<String> functionDependecies(OsFamily family) {
|
public Iterable<String> functionDependencies(OsFamily family) {
|
||||||
return ImmutableList.of();
|
return ImmutableList.of();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.jclouds.scriptbuilder.statements.login;
|
||||||
|
|
||||||
|
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit")
|
||||||
|
public class ReplaceShadowPasswordEntryOfLoginUserTest {
|
||||||
|
|
||||||
|
public void testWithPasswordUNIX() {
|
||||||
|
String cmd = new ReplaceShadowPasswordEntryOfLoginUser("bar").render(OsFamily.UNIX);
|
||||||
|
assert cmd.startsWith("awk -v user=^${SUDO_USER:=${USER}}: -v password='$6$") : cmd;
|
||||||
|
assert cmd
|
||||||
|
.endsWith("' 'BEGIN { FS=OFS=\":\" } $0 ~ user { $2 = password } 1' /etc/shadow >/etc/shadow.${SUDO_USER:=${USER}}\ntest -f /etc/shadow.${SUDO_USER:=${USER}} && mv /etc/shadow.${SUDO_USER:=${USER}} /etc/shadow\n") : cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = UnsupportedOperationException.class)
|
||||||
|
public void testAddUserWindowsNotSupported() {
|
||||||
|
new ReplaceShadowPasswordEntryOfLoginUser("password").render(OsFamily.WINDOWS);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.jclouds.scriptbuilder.statements.login;
|
||||||
|
|
||||||
|
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit")
|
||||||
|
public class ReplaceShadowPasswordEntryTest {
|
||||||
|
|
||||||
|
public void testWithPasswordUNIX() {
|
||||||
|
String userAdd = new ReplaceShadowPasswordEntry("foo", "bar").render(OsFamily.UNIX);
|
||||||
|
assert userAdd.startsWith("awk -v user=^foo: -v password='$6$") : userAdd;
|
||||||
|
assert userAdd
|
||||||
|
.endsWith("' 'BEGIN { FS=OFS=\":\" } $0 ~ user { $2 = password } 1' /etc/shadow >/etc/shadow.foo\ntest -f /etc/shadow.foo && mv /etc/shadow.foo /etc/shadow\n") : userAdd;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = UnsupportedOperationException.class)
|
||||||
|
public void testAddUserWindowsNotSupported() {
|
||||||
|
new ReplaceShadowPasswordEntry("user", "password").render(OsFamily.WINDOWS);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue