You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@jclouds.apache.org by Daniel Widdis <wi...@gmail.com> on 2014/06/02 19:38:58 UTC

Re: Specifying only public or private IP for RunScriptOnNode

Ignasi,

Thanks so much for putting that fix in for 1.7.3.  I've updated my 
jclouds dependencies and am trying to update my source to access the new 
feature.  Unfortunately I'm (possibly) stuck in interpreting the API.  
Reading the Javadoc [1], I note the allowed interfaces for the property 
are specified as PUBLIC, PRIVATE or ALL, but written without quotation 
marks implying they are an enum/constant rather than a String, but I 
can't find anywhere else in the API where these are defined as a 
constant value [2].  Looking at the source code, there is nowhere that I 
see a string defined, and the code changes appear to reference an enum 
AllowedInterfaces which is set @VisibleForTesting so I don't have access 
to it.

I've tried the following: 
overrides.setProperty(SOCKET_FINDER_ALLOWED_INTERFACES, "PRIVATE");

This at least doesn't give me an error, but I suspect it's wrong. Should 
I be doing something else, such as putting a copy of that 
AllowedInterfaces enum in my code, for example?

Dan

  [1] 
http://javadocs.jclouds.cloudbees.net/org/jclouds/compute/config/ComputeServiceProperties.html#SOCKET_FINDER_ALLOWED_INTERFACES
  [2] http://javadocs.jclouds.cloudbees.net/constant-values.html

On 5/25/14, 12:01 PM, Ignasi Barrera wrote:
> Hi Daniel,
>
> This was reported recently (see JCLOUDS-528 [1]) and fixed in master.
> If you use the latest 1.8.0-SNAPSHOT version you should be able to set
> the ""jclouds.compute.socket-finder-allowed-interfaces" property to
> control which IP addresses are used to connect to the node (see [2]).
>
> We are about to release 1.7.3, and if no one says the opposite I'll
> back port that fix in a while, so if that works for you, you should be
> able to use it in the next release.
>
> HTH!
>
>
> [1] https://issues.apache.org/jira/browse/JCLOUDS-528
> [2] https://github.com/jclouds/jclouds/blob/master/compute/src/main/java/org/jclouds/compute/config/ComputeServiceProperties.java#L111-L114
>
> On 25 May 2014 18:59, Daniel Widdis <wi...@gmail.com> wrote:
>> I am using jclouds to provision and configure servers on a Rackspace Hybrid
>> Cloud.  Specifically, I have a dedicated/managed server, which I connect to
>> via VPN, and regularly need to start up additional cloud servers to offload
>> some processing work.  The sequence of events on the server side is:
>>
>> 1. Server is created with a public IP and private IP
>> 2. Server starts up and becomes accessible via ssh
>> 3. Immediately after becoming accessible, a script executes on the Rackspace
>> side to disable the public IP
>> 4. The script proceeds to connect to the server as root and configure it
>> with a "RackConnect" IP address.  This is still a publicly reachable address
>> but is different than the original Public IP.
>>
>> My code is similar to the example at
>> https://github.com/jclouds/jclouds-examples/blob/master/rackspace/src/main/java/org/jclouds/examples/rackspace/cloudservers/CloudServersPublish.java
>> with the exception that I am using the privateIP for the awaitSsh() call.
>> However, the RunScriptOnNode() call uses the NodeMetadata as an argument,
>> and apparently attempts to connect to both public and private IP addresses.
>> Most of the time, my connection occurs in between steps 3 and 4 above,
>> before the RackConnect IP is provisioned, and I experience no problems.  But
>> about 2-3% of the time, RunScriptOnNode attempts to use the RackConnect IP.
>>
>> Because of the way Rackspace operates their firewall, if public connections
>> to my hybrid cloud are turned off, then connections on the RackConnect IP
>> time out, rather than being refused.  This gives me the unfortunate result
>> of failed connections.  What is frustrating is that although the code
>> attempts to reconnect multiple times, it continues to try the (timing out)
>> RackConnect IP rather than attempting any other IP (such as the private IP,
>> which is accessible.)
>>
>> A similar issue was discussed on this thread:
>> https://groups.google.com/forum/#!topic/jclouds/TBpDtt9jaTo  In that case,
>> the user wanted the public IP rather than the private, but the inability to
>> choose between them is noted.  At the end of that thread, it was implied
>> that an issue was filed in github. However, the project has since moved to
>> Apache and I have not been able to find anything related to this issue in
>> the current JIRA tracking system.
>>
>> Of note, the RackConnect IP is placed in the " accessIPv4" field, and added
>> to the list of public addresses from there (see
>> https://issues.apache.org/jira/browse/JCLOUDS-355 )  I don't know if this is
>> relevant.
>>
>> Ultimately, this boils down to a possible bug, and a feature request:
>>
>> 1. It may be a bug that the RunScriptOnNode() method does not attempt any
>> other IPs after expeirencing a failed/timed-out connection on one of them.
>>
>> 2. It would be a nice-to-have feature to modify the RunScriptOnNode method
>> to allow a user to specify either public (to deconflict with another private
>> network) or private (to avoid bandwidth charges and allow firewalled
>> security measures) IP addresses, as discussed in the mailing list thread
>> cited above.
>>
>> Dan


Re: Specifying only public or private IP for RunScriptOnNode

Posted by Ignasi Barrera <na...@apache.org>.
Ah OK :) I had in mind to look at it later and just went through it
without reading the thread again :)

