Summary:
Brooklyn conflates the management address of an entity with its public
address. I want to break this by publishing a new sensor called
management.host.address on entities that use JcloudsLocation and using
it in preference to host.address when creating SSH connections and
polling feeds. Its value is the entity's host.subnet.address if that is
accessible, otherwise host.address.
Some background:
JcloudsLocation makes a guess at the best host and port to use for SSH
connections to each instance. The value it chooses subsequently informs
a variety of entity sensors, most importantly the "host.address" sensor
which itself informs the address at which various feeds are polled and
other sensors like "main.uri". Right now Brooklyn always prefers a value
from the set of "public" addresses returned by the cloud. Internally to
JcloudsLocation the value that is picked is referred to as the
"management host and port", but by subsequently using it for
host.address we conflate it with the publicly accessible address.
An obvious change to make to this is to have Brooklyn use the private
address for SSH connections when it's on the same subnet as the thing it
has provisioned. In order to do this without mucking up all of the
existing assumptions I propose we introduce a new sensor called
"management.host.address", whose value is a reachable private address,
if one exists, and otherwise the value chosen for the public address.
When creating SSH connections SshMachineLocation would check for the
management address and fall back to its current behaviour if it's unset.
An alternative is to have SshMachineLocation itself work out whether it
can connect to a private address. I do not like this option because we
would be unable to reuse the information that a private address is
better in entity feeds and BrooklynAccessUtils.
Svet raised the excellent point that we risk having an instance's
private address match an irrelevant machine on the same network as
Brooklyn. To resolve this he suggests that we change the check for
reachability to also test credentials rather than simply trying to open
a socket as happens at the moment.
I'm going to start on an implementation of this. Any feedback or questions?
Sam