EMMA Coverage Report (generated Wed Jun 22 19:47:49 EDT 2011)
[all classes][org.jclouds.scriptbuilder.statements.login]

COVERAGE SUMMARY FOR SOURCE FILE [AdminAccess.java]

nameclass, %method, %block, %line, %
AdminAccess.java100% (2/2)83%  (19/23)91%  (402/442)88%  (93.9/107)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class AdminAccess$Builder100% (1/1)87%  (13/15)79%  (121/153)77%  (37/48)
adminPrivateKey (File): AdminAccess$Builder 0%   (0/1)0%   (0/8)0%   (0/3)
adminPublicKey (File): AdminAccess$Builder 0%   (0/1)0%   (0/8)0%   (0/3)
build (): AdminAccess 100% (1/1)71%  (40/56)50%  (5/10)
AdminAccess$Builder (): void 100% (1/1)100% (4/4)100% (2/2)
AdminAccess$Builder (Function): void 100% (1/1)100% (21/21)100% (8/8)
adminPassword (String): AdminAccess$Builder 100% (1/1)100% (5/5)100% (2/2)
adminPrivateKey (String): AdminAccess$Builder 100% (1/1)100% (8/8)100% (3/3)
adminPublicKey (String): AdminAccess$Builder 100% (1/1)100% (8/8)100% (3/3)
adminUsername (String): AdminAccess$Builder 100% (1/1)100% (5/5)100% (2/2)
authorizeAdminPublicKey (boolean): AdminAccess$Builder 100% (1/1)100% (5/5)100% (2/2)
grantSudoToAdminUser (boolean): AdminAccess$Builder 100% (1/1)100% (5/5)100% (2/2)
installAdminPrivateKey (boolean): AdminAccess$Builder 100% (1/1)100% (5/5)100% (2/2)
lockSsh (boolean): AdminAccess$Builder 100% (1/1)100% (5/5)100% (2/2)
loginPassword (String): AdminAccess$Builder 100% (1/1)100% (5/5)100% (2/2)
resetLoginPassword (boolean): AdminAccess$Builder 100% (1/1)100% (5/5)100% (2/2)
     