Good to see it is working!

I.

On 3 June 2014 00:28, Daniel Widdis <wi...@gmail.com> wrote:
> Ignasi,
>
> As I impled earlier, it looks like it does work (I tested to be sure it
> worked for "ALL" and "PRIVATE" and did not work for "PUBLIC" in my setup). I
> was unaware of how the string-to-enum conversion worked, but Andrew
> indicated it was probably something in Guice, which was a good enough
> explanation for me!
>
> My only confusion was where the API said to set the string to PRIVATE rather
> than setting it to "PRIVATE", making me think it might have been looking for
> some other enum/constant rather than the (obvious in hindsight) string
> itself.
>
> As for my code, it's rather simple and I posted the relevant half of it
> already...  I import the appropriate property string:
>
> import static
> org.jclouds.compute.config.ComputeServiceProperties.SOCKET_FINDER_ALLOWED_INTERFACES;
>
> And then I assign it:
>
>
>     Properties overrides = new Properties();
>     overrides.setProperty(SOCKET_FINDER_ALLOWED_INTERFACES, "PRIVATE");
>
> And then the overrides(overrides) gets added onto the ContextBuilder.
>
> Dan
>
>
> On 6/2/14, 3:04 PM, Ignasi Barrera wrote:
>>
>>
>> Could you share your code in a Gist or Pastie so we can see if there
>> is something wrong?
>>
>>
>

Re: Specifying only public or private IP for RunScriptOnNode

Posted by Daniel Widdis <wi...@gmail.com>.
Ignasi,

As I impled earlier, it looks like it does work (I tested to be sure it 
worked for "ALL" and "PRIVATE" and did not work for "PUBLIC" in my 
setup). I was unaware of how the string-to-enum conversion worked, but 
Andrew indicated it was probably something in Guice, which was a good 
enough explanation for me!

My only confusion was where the API said to set the string to PRIVATE 
rather than setting it to "PRIVATE", making me think it might have been 
looking for some other enum/constant rather than the (obvious in 
hindsight) string itself.

As for my code, it's rather simple and I posted the relevant half of it 
already...  I import the appropriate property string:

import static 
org.jclouds.compute.config.ComputeServiceProperties.SOCKET_FINDER_ALLOWED_INTERFACES;

And then I assign it:

     Properties overrides = new Properties();
     overrides.setProperty(SOCKET_FINDER_ALLOWED_INTERFACES, "PRIVATE");

And then the overrides(overrides) gets added onto the ContextBuilder.

Dan

On 6/2/14, 3:04 PM, Ignasi Barrera wrote:
>
> Could you share your code in a Gist or Pastie so we can see if there
> is something wrong?
>
>

Re: Specifying only public or private IP for RunScriptOnNode

Posted by Ignasi Barrera <ig...@gmail.com>.
I've just tested the following code with 1.7.3 (with DigitalOcean, but
the provider is not relevant):

Properties overrides = new Properties();
overrides.setProperty(SOCKET_FINDER_ALLOWED_INTERFACES, "PRIVATE");

ComputeServiceContext context = ContextBuilder.newBuilder("digitalocean")
   .credentials("foo", "bar")
   .modules(ImmutableSet.of(new SshjSshClientModule()))
   .overrides(overrides)
   .buildView(ComputeServiceContext.class);

