blob: 1b6fcfe34c44da3c3f128b471d76a88b33653547 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.chef.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.chef.config.ChefProperties.CHEF_BOOTSTRAP_DATABAG;
import java.io.IOException;
import java.io.InputStream;
import java.security.PrivateKey;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.chef.ChefApi;
import org.jclouds.chef.ChefContext;
import org.jclouds.chef.ChefService;
import org.jclouds.chef.config.ChefProperties;
import org.jclouds.chef.domain.BootstrapConfig;
import org.jclouds.chef.domain.Client;
import org.jclouds.chef.domain.CookbookVersion;
import org.jclouds.chef.domain.DatabagItem;
import org.jclouds.chef.domain.Environment;
import org.jclouds.chef.domain.Node;
import org.jclouds.chef.functions.BootstrapConfigForGroup;
import org.jclouds.chef.functions.GroupToBootScript;
import org.jclouds.chef.functions.RunListForGroup;
import org.jclouds.chef.strategy.CleanupStaleNodesAndClients;
import org.jclouds.chef.strategy.CreateNodeAndPopulateAutomaticAttributes;
import org.jclouds.chef.strategy.DeleteAllClientsInList;
import org.jclouds.chef.strategy.DeleteAllNodesInList;
import org.jclouds.chef.strategy.ListClients;
import org.jclouds.chef.strategy.ListCookbookVersions;
import org.jclouds.chef.strategy.ListCookbookVersionsInEnvironment;
import org.jclouds.chef.strategy.ListEnvironments;
import org.jclouds.chef.strategy.ListNodes;
import org.jclouds.chef.strategy.ListNodesInEnvironment;
import org.jclouds.chef.strategy.UpdateAutomaticAttributesOnNode;
import org.jclouds.crypto.Crypto;
import org.jclouds.domain.JsonBall;
import org.jclouds.io.ByteStreams2;
import org.jclouds.io.Payloads;
import org.jclouds.io.payloads.RSADecryptingPayload;
import org.jclouds.io.payloads.RSAEncryptingPayload;
import org.jclouds.json.Json;
import org.jclouds.logging.Logger;
import org.jclouds.scriptbuilder.domain.Statement;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Supplier;
import com.google.common.collect.Maps;
import com.google.common.io.InputSupplier;
@Singleton
public class BaseChefService implements ChefService {
private final ChefContext chefContext;
private final ChefApi api;
private final CleanupStaleNodesAndClients cleanupStaleNodesAndClients;
private final CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes;
private final DeleteAllNodesInList deleteAllNodesInList;
private final ListNodes listNodes;
private final DeleteAllClientsInList deleteAllClientsInList;
private final ListClients listClients;
private final UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode;
private final Supplier<PrivateKey> privateKey;
private final GroupToBootScript groupToBootScript;
private final String databag;
private final BootstrapConfigForGroup bootstrapConfigForGroup;
private final RunListForGroup runListForGroup;
private final ListCookbookVersions listCookbookVersions;
private final ListCookbookVersionsInEnvironment listCookbookVersionsInEnvironment;
private final ListEnvironments listEnvironments;
private final ListNodesInEnvironment listNodesInEnvironment;
private final Json json;
private final Crypto crypto;
@Resource
@Named(ChefProperties.CHEF_LOGGER)
protected Logger logger = Logger.NULL;
@Inject
protected BaseChefService(ChefContext chefContext, ChefApi api,
CleanupStaleNodesAndClients cleanupStaleNodesAndClients,
CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes,
DeleteAllNodesInList deleteAllNodesInList, ListNodes listNodes, DeleteAllClientsInList deleteAllClientsInList,
ListClients listClients, ListCookbookVersions listCookbookVersions,
UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode, Supplier<PrivateKey> privateKey,
@Named(CHEF_BOOTSTRAP_DATABAG) String databag, GroupToBootScript groupToBootScript,
BootstrapConfigForGroup bootstrapConfigForGroup, RunListForGroup runListForGroup,
ListEnvironments listEnvironments, ListNodesInEnvironment listNodesInEnvironment,
ListCookbookVersionsInEnvironment listCookbookVersionsInEnvironment, Json json, Crypto crypto) {
this.chefContext = checkNotNull(chefContext, "chefContext");
this.api = checkNotNull(api, "api");
this.cleanupStaleNodesAndClients = checkNotNull(cleanupStaleNodesAndClients, "cleanupStaleNodesAndClients");
this.createNodeAndPopulateAutomaticAttributes = checkNotNull(createNodeAndPopulateAutomaticAttributes,
"createNodeAndPopulateAutomaticAttributes");
this.deleteAllNodesInList = checkNotNull(deleteAllNodesInList, "deleteAllNodesInList");
this.listNodes = checkNotNull(listNodes, "listNodes");
this.deleteAllClientsInList = checkNotNull(deleteAllClientsInList, "deleteAllClientsInList");
this.listClients = checkNotNull(listClients, "listClients");
this.listCookbookVersions = checkNotNull(listCookbookVersions, "listCookbookVersions");
this.updateAutomaticAttributesOnNode = checkNotNull(updateAutomaticAttributesOnNode,
"updateAutomaticAttributesOnNode");
this.privateKey = checkNotNull(privateKey, "privateKey");
this.groupToBootScript = checkNotNull(groupToBootScript, "groupToBootScript");
this.databag = checkNotNull(databag, "databag");
this.bootstrapConfigForGroup = checkNotNull(bootstrapConfigForGroup, "bootstrapConfigForGroup");
this.runListForGroup = checkNotNull(runListForGroup, "runListForGroup");
this.listEnvironments = checkNotNull(listEnvironments, "listEnvironments");
this.listNodesInEnvironment = checkNotNull(listNodesInEnvironment, "listNodesInEnvironment");
this.listCookbookVersionsInEnvironment = checkNotNull(listCookbookVersionsInEnvironment, "listCookbookVersionsInEnvironment");
this.json = checkNotNull(json, "json");
this.crypto = checkNotNull(crypto, "crypto");
}
@Override
public ChefContext getContext() {
return chefContext;
}
@Override
public byte[] encrypt(InputSupplier<? extends InputStream> supplier) throws IOException {
return ByteStreams2.toByteArrayAndClose(new RSAEncryptingPayload(crypto, Payloads.newPayload(supplier.getInput()), privateKey
.get()).openStream());
}
@Override
public byte[] decrypt(InputSupplier<? extends InputStream> supplier) throws IOException {
return ByteStreams2.toByteArrayAndClose(new RSADecryptingPayload(crypto, Payloads.newPayload(supplier.getInput()), privateKey
.get()).openStream());
}
@VisibleForTesting
String buildBootstrapConfiguration(BootstrapConfig bootstrapConfig) {
checkNotNull(bootstrapConfig, "bootstrapConfig must not be null");
Map<String, Object> configMap = Maps.newHashMap();
configMap.put("run_list", bootstrapConfig.getRunList());
if (bootstrapConfig.getEnvironment().isPresent()) {
configMap.put("environment", bootstrapConfig.getEnvironment().get());
}
if (bootstrapConfig.getAttribtues().isPresent()) {
Map<String, Object> attributes = json.fromJson(bootstrapConfig.getAttribtues().get().toString(),
BootstrapConfigForGroup.BOOTSTRAP_CONFIG_TYPE);
configMap.putAll(attributes);
}
return json.toJson(configMap);
}
@Override
public Statement createBootstrapScriptForGroup(String group) {
return groupToBootScript.apply(group);
}
@Override
public void updateBootstrapConfigForGroup(String group, BootstrapConfig bootstrapConfig) {
try {
api.createDatabag(databag);
} catch (IllegalStateException e) {
}
String jsonConfig = buildBootstrapConfiguration(bootstrapConfig);
DatabagItem runlist = new DatabagItem(group, jsonConfig);
if (api.getDatabagItem(databag, group) == null) {
api.createDatabagItem(databag, runlist);
} else {
api.updateDatabagItem(databag, runlist);
}
}
@Override
public List<String> getRunListForGroup(String group) {
return runListForGroup.apply(group);
}
@Override
public JsonBall getBootstrapConfigForGroup(String group) {
return bootstrapConfigForGroup.apply(group);
}
@Override
public void cleanupStaleNodesAndClients(String prefix, int secondsStale) {
cleanupStaleNodesAndClients.execute(prefix, secondsStale);
}
@Override
public Node createNodeAndPopulateAutomaticAttributes(String nodeName, Iterable<String> runList) {
return createNodeAndPopulateAutomaticAttributes.execute(nodeName, runList);
}
@Override
public void updateAutomaticAttributesOnNode(String nodeName) {
updateAutomaticAttributesOnNode.execute(nodeName);
}
@Override
public void deleteAllNodesInList(Iterable<String> names) {
deleteAllNodesInList.execute(names);
}
@Override
public void deleteAllClientsInList(Iterable<String> names) {
deleteAllClientsInList.execute(names);
}
@Override
public Iterable<? extends Node> listNodes() {
return listNodes.execute();
}
@Override
public Iterable<? extends Node> listNodes(ExecutorService executorService) {
return listNodes.execute(executorService);
}
@Override
public Iterable<? extends Client> listClients() {
return listClients.execute();
}
@Override
public Iterable<? extends Client> listClients(ExecutorService executorService) {
return listClients.execute(executorService);
}
@Override
public Iterable<? extends CookbookVersion> listCookbookVersions() {
return listCookbookVersions.execute();
}
@Override public Iterable<? extends CookbookVersion> listCookbookVersions(
ExecutorService executorService) {
return listCookbookVersions.execute(executorService);
}
@Override
public Iterable<? extends CookbookVersion> listCookbookVersionsInEnvironment(String environmentName) {
return listCookbookVersionsInEnvironment.execute(environmentName);
}
@Override
public Iterable<? extends CookbookVersion> listCookbookVersionsInEnvironment(String environmentName,
ExecutorService executorService) {
return listCookbookVersionsInEnvironment.execute(executorService, environmentName);
}
@Override
public Iterable<? extends CookbookVersion> listCookbookVersionsInEnvironment(String environmentName,
String numVersions) {
return listCookbookVersionsInEnvironment.execute(environmentName, numVersions);
}
@Override
public Iterable<? extends CookbookVersion> listCookbookVersionsInEnvironment(String environmentName,
String numVersions, ExecutorService executorService) {
return listCookbookVersionsInEnvironment.execute(executorService, environmentName, numVersions);
}
@Override
public Iterable<? extends Environment> listEnvironments() {
return listEnvironments.execute();
}
@Override
public Iterable<? extends Node> listNodesInEnvironment(String environmentName) {
return listNodesInEnvironment.execute(environmentName);
}
@Override
public Iterable<? extends Node> listNodesInEnvironment(String environmentName, ExecutorService executorService) {
return listNodesInEnvironment.execute(executorService, environmentName);
}
}