class AdminAccess100% (1/1)75%  (6/8)97%  (281/289)97%  (56.9/59)
functionDependencies (OsFamily): Iterable 0%   (0/1)0%   (0/2)0%   (0/1)
getAdminCredentials (): Credentials 0%   (0/1)0%   (0/3)0%   (0/1)
apply (AdminAccess$Configuration): AdminAccess 100% (1/1)97%  (101/104)100% (12.9/13)
AdminAccess (String, String, String, String, String, boolean, boolean, boolea... 100% (1/1)100% (53/53)100% (16/16)
builder (): AdminAccess$Builder 100% (1/1)100% (4/4)100% (1/1)
builder (Function): AdminAccess$Builder 100% (1/1)100% (5/5)100% (1/1)
render (OsFamily): String 100% (1/1)100% (113/113)100% (25/25)
standard (): AdminAccess 100% (1/1)100% (5/5)100% (1/1)

1/**
2 *
3 * Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
4 *
5 * ====================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 * ====================================================================
18 */
19package org.jclouds.scriptbuilder.statements.login;
20 
21import static com.google.common.base.Charsets.UTF_8;
22import static com.google.common.base.Preconditions.checkNotNull;
23 
24import java.io.File;
25import java.io.IOException;
26import java.util.Map;
27 
28import javax.annotation.Nullable;
29 
30import org.jclouds.crypto.Sha512Crypt;
31import org.jclouds.domain.Credentials;
32import org.jclouds.scriptbuilder.domain.OsFamily;
33import org.jclouds.scriptbuilder.domain.Statement;
34import org.jclouds.scriptbuilder.domain.StatementList;
35import org.jclouds.scriptbuilder.statements.login.AdminAccess.Configuration;
36import org.jclouds.scriptbuilder.statements.ssh.SshStatements;
37 
38import com.google.common.base.Function;
39import com.google.common.base.Supplier;
40import com.google.common.base.Throwables;
41import com.google.common.collect.ImmutableList;
42import com.google.common.collect.ImmutableMap;
43import com.google.common.io.Files;
44import com.google.inject.ImplementedBy;
45 
46/**
47 * Controls the administrative access to a node. By default, it will perform the
48 * following:
49 * 
50 * <ul>
51 * <li>setup a new admin user which folks should use as opposed to the built-in
52 * vcloud account</li>
53 * <ul>
54 * <li>associate a random password to account</li>
55 * <ul>
56 * <li>securely ( use sha 512 on client side and literally rewrite the shadow
57 * entry, rather than pass password to OS in a script )</li>
58 * </ul>
59 * <li>associate the users' ssh public key with the account for login</li> <li>
60 * associate it with the os group wheel</li> </ul> <li>create os group wheel</li>
61 * <li>add sudoers for nopassword access to root by group wheel</li> <li>reset
62 * root password securely</li> <li>lockdown sshd_config for no root login, nor
63 * passwords allowed</li> </ul>
64 * 
65 * @author Adrian Cole
66 */
67public class AdminAccess implements Statement, Function<Configuration, AdminAccess> {
68   public static AdminAccess.Builder builder() {
69      return new Builder();
70   }
71 
72   public static AdminAccess.Builder builder(Function<String, String> cryptFunction) {
73      return new Builder(cryptFunction);
74   }
75 
76   public static AdminAccess standard() {
77      return new Builder().build();
78   }
79 
80   @ImplementedBy(DefaultConfiguration.class)
81   public static interface Configuration {
82      Supplier<String> defaultAdminUsername();
83 
84      Supplier<Map<String, String>> defaultAdminSshKeys();
85 
86      Supplier<String> passwordGenerator();
87 
88      Function<String, String> cryptFunction();
89   }
90 
91   public static class Builder {
92      private final Function<String, String> cryptFunction;
93 
94      public Builder() {
95         this(Sha512Crypt.function());
96      }
97 
98      public Builder(Function<String, String> cryptFunction) {
99         this.cryptFunction = cryptFunction;
100      }
101 
102      private String adminUsername;
103      private String adminPublicKey;
104      private File adminPublicKeyFile;
105      private String adminPrivateKey;
106      private File adminPrivateKeyFile;
107      private String adminPassword;
108      private String loginPassword;
109      private boolean lockSsh = true;
110      private boolean grantSudoToAdminUser = true;
111      private boolean authorizeAdminPublicKey = true;
112      private boolean installAdminPrivateKey = false;
113      private boolean resetLoginPassword = true;
114 
115      public AdminAccess.Builder adminUsername(String adminUsername) {
116         this.adminUsername = adminUsername;
117         return this;
118      }
119 
120      public AdminAccess.Builder adminPassword(String adminPassword) {
121         this.adminPassword = adminPassword;
122         return this;
123      }
124 
125      public AdminAccess.Builder loginPassword(String loginPassword) {
126         this.loginPassword = loginPassword;
127         return this;
128      }
129 
130      public AdminAccess.Builder lockSsh(boolean lockSsh) {
131         this.lockSsh = lockSsh;
132         return this;
133      }
134 
135      public AdminAccess.Builder resetLoginPassword(boolean resetLoginPassword) {
136         this.resetLoginPassword = resetLoginPassword;
137         return this;
138      }
139 
140      public AdminAccess.Builder authorizeAdminPublicKey(boolean authorizeAdminPublicKey) {
141         this.authorizeAdminPublicKey = authorizeAdminPublicKey;
142         return this;
143      }
144 
145      public AdminAccess.Builder installAdminPrivateKey(boolean installAdminPrivateKey) {
146         this.installAdminPrivateKey = installAdminPrivateKey;
147         return this;
148      }
149 
150      public AdminAccess.Builder grantSudoToAdminUser(boolean grantSudoToAdminUser) {
151         this.grantSudoToAdminUser = grantSudoToAdminUser;
152         return this;
153      }
154 
155      public AdminAccess.Builder adminPublicKey(File adminPublicKey) {
156         this.adminPublicKeyFile = adminPublicKey;
157         this.adminPublicKey = null;
158         return this;
159      }
160 
161      public AdminAccess.Builder adminPublicKey(String adminPublicKey) {
162         this.adminPublicKey = adminPublicKey;
163         this.adminPublicKeyFile = null;
164         return this;
165      }
166 
167      public AdminAccess.Builder adminPrivateKey(File adminPrivateKey) {
168         this.adminPrivateKeyFile = adminPrivateKey;
169         this.adminPrivateKey = null;
170         return this;
171      }
172 
173      public AdminAccess.Builder adminPrivateKey(String adminPrivateKey) {
174         this.adminPrivateKey = adminPrivateKey;
175         this.adminPrivateKeyFile = null;
176         return this;
177      }
178 
179      public AdminAccess build() {
180         try {
181            String adminPublicKey = this.adminPublicKey;
182            if (adminPublicKey == null && adminPublicKeyFile != null)
183               adminPublicKey = Files.toString(adminPublicKeyFile, UTF_8);
184            String adminPrivateKey = this.adminPrivateKey;
185            if (adminPrivateKey == null && adminPrivateKeyFile != null)
186               adminPrivateKey = Files.toString(adminPrivateKeyFile, UTF_8);
187            return new AdminAccess(adminUsername, adminPublicKey, adminPrivateKey, adminPassword, loginPassword,
188                  lockSsh, grantSudoToAdminUser, authorizeAdminPublicKey, installAdminPrivateKey, resetLoginPassword,
189                  cryptFunction);
190         } catch (IOException e) {
191            Throwables.propagate(e);
192            return null;
193         }
194      }
195   }
196 
197   private final String adminUsername;
198   private final String adminPublicKey;
199   private final String adminPrivateKey;
200   private final String adminPassword;
201   private final String loginPassword;
202   private final boolean lockSsh;
203   private final boolean grantSudoToAdminUser;
204   private final boolean authorizeAdminPublicKey;
205   private final boolean installAdminPrivateKey;
206   private final boolean resetLoginPassword;
207   private final Function<String, String> cryptFunction;
208   private final Credentials adminCredentials;
209 
210   protected AdminAccess(@Nullable String adminUsername, @Nullable String adminPublicKey,
211         @Nullable String adminPrivateKey, @Nullable String adminPassword, @Nullable String loginPassword,
212         boolean lockSsh, boolean grantSudoToAdminUser, boolean authorizeAdminPublicKey,
213         boolean installAdminPrivateKey, boolean resetLoginPassword, Function<String, String> cryptFunction) {
214      this.adminUsername = adminUsername;
215      this.adminPublicKey = adminPublicKey;
216      this.adminPrivateKey = adminPrivateKey;
217      this.adminPassword = adminPassword;
218      this.loginPassword = loginPassword;
219      this.lockSsh = lockSsh;
220      this.grantSudoToAdminUser = grantSudoToAdminUser;
221      this.authorizeAdminPublicKey = authorizeAdminPublicKey;
222      this.installAdminPrivateKey = installAdminPrivateKey;
223      this.resetLoginPassword = resetLoginPassword;
224      this.cryptFunction = cryptFunction;
225      if (adminUsername != null && authorizeAdminPublicKey && adminPrivateKey != null)
226         this.adminCredentials = new Credentials(adminUsername, adminPrivateKey);
227      else
228         this.adminCredentials = null;
229   }
230 
231   /**
232    * 
233    * @return new credentials or null if unchanged or unavailable
234    */
235   @Nullable
236   public Credentials getAdminCredentials() {
237      return adminCredentials;
238   }
239 
240   @Override
241   public Iterable<String> functionDependencies(OsFamily family) {
242      return ImmutableList.of();
243   }
244 
245   @Override
246   public AdminAccess apply(Configuration configuration) {
247      Builder builder = AdminAccess.builder(configuration.cryptFunction());
248      builder.adminUsername(this.adminUsername != null ? this.adminUsername : configuration.defaultAdminUsername()
249            .get());
250      builder.adminPassword(this.adminPassword != null ? this.adminPassword : configuration.passwordGenerator().get());
251      Map<String, String> adminSshKeys = (adminPublicKey != null && adminPrivateKey != null) ? ImmutableMap.of(
252            "public", adminPublicKey, "private", adminPrivateKey) : configuration.defaultAdminSshKeys().get();
253      builder.adminPublicKey(adminSshKeys.get("public"));
254      builder.adminPrivateKey(adminSshKeys.get("private"));
255      builder.loginPassword(this.loginPassword != null ? this.loginPassword : configuration.passwordGenerator().get());
256      builder.grantSudoToAdminUser(this.grantSudoToAdminUser);
257      builder.authorizeAdminPublicKey(this.authorizeAdminPublicKey);
258      builder.installAdminPrivateKey(this.installAdminPrivateKey);
259      builder.lockSsh(this.lockSsh);
260      builder.resetLoginPassword(this.resetLoginPassword);
261      return builder.build();
262   }
263 
264   @Override
265   public String render(OsFamily family) {
266      checkNotNull(family, "family");
267      if (family == OsFamily.WINDOWS)
268         throw new UnsupportedOperationException("windows not yet implemented");
269      checkNotNull(adminUsername, "adminUsername");
270      checkNotNull(adminPassword, "adminPassword");
271      checkNotNull(adminPublicKey, "adminPublicKey");
272      checkNotNull(adminPrivateKey, "adminPrivateKey");
273      checkNotNull(loginPassword, "loginPassword");
274 
275      ImmutableList.Builder<Statement> statements = ImmutableList.<Statement> builder();
276      UserAdd.Builder userBuilder = UserAdd.builder();
277      userBuilder.login(adminUsername);
278      if (authorizeAdminPublicKey)
279         userBuilder.authorizeRSAPublicKey(adminPublicKey);
280      userBuilder.password(adminPassword);
281      if (installAdminPrivateKey)
282         userBuilder.installRSAPrivateKey(adminPrivateKey);
283      if (grantSudoToAdminUser) {
284         statements.add(SudoStatements.createWheel());
285         userBuilder.group("wheel");
286      }
287      statements.add(userBuilder.build().cryptFunction(cryptFunction));
288      if (lockSsh)
289         statements.add(SshStatements.lockSshd());
290      if (resetLoginPassword) {
291         statements.add(ShadowStatements.resetLoginUserPasswordTo(loginPassword).cryptFunction(cryptFunction));
292      }
293      return new StatementList(statements.build()).render(family);
294   }
295}

[all classes][org.jclouds.scriptbuilder.statements.login]
EMMA 2.0.5312 (C) Vladimir Roubtsov