ComputeService compute = context.getComputeService();
TemplateOptions options = compute.templateOptions().runScript("uptime");
NodeMetadata node =
getOnlyElement(compute.createNodesInGroup("access", 1, options));


And it properly worked: DigittalOcean by default only provides a
public IP, and the code failed to run the script saying:

1) IllegalStateException on node 1769496:
java.lang.IllegalStateException: node does not have IP addresses
configured: <node info>
   at com.google.common.base.Preconditions.checkState(Preconditions.java:177)
   at org.jclouds.compute.util.ConcurrentOpenSocketFinder.checkNodeHasIps(ConcurrentOpenSocketFinder.java:191)
   ...

Which is the expected behavior. With that configuration, only private
addresses are configured, so the feature works as expected.

Could you share your code in a Gist or Pastie so we can see if there
is something wrong?


On 2 June 2014 21:05, Andrew Phillips <an...@apache.org> wrote:
>> If it is (which it seems to be), I'm good to go.
>
>
> I'm also guessing a bit here (we'll see what the experts have to say ;-)),
> but as far as I am aware, Guice is the one providing the string-to-enum
> conversion as part of it's out-of-the-box binding support [2].
>
>
> [1] https://code.google.com/p/google-guice/
> [2]
> http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/Binder.html,
> search for "all enums"

Re: Specifying only public or private IP for RunScriptOnNode

Posted by Andrew Phillips <an...@apache.org>.
> If it is (which it seems to be), I'm good to go.

I'm also guessing a bit here (we'll see what the experts have to say  
;-)), but as far as I am aware, Guice is the one providing the  
string-to-enum conversion as part of it's out-of-the-box binding  
support [2].


[1] https://code.google.com/p/google-guice/
[2]  
http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/Binder.html, search for "all  
enums"

Re: Specifying only public or private IP for RunScriptOnNode

Posted by Daniel Widdis <wi...@gmail.com>.
Thanks for the quick reply, Andrew!

I do think it's working... I've tried specifying "PUBLIC" (which I've 
made impossible via firewall) and it (correctly) times out on me, so it 
is behaving as expected.  It's just more of a black box to me as to why 
it is!

Unfortunately, I am unable to import AllowedInterfaces because it is a 
@VisibleForTesting enum, so is otherwise inaccessible (i.e., I can't do 
AllowedInterfaces.PRIVATE).

Similarly, it looks like an explicit conversion using 
AllowedInterfaces.valueOf("PRIVATE") should work for string-to-Enum 
conversion, but is also not possible for me to do because of the 
visibility of AllowedInterfaces.

My concern (possibly based on Java inexperience/ignorance) is whether my 
string value "PRIVATE" is properly translated to the enum 
AllowedInterfaces.PRIVATE internally using other methods that I may be 
unaware of. If it is (which it seems to be), I'm good to go.

Dan

On 6/2/14, 10:48 AM, Andrew Phillips wrote:
>> I've tried the following: 
>> overrides.setProperty(SOCKET_FINDER_ALLOWED_INTERFACES, "PRIVATE");
>
> That looks correct to me, Dan. If the conversion from a string is not 
> working (it may only work as a string if set via a -D property on the 
> command line? I'm not sure), you may want to import 
> org.jclouds.compute.util.ConcurrentOpenSocketFinder.AllowedInterfaces 
> and set the value to AllowedInterfaces.PRIVATE [1] instead.
>
> Hope that helps!
>
> ap
>
> [1] 
> https://git-wip-us.apache.org/repos/asf?p=jclouds.git;a=commitdiff;h=5cc4659


Re: Specifying only public or private IP for RunScriptOnNode

Posted by Andrew Phillips <an...@apache.org>.
> I've tried the following:  
> overrides.setProperty(SOCKET_FINDER_ALLOWED_INTERFACES, "PRIVATE");

That looks correct to me, Dan. If the conversion from a string is not  
working (it may only work as a string if set via a -D property on the  
command line? I'm not sure), you may want to import  
org.jclouds.compute.util.ConcurrentOpenSocketFinder.AllowedInterfaces  
and set the value to AllowedInterfaces.PRIVATE [1] instead.

Hope that helps!

ap

[1]  
https://git-wip-us.apache.org/repos/asf?p=jclouds.git;a=commitdiff;h=5cc4659