@Override public void deleteVolume(String volumeId) { IaasProvider iaasInfo = getIaasProvider(); ComputeServiceContext context = iaasInfo.getComputeService().getContext(); String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo); if (region == null) { log.fatal( "Cannot delete the volume [id]: " + volumeId + " of the [region] : " + region + " of Iaas : " + iaasInfo); return; } ElasticBlockStoreApi blockStoreApi = context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get(); blockStoreApi.deleteVolumeInRegion(region, volumeId); log.info( "Deletion of Volume [id]: " + volumeId + " was successful. [region] : " + region + " of Iaas : " + iaasInfo); }
@Test public void testLaunchCluster() throws RunNodesException { int numNodes = 3; final String clusterName = "test-launch-cluster"; Set<? extends NodeMetadata> nodes = context .getComputeService() .createNodesInGroup( clusterName, numNodes, TemplateOptions.Builder.overrideLoginUser("toor") .runScript(AdminAccess.standard())); assertEquals(numNodes, nodes.size(), "wrong number of nodes"); for (NodeMetadata node : nodes) { assertEquals("test-launch-cluster", node.getGroup()); logger.debug("Created Node: %s", node); SshClient client = context.utils().sshForNode().apply(node); client.connect(); ExecResponse hello = client.exec("echo hello"); assertEquals(hello.getOutput().trim(), "hello"); } context .getComputeService() .destroyNodesMatching( new Predicate<NodeMetadata>() { @Override public boolean apply(NodeMetadata input) { return input.getId().contains(clusterName); } }); }
@Override public boolean isValidZone(String region, String zone) throws InvalidZoneException { IaasProvider iaasInfo = getIaasProvider(); if (zone == null || iaasInfo == null) { String msg = "Zone or IaaSProvider is null: zone: " + zone + " - IaaSProvider: " + iaasInfo; log.error(msg); throw new InvalidZoneException(msg); } ComputeServiceContext context = iaasInfo.getComputeService().getContext(); AvailabilityZoneAndRegionApi zoneRegionApi = context.unwrapApi(AWSEC2Api.class).getAvailabilityZoneAndRegionApiForRegion(region).get(); Set<AvailabilityZoneInfo> availabilityZones = zoneRegionApi.describeAvailabilityZonesInRegion(region); for (AvailabilityZoneInfo zoneInfo : availabilityZones) { String configuredZone = zoneInfo.getZone(); if (zone.equalsIgnoreCase(configuredZone)) { if (log.isDebugEnabled()) { log.debug("Found a matching zone: " + zone); } return true; } } String msg = "Invalid zone: " + zone + " in the region: " + region + " and of the iaas: " + iaasInfo.getType(); log.error(msg); throw new InvalidZoneException(msg); }
public Ec2Context(Ec2Credentials credentials) { this.credentials = credentials; Properties properties = new Properties(); long scriptTimeout = TimeUnit.MILLISECONDS.convert(50, TimeUnit.MINUTES); properties.setProperty(TIMEOUT_SCRIPT_COMPLETE, scriptTimeout + ""); properties.setProperty(TIMEOUT_PORT_OPEN, scriptTimeout + ""); properties.setProperty(PROPERTY_CONNECTION_TIMEOUT, scriptTimeout + ""); properties.setProperty( PROPERTY_EC2_AMI_QUERY, "owner-id=137112412989;state=available;image-type=machine"); properties.setProperty(PROPERTY_EC2_CC_AMI_QUERY, ""); properties.setProperty( Constants.PROPERTY_MAX_RETRIES, Settings.JCLOUDS_PROPERTY_MAX_RETRIES + ""); properties.setProperty( Constants.PROPERTY_RETRY_DELAY_START, Settings.JCLOUDS_PROPERTY_RETRY_DELAY_START + ""); Iterable<Module> modules = ImmutableSet.<Module>of( new SshjSshClientModule(), new SLF4JLoggingModule(), new EnterpriseConfigurationModule()); ContextBuilder build = ContextBuilder.newBuilder("aws-ec2") .credentials(credentials.getAccessKey(), credentials.getSecretKey()) .modules(modules) .overrides(properties); ComputeServiceContext context = build.buildView(ComputeServiceContext.class); this.computeService = (AWSEC2ComputeService) context.getComputeService(); this.ec2api = computeService.getContext().unwrapApi(EC2Api.class); this.securityGroupApi = ec2api.getSecurityGroupApi().get(); this.keypairApi = (AWSKeyPairApi) ec2api.getKeyPairApi().get(); vmBatchSize = Settings.AWS_VM_BATCH_SIZE(); }
@Override public String createVolume(int sizeGB, String snapshotId) { IaasProvider iaasInfo = getIaasProvider(); ComputeServiceContext context = iaasInfo.getComputeService().getContext(); String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo); String zone = ComputeServiceBuilderUtil.extractZone(iaasInfo); if (region == null || zone == null) { log.fatal( "Cannot create a new volume in the [region] : " + region + ", [zone] : " + zone + " of Iaas : " + iaasInfo); return null; } ElasticBlockStoreApi blockStoreApi = context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get(); Volume volume; if (StringUtils.isEmpty(snapshotId)) { if (log.isDebugEnabled()) { log.info("Creating a volume in the zone " + zone); } volume = blockStoreApi.createVolumeInAvailabilityZone(zone, sizeGB); } else { if (log.isDebugEnabled()) { log.info("Creating a volume in the zone " + zone + " from the shanpshot " + snapshotId); } volume = blockStoreApi.createVolumeFromSnapshotInAvailabilityZone(zone, snapshotId); } if (volume == null) { log.fatal( "Volume creation was unsuccessful. [region] : " + region + ", [zone] : " + zone + " of Iaas : " + iaasInfo); return null; } log.info( "Successfully created a new volume [id]: " + volume.getId() + " in [region] : " + region + ", [zone] : " + zone + " of Iaas : " + iaasInfo); return volume.getId(); }
// Suggest at least 15 minutes for timeout public static String waitForPasswordOnAws( ComputeService computeService, final NodeMetadata node, long timeout, TimeUnit timeUnit) throws TimeoutException { ComputeServiceContext computeServiceContext = computeService.getContext(); AWSEC2Api ec2Client = computeServiceContext.unwrapApi(AWSEC2Api.class); final WindowsApi client = ec2Client.getWindowsApi().get(); final String region = node.getLocation().getParent().getId(); // The Administrator password will take some time before it is ready - Amazon says sometimes 15 // minutes. // So we create a predicate that tests if the password is ready, and wrap it in a retryable // predicate. Predicate<String> passwordReady = new Predicate<String>() { @Override public boolean apply(String s) { if (Strings.isNullOrEmpty(s)) return false; PasswordData data = client.getPasswordDataInRegion(region, s); if (data == null) return false; return !Strings.isNullOrEmpty(data.getPasswordData()); } }; LOG.info("Waiting for password, for " + node.getProviderId() + ":" + node.getId()); Predicate<String> passwordReadyRetryable = Predicates2.retry( passwordReady, timeUnit.toMillis(timeout), 10 * 1000, TimeUnit.MILLISECONDS); boolean ready = passwordReadyRetryable.apply(node.getProviderId()); if (!ready) throw new TimeoutException( "Password not available for " + node + " in region " + region + " after " + timeout + " " + timeUnit.name()); // Now pull together Amazon's encrypted password blob, and the private key that jclouds // generated PasswordDataAndPrivateKey dataAndKey = new PasswordDataAndPrivateKey( client.getPasswordDataInRegion(region, node.getProviderId()), node.getCredentials().getPrivateKey()); // And apply it to the decryption function WindowsLoginCredentialsFromEncryptedData f = computeServiceContext .utils() .injector() .getInstance(WindowsLoginCredentialsFromEncryptedData.class); LoginCredentials credentials = f.apply(dataAndKey); return credentials.getPassword(); }
@Override public synchronized void releaseAddress(String ip) { IaasProvider iaasInfo = getIaasProvider(); ComputeServiceContext context = iaasInfo.getComputeService().getContext(); ElasticIPAddressApi elasticIPAddressApi = context.unwrapApi(AWSEC2Api.class).getElasticIPAddressApi().get(); String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo); elasticIPAddressApi.disassociateAddressInRegion(region, ip); elasticIPAddressApi.releaseAddressInRegion(region, ip); }
public CloudComputeService( String apiKey, String accessKey, String instanceType, String groupName, String imageId, String keyPair, String securityGroup, float maxBid) { mInstanceType = instanceType; mGroupName = groupName; mImageId = imageId; mkeyPair = keyPair; mSecurityGroup = securityGroup; mMaxBid = maxBid; mGroupTag = "group=" + mGroupName; Properties overrides = new Properties(); overrides.put(ComputeServiceProperties.POLL_INITIAL_PERIOD, String.valueOf(60L * 1000L)); overrides.put(ComputeServiceProperties.POLL_MAX_PERIOD, String.valueOf(600L * 1000L)); overrides.put(Constants.PROPERTY_MAX_RETRIES, String.valueOf(60)); mComputeServiceContext = ContextBuilder.newBuilder("aws-ec2") .credentials(apiKey, accessKey) .modules(ImmutableSet.of(new Log4JLoggingModule())) .overrides(overrides) .buildView(ComputeServiceContext.class); mComputeService = mComputeServiceContext.getComputeService(); }
@Override public void releaseAddress(String ip) { ComputeServiceContext context = iaasProvider.getComputeService().getContext(); String region = ComputeServiceBuilderUtil.extractRegion(iaasProvider); NovaApi novaApi = context.unwrapApi(NovaApi.class); FloatingIPApi floatingIPApi = novaApi.getFloatingIPExtensionForZone(region).get(); for (FloatingIP floatingIP : floatingIPApi.list()) { if (floatingIP.getIp().equals(ip)) { floatingIPApi.delete(floatingIP.getId()); break; } } }
@Test public void testTemplateBuilderFindsMegabitUplink() throws IOException { ComputeServiceContext context = null; try { Properties overrides = setupProperties(); overrides.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_PORT_SPEED, "100"); context = createView(overrides, setupModules()); // TODO add something to the template about port speed? context.getComputeService().templateBuilder().build(); } finally { if (context != null) context.close(); } }
@Override public void detachVolume(String instanceId, String volumeId) { IaasProvider iaasInfo = getIaasProvider(); ComputeServiceContext context = iaasInfo.getComputeService().getContext(); String region = ComputeServiceBuilderUtil.extractRegion(iaasInfo); if (region == null) { log.fatal( "Cannot detach the volume [id]: " + volumeId + " from the instance [id]: " + instanceId + " of the [region] : " + region + " of Iaas : " + iaasInfo); return; } ElasticBlockStoreApi blockStoreApi = context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get(); Set<Volume> volumeDescriptions = blockStoreApi.describeVolumesInRegion(region, volumeId); Iterator<Volume> it = volumeDescriptions.iterator(); while (it.hasNext()) { Volume.Status status = it.next().getStatus(); if (status == Volume.Status.AVAILABLE) { log.warn( String.format( "Volume %s is already in AVAILABLE state. Volume seems to be detached somehow", volumeId)); return; } } blockStoreApi.detachVolumeInRegion( region, volumeId, true, DetachVolumeOptions.Builder.fromInstance(instanceId)); log.info( "Detachment of Volume [id]: " + volumeId + " from instance [id]: " + instanceId + " was successful. [region] : " + region + " of Iaas : " + iaasInfo); }
protected boolean isOSX(String id) { return context .getComputeService() .getNodeMetadata(hostId) .getOperatingSystem() .getDescription() .equals("Mac OS X"); }
public CreateServerWithKeyPair(String username, String apiKey) { Iterable<Module> modules = ImmutableSet.<Module>of(new SshjSshClientModule()); // These properties control how often jclouds polls for a status update Properties overrides = new Properties(); overrides.setProperty(POLL_INITIAL_PERIOD, POLL_PERIOD_TWENTY_SECONDS); overrides.setProperty(POLL_MAX_PERIOD, POLL_PERIOD_TWENTY_SECONDS); ComputeServiceContext context = ContextBuilder.newBuilder(PROVIDER) .credentials(username, apiKey) .overrides(overrides) .modules(modules) .buildView(ComputeServiceContext.class); computeService = context.getComputeService(); novaApi = context.unwrapApi(NovaApi.class); }
@AfterMethod(alwaysRun = true) @Override public void tearDown() throws Exception { try { super.tearDown(); } finally { if (context != null) context.close(); } }
/** Rigorous Test :-) */ public void testCanUseStub() throws IOException { Iterable<String> providers = ComputeServiceUtils.getSupportedProviders(); ComputeServiceContext context = new ComputeServiceContextFactory().createContext("stub", "foo", "bar"); ComputeService client = context.getComputeService(); // Set<? extends ComputeMetadata> nodes = // Sets.newHashSet(connection.getNodes().values()); for (ComputeMetadata node : client.listNodes()) { assertNotNull(node.getId()); assertNotNull(node.getLocation().getId()); // where in the // world is the node } }
@Test public void testBiggestTemplateBuilderWhenBootIsSAN() throws IOException { ComputeServiceContext context = null; try { Properties overrides = setupProperties(); overrides.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_DISK0_TYPE, "SAN"); context = createView(overrides, setupModules()); Template template = context.getComputeService().templateBuilder().biggest().build(); assertEquals(getCores(template.getHardware()), 16.0d); assertEquals(template.getHardware().getRam(), 16); assertEquals(getSpace(template.getHardware()), 100.0d); assertEquals(template.getHardware().getVolumes().get(0).getType(), Volume.Type.SAN); } finally { if (context != null) context.close(); } }
@Test public void testBiggestTemplateBuilderWhenPrivateNetwork() throws IOException { ComputeServiceContext context = null; try { Properties overrides = setupProperties(); overrides.setProperty( PROPERTY_SOFTLAYER_VIRTUALGUEST_CPU_REGEX, "Private [0-9]+ x ([.0-9]+) GHz Core[s]?"); context = createView(overrides, setupModules()); Template template = context.getComputeService().templateBuilder().biggest().build(); assertEquals(getCores(template.getHardware()), 8.0d); assertEquals(template.getHardware().getRam(), 16); assertEquals(getSpace(template.getHardware()), 100.0d); assertEquals(template.getHardware().getVolumes().get(0).getType(), Volume.Type.LOCAL); } finally { if (context != null) context.close(); } }
public static Map<Integer, Integer> dockerPortMappingsFor( JcloudsLocation docker, String containerId) { ComputeServiceContext context = null; try { Properties properties = new Properties(); properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, Boolean.toString(true)); properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, Boolean.toString(true)); context = ContextBuilder.newBuilder("docker") .endpoint(docker.getEndpoint()) .credentials(docker.getIdentity(), docker.getCredential()) .overrides(properties) .modules(ImmutableSet.<Module>of(new SLF4JLoggingModule(), new SshjSshClientModule())) .build(ComputeServiceContext.class); DockerApi api = context.unwrapApi(DockerApi.class); Container container = api.getContainerApi().inspectContainer(containerId); Map<Integer, Integer> portMappings = Maps.newLinkedHashMap(); Map<String, List<Map<String, String>>> ports = container.networkSettings().ports(); if (ports == null) ports = ImmutableMap.<String, List<Map<String, String>>>of(); LOG.debug("Docker will forward these ports {}", ports); for (Map.Entry<String, List<Map<String, String>>> entrySet : ports.entrySet()) { String containerPort = Iterables.get(Splitter.on("/").split(entrySet.getKey()), 0); String hostPort = Iterables.getOnlyElement( Iterables.transform( entrySet.getValue(), new Function<Map<String, String>, String>() { @Override public String apply(Map<String, String> hostIpAndPort) { return hostIpAndPort.get("HostPort"); } })); portMappings.put(Integer.parseInt(containerPort), Integer.parseInt(hostPort)); } return portMappings; } finally { if (context != null) { context.close(); } } }
@Override public synchronized boolean createKeyPairFromPublicKey( String region, String keyPairName, String publicKey) { IaasProvider iaasInfo = getIaasProvider(); String ec2Msg = " ec2. Region: " + region + " - Key Pair Name: "; ComputeServiceContext context = iaasInfo.getComputeService().getContext(); AWSKeyPairApi keyPairApi = context.unwrapApi(AWSEC2Api.class).getKeyPairApiForRegion(region).get(); KeyPair keyPair = keyPairApi.importKeyPairInRegion(region, keyPairName, publicKey); if (keyPair != null) { iaasInfo .getTemplate() .getOptions() .as(AWSEC2TemplateOptions.class) .keyPair(keyPair.getKeyName()); log.info(SUCCESSFUL_LOG_LINE + ec2Msg + keyPair.getKeyName()); return true; } log.error(FAILED_LOG_LINE + ec2Msg); return false; }
@Test(enabled = true, expectedExceptions = AuthorizationException.class) public void testCorrectAuthException() throws Exception { ComputeServiceContext context = null; try { Properties overrides = setupProperties(); overrides.setProperty(provider + ".identity", "MOM:MA"); overrides.setProperty(provider + ".credential", "MIA"); context = newBuilder() .modules(ImmutableSet.of(getLoggingModule(), credentialStoreModule)) .overrides(overrides) .build(ComputeServiceContext.class); context.getComputeService().listNodes(); } catch (AuthorizationException e) { throw e; } catch (RuntimeException e) { e.printStackTrace(); throw e; } finally { if (context != null) context.close(); } }
@BeforeGroups(groups = {"live"}) public void setupClient() { setupCredentials(); Properties overrides = setupProperties(); computeContext = new ComputeServiceContextFactory() .createContext( provider, ImmutableSet.<Module>of(new Log4JLoggingModule(), new SshjSshClientModule()), overrides); context = computeContext.getProviderSpecificContext(); client = context.getApi().getKeyPairServices(); }
public void testNoSsh() throws Exception { Map<String, String> keyPair = ComputeTestUtils.setupKeyPair(); AWSInstanceClient instanceClient = AWSEC2Client.class.cast(context.getApi()).getInstanceServices(); String group = PREFIX + "unssh"; computeContext.getComputeService().destroyNodesMatching(inGroup(group)); TemplateOptions options = computeContext.getComputeService().templateOptions(); options.authorizePublicKey(keyPair.get("public")).as(AWSEC2TemplateOptions.class); ComputeServiceContext noSshContext = null; try { noSshContext = new ComputeServiceContextFactory() .createContext( provider, ImmutableSet.of(new Log4JLoggingModule()), setupProperties()); Set<? extends NodeMetadata> nodes = noSshContext.getComputeService().createNodesInGroup(group, 1, options); NodeMetadata first = get(nodes, 0); assert first.getCredentials() != null : first; assert first.getCredentials().identity != null : first; assert first.getCredentials().credential == null : first; AWSRunningInstance instance = getInstance(instanceClient, first.getProviderId()); assert instance.getSpotInstanceRequestId() != null : instance; assertEquals(instance.getKeyName(), "jclouds#" + group); Map<? extends NodeMetadata, ExecResponse> responses = computeContext .getComputeService() .runScriptOnNodesMatching( runningInGroup(group), exec("echo hello"), overrideCredentialsWith( new Credentials(first.getCredentials().identity, keyPair.get("private"))) .wrapInInitScript(false) .runAsRoot(false)); ExecResponse hello = getOnlyElement(responses.values()); assertEquals(hello.getOutput().trim(), "hello"); } finally { noSshContext.close(); computeContext.getComputeService().destroyNodesMatching(inGroup(group)); } }
@Override public boolean isValidRegion(String region) throws InvalidRegionException { IaasProvider iaasInfo = getIaasProvider(); if (region == null || iaasInfo == null) { String msg = "Region or IaaSProvider is null: region: " + region + " - IaaSProvider: " + iaasInfo; log.error(msg); throw new InvalidRegionException(msg); } ComputeServiceContext context = iaasInfo.getComputeService().getContext(); Set<String> regions = context.unwrapApi(AWSEC2Api.class).getConfiguredRegions(); for (String configuredRegion : regions) { if (region.equalsIgnoreCase(configuredRegion)) { if (log.isDebugEnabled()) { log.debug("Found a matching region: " + region); } return true; } } String msg = "Invalid region: " + region + " in the iaas: " + iaasInfo.getType(); log.error(msg); throw new InvalidRegionException(msg); }
@Test(expectedExceptions = AuthorizationException.class) @Override public void testCorrectAuthException() throws Exception { ComputeServiceContext context = null; try { String credential = toStringAndClose(getClass().getResourceAsStream("/test")); Properties overrides = setupProperties(); overrides.setProperty(provider + ".identity", "*****@*****.**"); overrides.setProperty(provider + ".credential", credential); context = newBuilder() .modules(ImmutableSet.of(getLoggingModule(), credentialStoreModule)) .overrides(overrides) .build(ComputeServiceContext.class); context.getComputeService().listNodes(); } catch (AuthorizationException e) { throw e; } catch (RuntimeException e) { e.printStackTrace(); throw e; } finally { if (context != null) context.close(); } }
@Test(groups = {"Live", "WIP"}) public void buildClaimAndDestroy() { ComputeService svc = context.getComputeService(); SamplePool p = new SamplePool(svc); log.info("buildClaimAndDestroy: created pool"); p.refresh(); log.info("buildClaimAndDestroy: refreshed pool"); p.ensureExists(2, SamplePool.USUAL_VM); log.info("buildClaimAndDestroy: ensure have 2"); MachineSet l = p.claim(1, SamplePool.USUAL_VM); Assert.assertEquals(l.size(), 1); log.info("buildClaimAndDestroy: claimed 1"); MachineSet unclaimedUsual = p.unclaimed(MachinePoolPredicates.matching(SamplePool.USUAL_VM)); log.info("buildClaimAndDestroy: unclaimed now " + unclaimedUsual); Assert.assertTrue(!unclaimedUsual.isEmpty()); p.destroy(unclaimedUsual); unclaimedUsual = p.unclaimed(MachinePoolPredicates.matching(SamplePool.USUAL_VM)); log.info("buildClaimAndDestroy: destroyed, unclaimed now " + unclaimedUsual); log.info("end"); }
public static String getFirstReachableAddress(ComputeServiceContext context, NodeMetadata node) { // To pick the address, it relies on jclouds `sshForNode().apply(Node)` to check all IPs of node // (private+public), // to find one that is reachable. It does `openSocketFinder.findOpenSocketOnNode(node, // node.getLoginPort(), ...)`. // This keeps trying for time // org.jclouds.compute.reference.ComputeServiceConstants.Timeouts.portOpen. // TODO Want to configure this timeout here. // // TODO We could perhaps instead just set `templateOptions.blockOnPort(loginPort, 120)`, but // need // to be careful to only set that if config WAIT_FOR_SSHABLE is true. For some advanced // networking examples // (e.g. using DNAT on CloudStack), the brooklyn machine won't be able to reach the VM until // some additional // setup steps have been done. See links from Andrea: // https://github.com/jclouds/jclouds/pull/895 // https://issues.apache.org/jira/browse/WHIRR-420 // jclouds.ssh.max-retries // jclouds.ssh.retry-auth SshClient client; try { client = context.utils().sshForNode().apply(node); } catch (Exception e) { Exceptions.propagateIfFatal(e); /* i've seen: java.lang.IllegalStateException: Optional.get() cannot be called on an absent value * from org.jclouds.crypto.ASN1Codec.createASN1Sequence(ASN1Codec.java:86), if the ssh key has a passphrase, against AWS. * * others have reported: java.lang.IllegalArgumentException: DER length more than 4 bytes * when using a key with a passphrase (perhaps from other clouds?); not sure if that's this callpath or a different one. */ throw new IllegalStateException( "Unable to connect SshClient to " + node + "; check that the node is accessible and that the SSH key exists and is correctly configured, including any passphrase defined", e); } return client.getHostAddress(); }
@Override public List<String> associateAddresses(NodeMetadata node) { ComputeServiceContext context = iaasProvider.getComputeService().getContext(); String region = ComputeServiceBuilderUtil.extractRegion(iaasProvider); if (StringUtils.isEmpty(region)) { throw new RuntimeException( "Could not find region in iaas provider: " + iaasProvider.getName()); } NovaApi novaApi = context.unwrapApi(NovaApi.class); FloatingIPApi floatingIPApi = novaApi.getFloatingIPExtensionForZone(region).get(); String ip = null; // first try to find an unassigned IP. FluentIterable<FloatingIP> floatingIPs = floatingIPApi.list(); ArrayList<FloatingIP> unassignedIps = Lists.newArrayList( Iterables.filter( floatingIPs, new Predicate<FloatingIP>() { @Override public boolean apply(FloatingIP floatingIP) { return floatingIP.getInstanceId() == null; } })); if (!unassignedIps.isEmpty()) { // try to prevent multiple parallel launches from choosing the same ip. Collections.shuffle(unassignedIps); ip = Iterables.getLast(unassignedIps).getIp(); } // if no unassigned IP is available, we'll try to allocate an IP. if (StringUtils.isEmpty(ip)) { String floatingIpPool = iaasProvider.getProperty(CloudControllerConstants.DEFAULT_FLOATING_IP_POOL); FloatingIP allocatedFloatingIP; if (StringUtils.isEmpty(floatingIpPool)) { allocatedFloatingIP = floatingIPApi.create(); } else { log.debug( String.format( "Trying to allocate a floating IP address from IP pool %s", floatingIpPool)); allocatedFloatingIP = floatingIPApi.allocateFromPool(floatingIpPool); } if (allocatedFloatingIP == null) { String msg = String.format( "Floating IP API did not return a floating IP address from IP pool %s", floatingIpPool); log.error(msg); throw new CloudControllerException(msg); } ip = allocatedFloatingIP.getIp(); } // wait till the fixed IP address gets assigned - this is needed before // we associate a public IP log.info( String.format( "Waiting for private IP addresses get allocated: [node-id] %s", node.getId())); while (node.getPrivateAddresses() == null) { CloudControllerUtil.sleep(1000); } log.info(String.format("Private IP addresses allocated: %s", node.getPrivateAddresses())); if ((node.getPublicAddresses() != null) && (node.getPublicAddresses().iterator().hasNext())) { log.info( "Public IP address " + node.getPublicAddresses().iterator().next() + " is already allocated to the instance: [node-id] " + node.getId()); return null; } int retries = 0; int retryCount = Integer.getInteger("stratos.public.ip.association.retry.count", 5); while ((retries < retryCount) && (!associateIp(floatingIPApi, ip, node.getProviderId()))) { // wait for 5s CloudControllerUtil.sleep(5000); retries++; } log.info( String.format( "Successfully associated an IP address: [node-id] %s [ip] %s", node.getId(), ip)); List<String> allocatedIPAddresses = new ArrayList<String>(); allocatedIPAddresses.add(ip); return allocatedIPAddresses; }
@Override public ComputeService findComputeService(ConfigBag conf, boolean allowReuse) { String provider = checkNotNull(conf.get(CLOUD_PROVIDER), "provider must not be null"); String identity = checkNotNull(conf.get(CloudLocationConfig.ACCESS_IDENTITY), "identity must not be null"); String credential = checkNotNull( conf.get(CloudLocationConfig.ACCESS_CREDENTIAL), "credential must not be null"); Properties properties = new Properties(); properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, Boolean.toString(true)); properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, Boolean.toString(true)); properties.setProperty( "jclouds.ssh.max-retries", conf.getStringKey("jclouds.ssh.max-retries") != null ? conf.getStringKey("jclouds.ssh.max-retries").toString() : "50"); // Enable aws-ec2 lazy image fetching, if given a specific imageId; otherwise customize for // specific owners; or all as a last resort // See https://issues.apache.org/jira/browse/WHIRR-416 if ("aws-ec2".equals(provider)) { // TODO convert AWS-only flags to config keys if (groovyTruth(conf.get(IMAGE_ID))) { properties.setProperty(PROPERTY_EC2_AMI_QUERY, ""); properties.setProperty(PROPERTY_EC2_CC_AMI_QUERY, ""); } else if (groovyTruth(conf.getStringKey("imageOwner"))) { properties.setProperty( PROPERTY_EC2_AMI_QUERY, "owner-id=" + conf.getStringKey("imageOwner") + ";state=available;image-type=machine"); } else if (groovyTruth(conf.getStringKey("anyOwner"))) { // set `anyOwner: true` to override the default query (which is restricted to certain owners // as per below), // allowing the AMI query to bind to any machine // (note however, we sometimes pick defaults in JcloudsLocationFactory); // (and be careful, this can give a LOT of data back, taking several minutes, // and requiring extra memory allocated on the command-line) properties.setProperty(PROPERTY_EC2_AMI_QUERY, "state=available;image-type=machine"); /* * by default the following filters are applied: * Filter.1.Name=owner-id&Filter.1.Value.1=137112412989& * Filter.1.Value.2=063491364108& * Filter.1.Value.3=099720109477& * Filter.1.Value.4=411009282317& * Filter.2.Name=state&Filter.2.Value.1=available& * Filter.3.Name=image-type&Filter.3.Value.1=machine& */ } // occasionally can get com.google.common.util.concurrent.UncheckedExecutionException: // java.lang.RuntimeException: // security group eu-central-1/jclouds#brooklyn-bxza-alex-eu-central-shoul-u2jy-nginx-ielm // is not available after creating // the default timeout was 500ms so let's raise it in case that helps properties.setProperty( EC2Constants.PROPERTY_EC2_TIMEOUT_SECURITYGROUP_PRESENT, "" + Duration.seconds(30).toMilliseconds()); } // FIXME Deprecated mechanism, should have a ConfigKey for overrides Map<String, Object> extra = Maps.filterKeys(conf.getAllConfig(), Predicates.containsPattern("^jclouds\\.")); if (extra.size() > 0) { LOG.warn("Jclouds using deprecated property overrides: " + Sanitizer.sanitize(extra)); } properties.putAll(extra); String endpoint = conf.get(CloudLocationConfig.CLOUD_ENDPOINT); if (!groovyTruth(endpoint)) endpoint = getDeprecatedProperty(conf, Constants.PROPERTY_ENDPOINT); if (groovyTruth(endpoint)) properties.setProperty(Constants.PROPERTY_ENDPOINT, endpoint); Map<?, ?> cacheKey = MutableMap.builder() .putAll(properties) .put("provider", provider) .put("identity", identity) .put("credential", credential) .putIfNotNull("endpoint", endpoint) .build() .asUnmodifiable(); if (allowReuse) { ComputeService result = cachedComputeServices.get(cacheKey); if (result != null) { LOG.trace( "jclouds ComputeService cache hit for compute service, for " + Sanitizer.sanitize(properties)); return result; } LOG.debug( "jclouds ComputeService cache miss for compute service, creating, for " + Sanitizer.sanitize(properties)); } Iterable<Module> modules = getCommonModules(); // Synchronizing to avoid deadlock from sun.reflect.annotation.AnnotationType. // See https://github.com/brooklyncentral/brooklyn/issues/974 ComputeServiceContext computeServiceContext; synchronized (createComputeServicesMutex) { computeServiceContext = ContextBuilder.newBuilder(provider) .modules(modules) .credentials(identity, credential) .overrides(properties) .build(ComputeServiceContext.class); } final ComputeService computeService = computeServiceContext.getComputeService(); if (allowReuse) { synchronized (cachedComputeServices) { ComputeService result = cachedComputeServices.get(cacheKey); if (result != null) { LOG.debug( "jclouds ComputeService cache recovery for compute service, for " + Sanitizer.sanitize(cacheKey)); // keep the old one, discard the new one computeService.getContext().close(); return result; } LOG.debug( "jclouds ComputeService created " + computeService + ", adding to cache, for " + Sanitizer.sanitize(properties)); cachedComputeServices.put(cacheKey, computeService); } } return computeService; }
@Override public String associatePredefinedAddress(NodeMetadata node, String ip) { if (log.isDebugEnabled()) { log.debug( String.format( "Trying to associate predefined IP address: [node-id] %s [ip] %s", node.getId(), ip)); } ComputeServiceContext context = iaasProvider.getComputeService().getContext(); String region = ComputeServiceBuilderUtil.extractRegion(iaasProvider); FloatingIPApi floatingIPApi = context.unwrapApi(NovaApi.class).getFloatingIPExtensionForZone(region).get(); // get the list of all unassigned IP. ArrayList<FloatingIP> unassignedFloatingIPs = Lists.newArrayList( Iterables.filter( floatingIPApi.list(), new Predicate<FloatingIP>() { @Override public boolean apply(FloatingIP floatingIP) { return StringUtils.isEmpty(floatingIP.getFixedIp()); } })); boolean isAvailable = false; for (FloatingIP floatingIP : unassignedFloatingIPs) { if (log.isDebugEnabled()) { log.debug( "OpenstackNovaIaas:associatePredefinedAddress:iterating over available floatingip:" + floatingIP); } if (ip.equals(floatingIP.getIp())) { if (log.isDebugEnabled()) { log.debug( String.format( "OpenstackNovaIaas:associatePredefinedAddress:floating ip in use:%s /ip:%s", floatingIP, ip)); } isAvailable = true; break; } } if (isAvailable) { // assign ip if (log.isDebugEnabled()) { log.debug("OpenstackNovaIaas:associatePredefinedAddress:assign floating ip:" + ip); } // exercise same code as in associateAddress() // wait till the fixed IP address gets assigned - this is needed before // we associate a public IP while (node.getPrivateAddresses() == null) { CloudControllerUtil.sleep(1000); } int retries = 0; int retryCount = Integer.getInteger("stratos.public.ip.association.retry.count", 5); while (retries < retryCount && !associateIp(floatingIPApi, ip, node.getProviderId())) { // wait for 5s CloudControllerUtil.sleep(5000); retries++; } NodeMetadataBuilder.fromNodeMetadata(node).publicAddresses(ImmutableSet.of(ip)).build(); log.info( String.format( "Successfully associated predefined IP address: [node-id] %s [ip] %s ", node.getId(), ip)); return ip; } else { log.warn( String.format( "Could not associate predefined IP address: [node-id] %s [ip] %s ", node.getId(), ip)); return null; } }
public static CloudTransformer tranformerFor(ComputeServiceContext source, String target) { return checkNotNull( source.utils().injector().getInstance(Key.get(mapOfString)).get(target), " no transformer were registered for targget cloud: " + target); }