| /* |
| * 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.softlayer.compute.strategy; |
| |
| import static com.google.common.base.Preconditions.checkArgument; |
| import static com.google.common.base.Preconditions.checkNotNull; |
| import static com.google.common.base.Preconditions.checkState; |
| import static com.google.common.collect.Iterables.contains; |
| import static com.google.common.collect.Iterables.filter; |
| import static com.google.common.collect.Iterables.get; |
| import static com.google.common.collect.Iterables.tryFind; |
| import static java.lang.Math.round; |
| import static java.lang.String.format; |
| import static org.jclouds.compute.util.ComputeServiceUtils.getCores; |
| import static org.jclouds.compute.util.ComputeServiceUtils.getSpace; |
| import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_ACTIVE_TRANSACTIONS_DELAY; |
| import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_DELAY; |
| import static org.jclouds.util.Predicates2.retry; |
| import java.util.Comparator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.concurrent.TimeUnit; |
| |
| import javax.annotation.Resource; |
| import javax.inject.Inject; |
| import javax.inject.Named; |
| import javax.inject.Singleton; |
| |
| import org.jclouds.collect.Memoized; |
| import org.jclouds.compute.ComputeServiceAdapter; |
| import org.jclouds.compute.domain.Hardware; |
| import org.jclouds.compute.domain.HardwareBuilder; |
| import org.jclouds.compute.domain.Processor; |
| import org.jclouds.compute.domain.Template; |
| import org.jclouds.compute.domain.Volume; |
| import org.jclouds.compute.domain.Volume.Type; |
| import org.jclouds.compute.domain.internal.VolumeImpl; |
| import org.jclouds.compute.reference.ComputeServiceConstants; |
| import org.jclouds.domain.LoginCredentials; |
| import org.jclouds.logging.Logger; |
| import org.jclouds.softlayer.SoftLayerApi; |
| import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions; |
| import org.jclouds.softlayer.domain.ContainerVirtualGuestConfiguration; |
| import org.jclouds.softlayer.domain.Datacenter; |
| import org.jclouds.softlayer.domain.NetworkVlan; |
| import org.jclouds.softlayer.domain.OperatingSystem; |
| import org.jclouds.softlayer.domain.Password; |
| import org.jclouds.softlayer.domain.SecuritySshKey; |
| import org.jclouds.softlayer.domain.SoftwareDescription; |
| import org.jclouds.softlayer.domain.SoftwareLicense; |
| import org.jclouds.softlayer.domain.VirtualDiskImage; |
| import org.jclouds.softlayer.domain.VirtualDiskImageSoftware; |
| import org.jclouds.softlayer.domain.VirtualGuest; |
| import org.jclouds.softlayer.domain.VirtualGuestAttribute; |
| import org.jclouds.softlayer.domain.VirtualGuestBlockDevice; |
| import org.jclouds.softlayer.domain.VirtualGuestBlockDeviceTemplate; |
| import org.jclouds.softlayer.domain.VirtualGuestBlockDeviceTemplateGroup; |
| import org.jclouds.softlayer.domain.VirtualGuestNetworkComponent; |
| |
| import com.google.common.base.Function; |
| import com.google.common.base.Optional; |
| import com.google.common.base.Predicate; |
| import com.google.common.base.Stopwatch; |
| import com.google.common.base.Strings; |
| import com.google.common.base.Supplier; |
| import com.google.common.collect.ComparisonChain; |
| import com.google.common.collect.FluentIterable; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.collect.ImmutableSet.Builder; |
| import com.google.common.collect.ImmutableSortedSet; |
| import com.google.common.collect.Sets; |
| |
| /** |
| * defines the connection between the {@link SoftLayerApi} implementation and |
| * the jclouds {@link org.jclouds.compute.ComputeService} |
| * |
| */ |
| @Singleton |
| public class SoftLayerComputeServiceAdapter implements |
| ComputeServiceAdapter<VirtualGuest, Hardware, OperatingSystem, Datacenter> { |
| |
| private static final String USER_META_NOTES = "notes"; |
| private static final int USER_META_NOTES_MAX_LENGTH = 1000; |
| private static final String BOOTABLE_DEVICE = "0"; |
| public static final String DEFAULT_DISK_TYPE = "LOCAL"; |
| |
| @Resource |
| @Named(ComputeServiceConstants.COMPUTE_LOGGER) |
| protected Logger logger = Logger.NULL; |
| |
| private final SoftLayerApi api; |
| private final Supplier<ContainerVirtualGuestConfiguration> createObjectOptionsSupplier; |
| private final Predicate<VirtualGuest> loginDetailsTester; |
| private final long guestLoginDelay; |
| private final long activeTransactionsDelay; |
| |
| @Inject |
| public SoftLayerComputeServiceAdapter(SoftLayerApi api, |
| VirtualGuestHasLoginDetailsPresent virtualGuestHasLoginDetailsPresent, |
| @Memoized Supplier<ContainerVirtualGuestConfiguration> createObjectOptionsSupplier, |
| @Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_DELAY) long guestLoginDelay, |
| @Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_ACTIVE_TRANSACTIONS_DELAY) long activeTransactionsDelay) { |
| this.api = checkNotNull(api, "api"); |
| this.guestLoginDelay = guestLoginDelay; |
| this.activeTransactionsDelay = activeTransactionsDelay; |
| this.createObjectOptionsSupplier = checkNotNull(createObjectOptionsSupplier, "createObjectOptionsSupplier"); |
| checkArgument(guestLoginDelay > 500, "guestOrderDelay must be in milliseconds and greater than 500"); |
| this.loginDetailsTester = retry(virtualGuestHasLoginDetailsPresent, guestLoginDelay); |
| } |
| |
| @Override |
| public NodeAndInitialCredentials<VirtualGuest> createNodeWithGroupEncodedIntoName(String group, String name, |
| Template template) { |
| checkNotNull(template, "template was null"); |
| checkNotNull(template.getOptions(), "template options was null"); |
| checkArgument(template.getOptions().getClass().isAssignableFrom(SoftLayerTemplateOptions.class), |
| "options class %s should have been assignable from SoftLayerTemplateOptions", |
| template.getOptions().getClass()); |
| |
| SoftLayerTemplateOptions templateOptions = template.getOptions().as(SoftLayerTemplateOptions.class); |
| String domainName = templateOptions.getDomainName(); |
| String diskType = templateOptions.getDiskType() == null ? DEFAULT_DISK_TYPE : templateOptions.getDiskType(); |
| boolean hourlyBillingFlag = templateOptions.isHourlyBillingFlag() == null ? true : templateOptions.isHourlyBillingFlag(); |
| Integer portSpeed = templateOptions.getPortSpeed(); |
| Set<VirtualGuestNetworkComponent> networkComponents = portSpeed != null ? |
| ImmutableSet.of(VirtualGuestNetworkComponent.builder().speed(portSpeed).build()) : |
| ImmutableSet.<VirtualGuestNetworkComponent>of(); |
| final Datacenter datacenter = Datacenter.builder().name(template.getLocation().getId()).build(); |
| final String imageId = template.getImage().getId(); |
| int cores = (int) template.getHardware().getProcessors().get(0).getCores(); |
| String notes = getNotes(templateOptions); |
| |
| VirtualGuest.Builder<?> virtualGuestBuilder = VirtualGuest.builder() |
| .domain(domainName) |
| .hostname(name) |
| .hourlyBillingFlag(hourlyBillingFlag) |
| .startCpus(cores) |
| .maxMemory(template.getHardware().getRam()) |
| .datacenter(datacenter) |
| .localDiskFlag(isLocalDisk(diskType)) |
| .networkComponents(networkComponents); |
| |
| // set operating system or blockDeviceTemplateGroup |
| Optional<OperatingSystem> optionalOperatingSystem = tryExtractOperatingSystemFrom(imageId); |
| if (optionalOperatingSystem.isPresent()) { |
| virtualGuestBuilder.operatingSystem(optionalOperatingSystem.get()); |
| // the imageId specified is an id of a public/private/flex image |
| } else { |
| VirtualGuestBlockDeviceTemplateGroup blockDeviceTemplateGroup = VirtualGuestBlockDeviceTemplateGroup |
| .builder().globalIdentifier(imageId).build(); |
| virtualGuestBuilder.blockDeviceTemplateGroup(blockDeviceTemplateGroup).build(); |
| } |
| // set multi-disks |
| if (!templateOptions.getBlockDevices().isEmpty()) { |
| List<VirtualGuestBlockDevice> blockDevices = getBlockDevices(templateOptions.getBlockDevices(), diskType); |
| virtualGuestBuilder.blockDevices(blockDevices); |
| } |
| // set dedicatedAccountHostOnlyFlag |
| if (templateOptions.isDedicatedAccountHostOnlyFlag() != null) { |
| virtualGuestBuilder.dedicatedAccountHostOnly(templateOptions.isDedicatedAccountHostOnlyFlag()); |
| } |
| // set privateNetworkOnlyFlag |
| if (templateOptions.isPrivateNetworkOnlyFlag() != null) { |
| virtualGuestBuilder.privateNetworkOnlyFlag(templateOptions.isPrivateNetworkOnlyFlag()); |
| } |
| // set primaryNetworkComponent.networkVlan.id |
| if (templateOptions.getPrimaryNetworkComponentNetworkVlanId() != null) { |
| int primaryNetworkComponentNetworkVlanId = templateOptions.getPrimaryNetworkComponentNetworkVlanId(); |
| virtualGuestBuilder.primaryNetworkComponent( |
| VirtualGuestNetworkComponent.builder() |
| .networkVlan(NetworkVlan.builder().id(primaryNetworkComponentNetworkVlanId).build()) |
| .build()); |
| } |
| // set primaryBackendNetworkComponent.networkVlan.id |
| if (templateOptions.getPrimaryBackendNetworkComponentNetworkVlanId() != null) { |
| int primaryBackendNetworkComponentNetworkVlanId = templateOptions.getPrimaryBackendNetworkComponentNetworkVlanId(); |
| virtualGuestBuilder.primaryBackendNetworkComponent( |
| VirtualGuestNetworkComponent.builder() |
| .networkVlan(NetworkVlan.builder().id(primaryBackendNetworkComponentNetworkVlanId).build()) |
| .build()); |
| } |
| // set postInstallScriptUri |
| if (templateOptions.getPostInstallScriptUri() != null) { |
| // Specifies the uri location of the script to be downloaded and run after installation is complete. |
| virtualGuestBuilder.postInstallScriptUri(templateOptions.getPostInstallScriptUri()); |
| } |
| // set userData |
| if (templateOptions.getUserData() != null) { |
| virtualGuestBuilder.virtualGuestAttribute(VirtualGuestAttribute.builder().value(templateOptions.getUserData()).build()); |
| } |
| // set sshKeys |
| if (!templateOptions.getSshKeys().isEmpty()) { |
| Set<SecuritySshKey> sshKeys = Sets.newHashSet(); |
| for (int sshKeyId : templateOptions.getSshKeys()) { |
| sshKeys.add(SecuritySshKey.builder().id(sshKeyId).build()); |
| } |
| virtualGuestBuilder.sshKeys(sshKeys); |
| } |
| |
| VirtualGuest virtualGuest = virtualGuestBuilder.build(); |
| logger.debug(">> creating new VirtualGuest(%s)", virtualGuest); |
| VirtualGuest result = api.getVirtualGuestApi().createVirtualGuest(virtualGuest); |
| logger.trace("<< VirtualGuest(%s)", result.getId()); |
| |
| // tags |
| if (!templateOptions.getTags().isEmpty()) { |
| api.getVirtualGuestApi().setTags(result.getId(), templateOptions.getTags()); |
| } |
| |
| // notes |
| if (!Strings.isNullOrEmpty(notes)) { |
| api.getVirtualGuestApi().setNotes(result.getId(), notes); |
| } |
| |
| logger.debug(">> awaiting login details for virtualGuest(%s)", result.getId()); |
| boolean orderInSystem = loginDetailsTester.apply(result); |
| logger.trace("<< VirtualGuest(%s) complete(%s)", result.getId(), orderInSystem); |
| |
| if (!orderInSystem) { |
| logger.warn("VirtualGuest(%s) doesn't have login details within %sms so it will be destroyed.", result, |
| Long.toString(guestLoginDelay)); |
| api.getVirtualGuestApi().deleteVirtualGuest(result.getId()); |
| throw new IllegalStateException(format("VirtualGuest(%s) is being destroyed as it doesn't have login details" + |
| " after %sms. Please, try by increasing `jclouds.softlayer.virtualguest.login_details_delay` and " + |
| " try again", result, Long.toString(guestLoginDelay))); |
| } |
| result = api.getVirtualGuestApi().getVirtualGuest(result.getId()); |
| Password pwd = get(result.getOperatingSystem().getPasswords(), 0); |
| return new NodeAndInitialCredentials<VirtualGuest>(result, result.getId() + "", |
| LoginCredentials.builder().user(pwd.getUsername()).password(pwd.getPassword()).build()); |
| } |
| |
| private String getNotes(SoftLayerTemplateOptions templateOptions) { |
| String notes = null; |
| Map<String, String> meta = templateOptions.getUserMetadata(); |
| if (meta != null) { |
| notes = meta.get(USER_META_NOTES); |
| if (!Strings.isNullOrEmpty(notes)) { |
| checkArgument(notes.length() <= USER_META_NOTES_MAX_LENGTH, "'notes' property in user metadata should be long at most " + USER_META_NOTES_MAX_LENGTH + " characters."); |
| } |
| } |
| return notes; |
| } |
| |
| @Override |
| public Iterable<Hardware> listHardwareProfiles() { |
| ContainerVirtualGuestConfiguration virtualGuestConfiguration = createObjectOptionsSupplier.get(); |
| Builder<Hardware> hardware = ImmutableSortedSet.orderedBy(new Comparator<Hardware>() { |
| @Override |
| public int compare(Hardware h1, Hardware h2) { |
| List<? extends Volume> volumes1 = h1.getVolumes(); |
| List<? extends Volume> volumes2 = h2.getVolumes(); |
| ComparisonChain comparisonChain = ComparisonChain.start().compare(getCores(h1), getCores(h2)) |
| .compare(h1.getRam(), h2.getRam()) |
| .compare(getSpace(h1), getSpace(h2)) |
| .compare(getBootableDeviceType(h1), getBootableDeviceType(h2)); |
| if (!volumes1.isEmpty() && !volumes2.isEmpty() && volumes1.size() == volumes2.size()) { |
| for (int i = 0; i < volumes1.size(); i++) { |
| comparisonChain = comparisonChain.compare(volumes1.get(i).getType(), volumes2.get(i).getType()); |
| } |
| } |
| return comparisonChain.result(); |
| } |
| }); |
| for (VirtualGuestBlockDevice blockDevice : virtualGuestConfiguration.getVirtualGuestBlockDevices()) { |
| float capacity = blockDevice.getVirtualDiskImage().getCapacity(); |
| Type type = blockDevice.getVirtualGuest().isLocalDiskFlag() ? Type.LOCAL : Type.SAN; |
| if (blockDevice.getDevice().equals(BOOTABLE_DEVICE)) { |
| for (Integer cpus : virtualGuestConfiguration.getCpusOfProcessors()) { |
| for (Integer memory : virtualGuestConfiguration.getMemories()) { |
| String id = format("cpu=%s,memory=%s,disk=%s,type=%s", cpus, memory, round(capacity), type); |
| hardware.add(new HardwareBuilder() |
| .ids(id) |
| .ram(memory) |
| .processors(ImmutableList.of(new Processor(cpus, 2))) |
| .hypervisor("XenServer") |
| .volumes(ImmutableList.<Volume>of( |
| new VolumeImpl(blockDevice.getId() + "", |
| type, |
| capacity, |
| blockDevice.getDevice(), |
| blockDevice.getBootableFlag() == 1, |
| true))) |
| .build()); |
| } |
| } |
| } |
| } |
| return hardware.build(); |
| } |
| |
| @Override |
| public Set<OperatingSystem> listImages() { |
| Set<OperatingSystem> result = Sets.newHashSet(); |
| // add allObjects filtered by the available OS |
| Set<SoftwareDescription> allObjects = api.getSoftwareDescriptionApi().getAllObjects(); |
| for (OperatingSystem os : createObjectOptionsSupplier.get().getVirtualGuestOperatingSystems()) { |
| result.addAll(FluentIterable.from(allObjects) |
| .filter(new IsOperatingSystem()) |
| .filter(new HasSameOsReferenceCode(os.getOperatingSystemReferenceCode())) |
| .transform(new SoftwareDescriptionToOperatingSystem(os.getId())) |
| .toSet()); |
| } |
| return result; |
| } |
| |
| @Override |
| public OperatingSystem getImage(final String id) { |
| // look for imageId among stock images |
| Optional<OperatingSystem> operatingSystemOptional = tryFind(listImages(), |
| new Predicate<OperatingSystem>() { |
| @Override |
| public boolean apply(OperatingSystem input) { |
| return input.getId().equals(id); |
| } |
| } |
| ); |
| if (operatingSystemOptional.isPresent()) return operatingSystemOptional.get(); |
| |
| // if imageId is not a stock image, it searches among private and public images |
| Stopwatch stopwatch = Stopwatch.createStarted(); |
| VirtualGuestBlockDeviceTemplateGroup image = api.getVirtualGuestBlockDeviceTemplateGroupApi().getObject(id); |
| logger.trace("<< Image(%s) found in (%s)", id, stopwatch.elapsed(TimeUnit.SECONDS)); |
| return tryExtractOperatingSystemFrom(image).orNull(); |
| } |
| |
| @Override |
| public Iterable<VirtualGuest> listNodes() { |
| return api.getAccountApi().listVirtualGuests(); |
| } |
| |
| @Override |
| public Iterable<VirtualGuest> listNodesByIds(final Iterable<String> ids) { |
| return filter(listNodes(), new Predicate<VirtualGuest>() { |
| |
| @Override |
| public boolean apply(VirtualGuest server) { |
| return contains(ids, server.getId()); |
| } |
| }); |
| } |
| |
| @Override |
| public Iterable<Datacenter> listLocations() { |
| Set<Datacenter> result = Sets.newHashSet(); |
| Set<Datacenter> unfiltered = api.getDatacenterApi().listDatacenters(); |
| Set<Datacenter> datacenterAvailable = createObjectOptionsSupplier.get().getVirtualGuestDatacenters(); |
| for (Datacenter datacenter : datacenterAvailable) { |
| final String datacenterName = datacenter.getName(); |
| result.addAll(Sets.newHashSet(filter(unfiltered, |
| new Predicate<Datacenter>() { |
| @Override |
| public boolean apply(Datacenter input) { |
| return input.getName().equals(datacenterName); |
| } |
| }))); |
| } |
| return result; |
| } |
| |
| @Override |
| public VirtualGuest getNode(String id) { |
| long serverId = Long.parseLong(id); |
| return api.getVirtualGuestApi().getVirtualGuest(serverId); |
| } |
| |
| @Override |
| public void destroyNode(String id) { |
| VirtualGuest guest = getNode(id); |
| if (guest == null) return; |
| logger.debug(">> awaiting virtualGuest(%s) without active transactions", guest.getId()); |
| checkState(retry(new Predicate<VirtualGuest>() { |
| public boolean apply(VirtualGuest guest) { |
| return getNode(guest.getId() + "").getActiveTransactionCount() == 0; |
| } |
| }, activeTransactionsDelay).apply(guest), "%s still has active transactions!", guest); |
| logger.debug(">> canceling virtualGuest with globalIdentifier(%s)", id); |
| checkState(api.getVirtualGuestApi().deleteVirtualGuest(guest.getId()), "server(%s) still there after deleting!?", id); |
| } |
| |
| @Override |
| public void rebootNode(String id) { |
| api.getVirtualGuestApi().rebootHardVirtualGuest(Long.parseLong(id)); |
| } |
| |
| @Override |
| public void resumeNode(String id) { |
| api.getVirtualGuestApi().resumeVirtualGuest(Long.parseLong(id)); |
| } |
| |
| @Override |
| public void suspendNode(String id) { |
| api.getVirtualGuestApi().pauseVirtualGuest(Long.parseLong(id)); |
| } |
| |
| /** |
| * This method will deliberately skip device position 1 as it is reserved to SWAP |
| * @param blockDeviceCapacities list of blockDevices to be attached |
| * @param diskType disks can be LOCAL or SAN |
| * @return |
| */ |
| private static List<VirtualGuestBlockDevice> getBlockDevices(List<Integer> blockDeviceCapacities, String diskType) { |
| ImmutableList.Builder<VirtualGuestBlockDevice> blockDevicesBuilder = ImmutableList.builder(); |
| int devicePosition = 0; |
| for (int i = 0; i < blockDeviceCapacities.size(); i++) { |
| if (i > 0) { devicePosition = i + 1; } |
| blockDevicesBuilder.add(VirtualGuestBlockDevice.builder() |
| .device(devicePosition + "") |
| .diskImage(VirtualDiskImage.builder() |
| .capacity(blockDeviceCapacities.get(i)) |
| .typeId(Type.valueOf(diskType).ordinal()) |
| .build()) |
| .build()); |
| } |
| return blockDevicesBuilder.build(); |
| } |
| |
| private static boolean isLocalDisk(String diskType) { |
| return diskType.equalsIgnoreCase(Type.LOCAL.name()); |
| } |
| |
| private static int getBootableDeviceType(Hardware hardware) { |
| List<? extends Volume> volumes = hardware.getVolumes(); |
| Optional<? extends Volume> optionalBootableVolume = tryFind(volumes, new Predicate<Volume>() { |
| @Override |
| public boolean apply(Volume volume) { |
| return volume.getDevice().equals(BOOTABLE_DEVICE); |
| } |
| }); |
| if (!optionalBootableVolume.isPresent()) { |
| return Type.LOCAL.ordinal(); |
| } |
| return optionalBootableVolume.get().getType().ordinal(); |
| } |
| |
| private Optional<OperatingSystem> tryExtractOperatingSystemFrom(final String imageId) { |
| Set<OperatingSystem> operatingSystemsAvailable = createObjectOptionsSupplier.get().getVirtualGuestOperatingSystems(); |
| return FluentIterable.from(operatingSystemsAvailable) |
| .filter(new Predicate<OperatingSystem>() { |
| @Override |
| public boolean apply(OperatingSystem input) { |
| if (input == null) return false; |
| return input.getId().contains(imageId); |
| } |
| }) |
| .first(); |
| } |
| |
| private Optional<OperatingSystem> tryExtractOperatingSystemFrom(VirtualGuestBlockDeviceTemplateGroup image) { |
| if (image.getGlobalIdentifier() == null) return Optional.absent(); |
| return FluentIterable.from(image.getChildren()) |
| .transformAndConcat(new BlockDeviceTemplateGroupToBlockDeviceTemplateIterable()) |
| .filter(new IsBootableDevice()) |
| .transformAndConcat(new BlockDeviceTemplateToDiskImageSoftware()) |
| .transform(new DiskImageSoftwareToSoftwareDescription()) |
| .filter(new IsOperatingSystem()) |
| .transform(new SoftwareDescriptionToOperatingSystem(image.getGlobalIdentifier())) |
| .first(); |
| } |
| |
| public static class VirtualGuestHasLoginDetailsPresent implements Predicate<VirtualGuest> { |
| private final SoftLayerApi client; |
| |
| @Inject |
| public VirtualGuestHasLoginDetailsPresent(SoftLayerApi client) { |
| this.client = checkNotNull(client, "client was null"); |
| } |
| |
| @Override |
| public boolean apply(VirtualGuest guest) { |
| checkNotNull(guest, "virtual guest was null"); |
| |
| VirtualGuest virtualGuest = client.getVirtualGuestApi().getVirtualGuest(guest.getId()); |
| boolean hasBackendIp = virtualGuest.getPrimaryBackendIpAddress() != null; |
| boolean hasPrimaryIp = virtualGuest.getPrimaryIpAddress() != null; |
| boolean hasPasswords = virtualGuest.getOperatingSystem() != null |
| && !virtualGuest.getOperatingSystem().getPasswords().isEmpty(); |
| |
| return virtualGuest.isPrivateNetworkOnly() ? hasBackendIp && hasPasswords : hasBackendIp && hasPrimaryIp && hasPasswords; |
| } |
| } |
| |
| private static class SoftwareDescriptionToOperatingSystem implements Function<SoftwareDescription, OperatingSystem> { |
| private final String osId; |
| |
| public SoftwareDescriptionToOperatingSystem(String osId) { |
| this.osId = osId; |
| } |
| |
| @Override |
| public OperatingSystem apply(SoftwareDescription input) { |
| return OperatingSystem.builder().id(osId) |
| .softwareLicense(SoftwareLicense.builder().softwareDescription(input).build()) |
| .operatingSystemReferenceCode(input.getReferenceCode()) |
| .build(); |
| } |
| } |
| |
| private static class IsBootableDevice implements Predicate<VirtualGuestBlockDeviceTemplate> { |
| @Override |
| public boolean apply(VirtualGuestBlockDeviceTemplate blockDeviceTemplate) { |
| return blockDeviceTemplate.getDevice().equals(BOOTABLE_DEVICE); |
| } |
| } |
| |
| private static class BlockDeviceTemplateGroupToBlockDeviceTemplateIterable implements Function<VirtualGuestBlockDeviceTemplateGroup, |
| Iterable<VirtualGuestBlockDeviceTemplate>> { |
| @Override |
| public Iterable<VirtualGuestBlockDeviceTemplate> apply(VirtualGuestBlockDeviceTemplateGroup input) { |
| return input.getBlockDevices(); |
| } |
| } |
| |
| private static class BlockDeviceTemplateToDiskImageSoftware implements Function<VirtualGuestBlockDeviceTemplate, Iterable<VirtualDiskImageSoftware>> { |
| @Override |
| public Iterable<VirtualDiskImageSoftware> apply(VirtualGuestBlockDeviceTemplate bootableDevice) { |
| return bootableDevice.getDiskImage().getSoftwareReferences(); |
| } |
| } |
| |
| private static class DiskImageSoftwareToSoftwareDescription implements Function<VirtualDiskImageSoftware, SoftwareDescription> { |
| @Override |
| public SoftwareDescription apply(VirtualDiskImageSoftware software) { |
| return software.getSoftwareDescription(); |
| } |
| } |
| |
| private static class HasSameOsReferenceCode implements Predicate<SoftwareDescription> { |
| private final String osReferenceCode; |
| |
| public HasSameOsReferenceCode(String osReferenceCode) { |
| this.osReferenceCode = osReferenceCode; |
| } |
| |
| @Override |
| public boolean apply(SoftwareDescription input) { |
| return input.getReferenceCode().equals(osReferenceCode); |
| } |
| } |
| |
| private static class IsOperatingSystem implements Predicate<SoftwareDescription> { |
| @Override |
| public boolean apply(SoftwareDescription softwareDescription) { |
| // operatingSystem is set to '1' if this Software Description describes an Operating System. |
| return softwareDescription.getOperatingSystem() == 1; |
| } |
| } |
| } |