| /* |
| * 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 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.ListNodesInEnvironment; |
| import org.jclouds.chef.strategy.ListEnvironments; |
| import org.jclouds.chef.strategy.ListNodes; |
| import org.jclouds.chef.strategy.UpdateAutomaticAttributesOnNode; |
| import org.jclouds.crypto.Crypto; |
| import org.jclouds.domain.JsonBall; |
| 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.ByteStreams; |
| 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 ByteStreams.toByteArray(new RSAEncryptingPayload(crypto, Payloads.newPayload(supplier.getInput()), privateKey |
| .get())); |
| } |
| |
| @Override |
| public byte[] decrypt(InputSupplier<? extends InputStream> supplier) throws IOException { |
| return ByteStreams.toByteArray(new RSADecryptingPayload(crypto, Payloads.newPayload(supplier.getInput()), privateKey |
| .get())); |
| } |
| |
| @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 Client> listClients() { |
| return listClients.execute(); |
| } |
| |
| @Override |
| public Iterable<? extends CookbookVersion> listCookbookVersions() { |
| return listCookbookVersions.execute(); |
| } |
| |
| @Override |
| public Iterable<? extends CookbookVersion> listCookbookVersionsInEnvironment(String environmentName) { |
| return listCookbookVersionsInEnvironment.execute(environmentName); |
| } |
| |
| @Override |
| public Iterable<? extends CookbookVersion> listCookbookVersionsInEnvironment(String environmentName, String numVersions) { |
| return listCookbookVersionsInEnvironment.execute(environmentName, numVersions); |
| } |
| |
| @Override |
| public Iterable<? extends Environment> listEnvironments() { |
| return listEnvironments.execute(); |
| } |
| |
| @Override |
| public Iterable<? extends Node> listNodesInEnvironment(String environmentName) { |
| return listNodesInEnvironment.execute(environmentName); |
| } |
| |
| } |