updated to not create nodes by default

This commit is contained in:
Adrian Cole 2010-08-03 19:20:37 -04:00
parent 21b1246e0e
commit a8db5c837f
9 changed files with 70 additions and 110 deletions

View File

@ -22,7 +22,7 @@ public interface ChefService {
void createNodeAndPopulateAutomaticAttributes(String nodeName, Iterable<String> runList);
void deleteAllClientsAndNodesInList(Iterable<String> names);
void deleteAllNodesInList(Iterable<String> names);
Iterable<? extends Node> getNodes();

View File

@ -13,7 +13,7 @@ import org.jclouds.chef.domain.Node;
import org.jclouds.chef.reference.ChefConstants;
import org.jclouds.chef.strategy.CleanupStaleNodesAndClients;
import org.jclouds.chef.strategy.CreateNodeAndPopulateAutomaticAttributes;
import org.jclouds.chef.strategy.DeleteAllClientsAndNodesInList;
import org.jclouds.chef.strategy.DeleteAllNodesInList;
import org.jclouds.chef.strategy.GetNodes;
import org.jclouds.chef.strategy.UpdateAutomaticAttributesOnNode;
import org.jclouds.logging.Logger;
@ -34,21 +34,20 @@ public class BaseChefService implements ChefService {
private final ChefContext chefContext;
private final CleanupStaleNodesAndClients cleanupStaleNodesAndClients;
private final CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes;
private final DeleteAllClientsAndNodesInList deleteAllClientsAndNodesInList;
private final DeleteAllNodesInList deleteAllNodesInList;
private final GetNodes getNodes;
private final UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode;
@Inject
protected BaseChefService(ChefContext chefContext, CleanupStaleNodesAndClients cleanupStaleNodesAndClients,
CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes,
DeleteAllClientsAndNodesInList deleteAllClientsAndNodesInList, GetNodes getNodes,
DeleteAllNodesInList deleteAllNodesInList, GetNodes getNodes,
UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode) {
this.chefContext = checkNotNull(chefContext, "chefContext");
this.cleanupStaleNodesAndClients = checkNotNull(cleanupStaleNodesAndClients, "cleanupStaleNodesAndClients");
this.createNodeAndPopulateAutomaticAttributes = checkNotNull(createNodeAndPopulateAutomaticAttributes,
"createNodeAndPopulateAutomaticAttributes");
this.deleteAllClientsAndNodesInList = checkNotNull(deleteAllClientsAndNodesInList,
"deleteAllClientsAndNodesInList");
this.deleteAllNodesInList = checkNotNull(deleteAllNodesInList, "deleteAllNodesInList");
this.getNodes = checkNotNull(getNodes, "getNodes");
this.updateAutomaticAttributesOnNode = checkNotNull(updateAutomaticAttributesOnNode,
"updateAutomaticAttributesOnNode");
@ -65,8 +64,8 @@ public class BaseChefService implements ChefService {
}
@Override
public void deleteAllClientsAndNodesInList(Iterable<String> names) {
deleteAllClientsAndNodesInList.execute(names);
public void deleteAllNodesInList(Iterable<String> names) {
deleteAllNodesInList.execute(names);
}
@Override

View File

@ -18,7 +18,7 @@
*/
package org.jclouds.chef.strategy;
import org.jclouds.chef.strategy.internal.DeleteAllClientsAndNodesInListImpl;
import org.jclouds.chef.strategy.internal.DeleteAllNodesInListImpl;
import com.google.inject.ImplementedBy;
@ -27,8 +27,8 @@ import com.google.inject.ImplementedBy;
*
* @author Adrian Cole
*/
@ImplementedBy(DeleteAllClientsAndNodesInListImpl.class)
public interface DeleteAllClientsAndNodesInList {
@ImplementedBy(DeleteAllNodesInListImpl.class)
public interface DeleteAllNodesInList {
public void execute(Iterable<String> names);

View File

@ -55,10 +55,10 @@ public class CleanupStaleNodesAndClientsImpl implements CleanupStaleNodesAndClie
protected Logger logger = Logger.NULL;
private final GetNodesImpl getAllNodes;
private final DeleteAllClientsAndNodesInListImpl deleter;
private final DeleteAllNodesInListImpl deleter;
@Inject
public CleanupStaleNodesAndClientsImpl(DeleteAllClientsAndNodesInListImpl deleter, GetNodesImpl getAllNodes) {
public CleanupStaleNodesAndClientsImpl(DeleteAllNodesInListImpl deleter, GetNodesImpl getAllNodes) {
this.getAllNodes = checkNotNull(getAllNodes, "getAllNodes");
this.deleter = checkNotNull(deleter, "deleter");
}

View File

@ -23,6 +23,7 @@ import static org.jclouds.concurrent.FutureIterables.awaitCompletion;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import javax.annotation.Resource;
import javax.inject.Named;
@ -32,10 +33,9 @@ import org.jclouds.Constants;
import org.jclouds.chef.ChefAsyncClient;
import org.jclouds.chef.ChefClient;
import org.jclouds.chef.reference.ChefConstants;
import org.jclouds.chef.strategy.DeleteAllClientsAndNodesInList;
import org.jclouds.chef.strategy.DeleteAllNodesInList;
import org.jclouds.logging.Logger;
import java.util.concurrent.Future;
import com.google.inject.Inject;
/**
@ -44,7 +44,7 @@ import com.google.inject.Inject;
* @author Adrian Cole
*/
@Singleton
public class DeleteAllClientsAndNodesInListImpl implements DeleteAllClientsAndNodesInList {
public class DeleteAllNodesInListImpl implements DeleteAllNodesInList {
protected final ChefClient chefClient;
protected final ChefAsyncClient chefAsyncClient;
@ -58,7 +58,7 @@ public class DeleteAllClientsAndNodesInListImpl implements DeleteAllClientsAndNo
protected Long maxTime;
@Inject
DeleteAllClientsAndNodesInListImpl(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor,
DeleteAllNodesInListImpl(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor,
ChefClient getAllNode, ChefAsyncClient ablobstore) {
this.userExecutor = userExecutor;
this.chefAsyncClient = ablobstore;
@ -70,12 +70,11 @@ public class DeleteAllClientsAndNodesInListImpl implements DeleteAllClientsAndNo
Map<String, Exception> exceptions = newHashMap();
Map<String, Future<?>> responses = newHashMap();
for (String name : names) {
responses.put(name, chefAsyncClient.deleteClient(name));
responses.put(name, chefAsyncClient.deleteNode(name));
}
exceptions = awaitCompletion(responses, userExecutor, maxTime, logger, String.format(
"getting deleting clients and nodes: %s", names));
"getting deleting nodes: %s", names));
if (exceptions.size() > 0)
throw new RuntimeException(String.format("errors deleting clients and nodes: %s: %s", names, exceptions));
throw new RuntimeException(String.format("errors deleting nodes: %s: %s", names, exceptions));
}
}

View File

@ -73,6 +73,7 @@ import org.jclouds.io.InputSuppliers;
import org.jclouds.io.Payloads;
import org.jclouds.io.payloads.FilePayload;
import org.jclouds.json.Json;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.HttpClient;
import org.jclouds.rest.ResourceNotFoundException;
import org.testng.annotations.AfterClass;
@ -159,7 +160,7 @@ public abstract class BaseChefClientLiveTest {
@Test(dependsOnMethods = "testCreateClient")
public void testGenerateKeyForClient() throws Exception {
clientKey = Pems.pem(getValidatorConnection().generateKeyForClient(PREFIX).getPrivateKey());
clientKey = Pems.pem(getClientConnection().generateKeyForClient(PREFIX).getPrivateKey());
assertNotNull(clientKey);
recreateClientConnection();
@ -210,23 +211,33 @@ public abstract class BaseChefClientLiveTest {
}
}
@Test
public void testListClients() throws Exception {
@Test(expectedExceptions = AuthorizationException.class)
public void testValidatorCannotListClients() throws Exception {
for (String client : getValidatorConnection().listClients())
assertNotNull(getValidatorConnection().getClient(client));
}
@Test(dependsOnMethods = "testListClients")
public void testCreateClient() throws Exception {
@Test(expectedExceptions = AuthorizationException.class)
public void testValidatorCannotDeleteClient() throws Exception {
getValidatorConnection().deleteClient(PREFIX);
}
clientKey = Pems.pem(getValidatorConnection().createClient(PREFIX).getPrivateKey());
@Test(expectedExceptions = AuthorizationException.class)
public void testValidatorCannotCreateClient() throws Exception {
getValidatorConnection().createClient(PREFIX);
}
@Test
public void testCreateClient() throws Exception {
getAdminConnection().deleteClient(PREFIX);
clientKey = Pems.pem(getAdminConnection().createClient(PREFIX).getPrivateKey());
recreateClientConnection();
getClientConnection().clientExists(PREFIX);
Set<String> clients = getValidatorConnection().listClients();
Set<String> clients = getAdminConnection().listClients();
assert clients.contains(PREFIX) : String.format("client %s not in %s", PREFIX, clients);
assertNotNull(getValidatorConnection().getClient(PREFIX));
assertNotNull(getClientConnection().getClient(PREFIX));
}
@Test(dependsOnMethods = "testCreateClient")

View File

@ -36,14 +36,14 @@ import com.google.common.collect.ImmutableSet;
*/
@Test(groups = "live", testName = "chef.DeleteAllClientsAndNodesInListImplTest")
public class DeleteAllClientsAndNodesInListImplLiveTest extends BaseChefStrategyLiveTest {
private DeleteAllClientsAndNodesInListImpl strategy;
private DeleteAllNodesInListImpl strategy;
private CreateNodeAndPopulateAutomaticAttributesImpl creater;
private ChefClient chef;
@BeforeTest(groups = "live", dependsOnMethods = "setupClient")
void setupStrategy() {
this.creater = injector.getInstance(CreateNodeAndPopulateAutomaticAttributesImpl.class);
this.strategy = injector.getInstance(DeleteAllClientsAndNodesInListImpl.class);
this.strategy = injector.getInstance(DeleteAllNodesInListImpl.class);
this.chef = injector.getInstance(ChefClient.class);
}

View File

@ -19,8 +19,6 @@
package org.jclouds.chef.servlet;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Sets.newHashSet;
import static java.util.Collections.singleton;
import static org.jclouds.chef.reference.ChefConstants.CHEF_NODE;
@ -29,9 +27,6 @@ import static org.jclouds.chef.reference.ChefConstants.CHEF_SERVICE_CLIENT;
import java.util.Properties;
import java.util.Set;
import java.util.Map.Entry;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
@ -40,21 +35,18 @@ import org.jclouds.chef.ChefAsyncClient;
import org.jclouds.chef.ChefClient;
import org.jclouds.chef.ChefContext;
import org.jclouds.chef.ChefService;
import org.jclouds.chef.domain.Client;
import org.jclouds.chef.reference.ChefConstants;
import org.jclouds.chef.servlet.functions.InitParamsToProperties;
import org.jclouds.crypto.Pems;
import org.jclouds.logging.Logger;
import org.jclouds.logging.jdk.JDKLogger;
import org.jclouds.rest.RestContextFactory;
import com.google.common.base.Throwables;
/**
* Registers a new node in Chef and binds its name to {@link ChefConstants.CHEF_NODE}, its role to
* {@link ChefConstants.CHEF_ROLE} and the {@link ChefService} for the client to
* {@link ChefConstants.CHEF_SERVICE_CLIENT} upon initialized. Deletes the node and client when the
* context is destroyed.
* Registers a new node in Chef and binds its name to
* {@link ChefConstants.CHEF_NODE}, its role to {@link ChefConstants.CHEF_ROLE}
* and the {@link ChefService} for the client to
* {@link ChefConstants.CHEF_SERVICE_CLIENT} upon initialized. Deletes the node
* and client when the context is destroyed.
*
* @author Adrian Cole
*/
@ -69,29 +61,28 @@ public class ChefRegistrationListener implements ServletContextListener {
Properties overrides = InitParamsToProperties.INSTANCE.apply(servletContextEvent);
String role = getInitParam(servletContextEvent, CHEF_ROLE);
logger.trace("creating validator connection");
logger.trace("creating client connection");
ChefService validatorService = createService(overrides);
logger.debug("created validator connection");
ChefService client = createService(overrides);
logger.debug("created client connection");
ChefService clientService = null;
String nodeName;
try {
while (true) {
nodeName = findNextClientAndNodeName(validatorService, role);
nodeName = findNextNodeName(client, role);
try {
clientService = createClientAndNode(validatorService, role, nodeName, overrides);
client.createNodeAndPopulateAutomaticAttributes(nodeName, singleton("role[" + role + "]"));
break;
} catch (IllegalStateException ex) {
logger.debug("node or client already exists %s: %s", nodeName, ex.getMessage());
logger.debug("client already exists %s: %s", nodeName, ex.getMessage());
}
}
} finally {
validatorService.getContext().close();
client.getContext().close();
}
servletContextEvent.getServletContext().setAttribute(CHEF_NODE, nodeName);
servletContextEvent.getServletContext().setAttribute(CHEF_ROLE, role);
servletContextEvent.getServletContext().setAttribute(CHEF_SERVICE_CLIENT, clientService);
servletContextEvent.getServletContext().setAttribute(CHEF_SERVICE_CLIENT, client);
logger.debug("initialized");
} catch (RuntimeException e) {
logger.error(e, "error registering");
@ -99,60 +90,22 @@ public class ChefRegistrationListener implements ServletContextListener {
}
}
private String findNextClientAndNodeName(ChefService validatorService, String prefix) {
Future<Set<String>> nodes = validatorService.getContext().getAsyncApi().listNodes();
Future<Set<String>> clients = validatorService.getContext().getAsyncApi().listClients();
try {
String nodeName;
Set<String> names = newHashSet(concat(nodes.get(), clients.get()));
int index = 0;
while (true) {
nodeName = prefix + "-" + index++;
if (!names.contains(nodeName))
break;
}
logger.trace("nodeName %s not in %s", nodeName, names);
return nodeName;
} catch (InterruptedException e) {
propagate(e);
return null;
} catch (ExecutionException e) {
propagate(e);
return null;
}
}
private ChefService createClientAndNode(ChefService validatorClient, String role, String id, Properties overrides) {
logger.trace("attempting to create client %s", id);
Client client = validatorClient.getContext().getApi().createClient(id);
logger.debug("created client %s", id);
ChefService clientService = null;
try {
Properties clientProperties = new Properties();
clientProperties.putAll(overrides);
removeCredentials(clientProperties);
clientProperties.setProperty("chef.identity", id);
clientProperties.setProperty("chef.credential", Pems.pem(client.getPrivateKey()));
clientService = createService(clientProperties);
clientService.createNodeAndPopulateAutomaticAttributes(id, singleton("role[" + role + "]"));
return clientService;
} catch (Exception e) {
logger.error(e, "error creating node %s", id);
Throwables.propagate(e);
return null;
}
}
private void removeCredentials(Properties clientProperties) {
for (Entry<Object, Object> entry : clientProperties.entrySet()) {
if (entry.getKey().toString().indexOf("credential") != -1)
clientProperties.remove(entry.getKey());
private String findNextNodeName(ChefService client, String prefix) {
Set<String> nodes = client.getContext().getApi().listNodes();
String nodeName;
Set<String> names = newHashSet(nodes);
int index = 0;
while (true) {
nodeName = prefix + "-" + index++;
if (!names.contains(nodeName))
break;
}
return nodeName;
}
private ChefService createService(Properties props) {
return ((ChefContext) new RestContextFactory().<ChefClient, ChefAsyncClient> createContext("chef", props))
.getChefService();
.getChefService();
}
private static String getInitParam(ServletContextEvent servletContextEvent, String name) {
@ -169,13 +122,13 @@ public class ChefRegistrationListener implements ServletContextListener {
*/
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
ChefService clientService = getContextAttributeOrNull(servletContextEvent, CHEF_SERVICE_CLIENT);
ChefService client = getContextAttributeOrNull(servletContextEvent, CHEF_SERVICE_CLIENT);
String nodename = getContextAttributeOrNull(servletContextEvent, CHEF_NODE);
if (nodename != null && clientService != null) {
clientService.deleteAllClientsAndNodesInList(singleton(nodename));
if (nodename != null && client != null) {
client.deleteAllNodesInList(singleton(nodename));
}
if (clientService != null) {
clientService.getContext().close();
if (client != null) {
client.getContext().close();
}
}
}

View File

@ -49,9 +49,7 @@ import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.base.Charsets;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.io.Files;
import com.google.inject.Guice;
import com.google.inject.Module;
@ -74,7 +72,7 @@ public class OpscodePlatformClientLiveTest extends BaseChefClientLiveTest {
@BeforeClass(groups = { "live" })
public void setupClient() throws IOException {
validator = checkNotNull(System.getProperty("jclouds.test.validator"), "jclouds.test.validator");
orgname = Iterables.get(Splitter.on('-').split(validator), 0);
orgname = validator.substring(0, validator.lastIndexOf('-'));
String validatorKey = System.getProperty("jclouds.test.validator.key");
if (validatorKey == null || validatorKey.equals(""))
validatorKey = System.getProperty("user.home") + "/.chef/" + orgname + "-validator.pem";
@ -141,7 +139,7 @@ public class OpscodePlatformClientLiveTest extends BaseChefClientLiveTest {
private User orgUser;
private String createdOrgname;
// @Test(expectedExceptions = AuthorizationException.class)
@Test(expectedExceptions = AuthorizationException.class)
public void testListOrganizations() throws Exception {
Set<String> orgs = adminConnection.getApi().listOrganizations();
assertNotNull(orgs);