| /* |
| * 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.functions; |
| |
| import static com.google.common.base.Preconditions.checkNotNull; |
| import static com.google.common.base.Preconditions.checkState; |
| import static org.jclouds.scriptbuilder.domain.Statements.appendFile; |
| import static org.jclouds.scriptbuilder.domain.Statements.exec; |
| import static org.jclouds.scriptbuilder.domain.Statements.newStatementList; |
| |
| import java.lang.reflect.Type; |
| import java.net.URI; |
| import java.security.PrivateKey; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.regex.Pattern; |
| |
| import javax.inject.Inject; |
| import javax.inject.Named; |
| import javax.inject.Singleton; |
| |
| import org.jclouds.chef.config.Validator; |
| import org.jclouds.crypto.Pems; |
| import org.jclouds.json.Json; |
| import org.jclouds.location.Provider; |
| import org.jclouds.scriptbuilder.domain.Statement; |
| |
| import com.google.common.annotations.VisibleForTesting; |
| import com.google.common.base.Function; |
| import com.google.common.base.Optional; |
| import com.google.common.base.Splitter; |
| import com.google.common.base.Supplier; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableMap; |
| import com.google.inject.TypeLiteral; |
| |
| /** |
| * |
| * Generates a bootstrap script relevant for a particular group |
| * |
| * @author Adrian Cole |
| */ |
| @Singleton |
| public class GroupToBootScript implements Function<String, Statement> { |
| private static final Pattern newLinePattern = Pattern.compile("(\\r\\n)|(\\n)"); |
| |
| @VisibleForTesting |
| static final Type RUN_LIST_TYPE = new TypeLiteral<Map<String, List<String>>>() { |
| }.getType(); |
| private final Supplier<URI> endpoint; |
| private final Json json; |
| private final Map<String, List<String>> runListForTag; |
| private final Statement installChefGems; |
| private final Optional<String> validatorName; |
| private final Optional<PrivateKey> validatorCredential; |
| |
| @Inject |
| public GroupToBootScript(@Provider Supplier<URI> endpoint, Json json, Map<String, List<String>> runListForTag, |
| @Named("installChefGems") Statement installChefGems, @Validator Optional<String> validatorName, |
| @Validator Optional<PrivateKey> validatorCredential) { |
| this.endpoint = checkNotNull(endpoint, "endpoint"); |
| this.json = checkNotNull(json, "json"); |
| this.runListForTag = checkNotNull(runListForTag, "runListForTag"); |
| this.installChefGems = checkNotNull(installChefGems, "installChefGems"); |
| this.validatorName = checkNotNull(validatorName, "validatorName"); |
| this.validatorCredential = checkNotNull(validatorCredential, validatorCredential); |
| } |
| |
| public Statement apply(String tag) { |
| checkNotNull(tag, "tag"); |
| String validatorClientName = validatorName.get(); |
| PrivateKey validatorKey = validatorCredential.get(); |
| |
| List<String> runList = runListForTag.get(tag); |
| checkState(runList != null, "runList for %s was not found", tag); |
| checkState(runList.size() > 0, "runList for %s was empty", tag); |
| |
| String chefConfigDir = "{root}etc{fs}chef"; |
| Statement createChefConfigDir = exec("{md} " + chefConfigDir); |
| Statement createClientRb = appendFile(chefConfigDir + "{fs}client.rb", ImmutableList.of("require 'rubygems'", |
| "require 'ohai'", "o = Ohai::System.new", "o.all_plugins", String.format( |
| "node_name \"%s-\" + o[:ipaddress]", tag), "log_level :info", "log_location STDOUT", String |
| .format("validation_client_name \"%s\"", validatorClientName), String.format( |
| "chef_server_url \"%s\"", endpoint.get()))); |
| |
| Statement createValidationPem = appendFile(chefConfigDir + "{fs}validation.pem", Splitter.on(newLinePattern) |
| .split(Pems.pem(validatorKey))); |
| |
| String chefBootFile = chefConfigDir + "{fs}first-boot.json"; |
| |
| Statement createFirstBoot = appendFile(chefBootFile, Collections.singleton(json.toJson(ImmutableMap |
| .<String, List<String>> of("run_list", runList), RUN_LIST_TYPE))); |
| |
| Statement runChef = exec("chef-client -j " + chefBootFile); |
| |
| return newStatementList(installChefGems, createChefConfigDir, createClientRb, |
| createValidationPem, createFirstBoot, runChef); |
| } |
| |
| } |