| /* |
| * 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.apache.provisionr.commands; |
| |
| import com.google.common.annotations.VisibleForTesting; |
| import com.google.common.base.Charsets; |
| import com.google.common.base.Optional; |
| import static com.google.common.base.Preconditions.checkArgument; |
| import static com.google.common.base.Preconditions.checkNotNull; |
| import com.google.common.base.Throwables; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.collect.Iterables; |
| import com.google.common.collect.Lists; |
| import com.google.common.io.Files; |
| import java.io.File; |
| import java.util.List; |
| import java.util.NoSuchElementException; |
| import java.util.Set; |
| import org.apache.felix.gogo.commands.Option; |
| import org.apache.karaf.shell.console.OsgiCommandSupport; |
| import org.apache.provisionr.api.Provisionr; |
| import org.apache.provisionr.api.access.AdminAccess; |
| import org.apache.provisionr.api.network.Network; |
| import org.apache.provisionr.api.network.Rule; |
| import org.apache.provisionr.api.pool.Pool; |
| import org.apache.provisionr.api.provider.Provider; |
| import org.apache.provisionr.commands.predicates.ProvisionrPredicates; |
| import org.apache.provisionr.core.templates.PoolTemplate; |
| |
| public abstract class CreateCommand extends OsgiCommandSupport { |
| |
| @Option(name = "--id", description = "Service ID (use provisionr:services)", required = true) |
| protected String id; |
| |
| @Option(name = "--package", description = "Package to install by default (multi-valued)", |
| multiValued = true) |
| protected List<String> packages = Lists.newArrayList(); |
| |
| @Option(name = "-t", aliases = "--template", description = "Pre-configured template (packages, files)") |
| protected String template; |
| |
| @Option(name = "--timeout", description = "Timeout in seconds for the command's initialization steps. " + |
| "If not specified, defaults to 600 seconds.") |
| protected int bootstrapTimeout = 600; |
| |
| @Option(name = "--public-key-path", description = "Path to the public key. " + |
| "The default value can be overridden in org.apache.provisionr.core") |
| private String publicKeyPath; |
| |
| @Option(name = "--private-key-path", description = "Path to the private key. " + |
| "The default value can be overridden in org.apache.provisionr.core") |
| private String privateKeyPath; |
| |
| protected final List<Provisionr> services; |
| |
| protected final List<PoolTemplate> templates; |
| |
| public CreateCommand(List<Provisionr> services, List<PoolTemplate> templates, |
| String publicKeyPath, String privateKeyPath) { |
| this.services = checkNotNull(services, "services is null"); |
| this.templates = checkNotNull(templates, "templates is null"); |
| |
| this.publicKeyPath = checkNotNull(publicKeyPath, "publicKeyPath is null"); |
| this.privateKeyPath = checkNotNull(privateKeyPath, "privateKeyPath is null"); |
| } |
| |
| @VisibleForTesting |
| void setId(String id) { |
| this.id = checkNotNull(id, "id is null"); |
| } |
| |
| @VisibleForTesting |
| void setPackages(List<String> packages) { |
| this.packages = ImmutableList.copyOf(packages); |
| } |
| |
| @VisibleForTesting |
| void setTemplate(String template) { |
| this.template = checkNotNull(template, "template is null"); |
| } |
| |
| @VisibleForTesting |
| void setBootstrapTimeout(int bootstrapTimeout) { |
| this.bootstrapTimeout = bootstrapTimeout; |
| } |
| |
| @VisibleForTesting |
| void setPublicKeyPath(String publicKeyPath) { |
| this.publicKeyPath = checkNotNull(publicKeyPath, "publicKeyPath is null"); |
| } |
| |
| @VisibleForTesting |
| void setPrivateKeyPath(String privateKeyPath) { |
| this.privateKeyPath = checkNotNull(privateKeyPath, "privateKeyPath is null"); |
| } |
| |
| @VisibleForTesting |
| AdminAccess collectCurrentUserCredentialsForAdminAccess() { |
| try { |
| String publicKey = Files.toString(new File(publicKeyPath), Charsets.UTF_8); |
| String privateKey = Files.toString(new File(privateKeyPath), Charsets.UTF_8); |
| |
| return AdminAccess.builder().username(System.getProperty("user.name")) |
| .publicKey(publicKey).privateKey(privateKey).createAdminAccess(); |
| } catch (Exception e) { |
| throw Throwables.propagate(e); |
| } |
| } |
| |
| @VisibleForTesting |
| Pool applyTemplate(Pool pool) { |
| for (PoolTemplate candidate : templates) { |
| if (candidate.getId().equalsIgnoreCase(template)) { |
| return candidate.apply(pool); |
| } |
| } |
| throw new NoSuchElementException("No pool template found with name: " + template); |
| } |
| |
| @VisibleForTesting |
| Network buildNetwork(List<Integer> ports) { |
| /* Always allow ICMP and ssh traffic by default */ |
| return Network.builder().addRules( |
| Rule.builder().anySource().icmp().createRule(), |
| Rule.builder().anySource().tcp().port(22).createRule() |
| ).addRules( |
| formatPortsAsIngressRules(ports) |
| ).createNetwork(); |
| } |
| |
| Optional<Provider> getDefaultProvider(Provisionr service) { |
| checkArgument(service.getDefaultProvider().isPresent(), String.format("please configure a default provider " + |
| "by editing etc/org.apache.provisionr.%s.cfg", id)); |
| return service.getDefaultProvider(); |
| } |
| |
| Provisionr getService() { |
| Optional<Provisionr> service = Iterables.tryFind(services, ProvisionrPredicates.withId(id)); |
| if (!service.isPresent()) { |
| throw new NoSuchElementException("No provisioning service found with id: " + id); |
| } |
| return service.get(); |
| } |
| |
| private Set<Rule> formatPortsAsIngressRules(List<Integer> ports) { |
| ImmutableSet.Builder<Rule> rules = ImmutableSet.builder(); |
| for (int port : ports) { |
| rules.add(Rule.builder().anySource().tcp().port(port).createRule()); |
| } |
| return rules.build(); |
| } |
| } |