diff options
Diffstat (limited to 'cloudinit/net/__init__.py')
| -rw-r--r-- | cloudinit/net/__init__.py | 42 | 
1 files changed, 38 insertions, 4 deletions
| diff --git a/cloudinit/net/__init__.py b/cloudinit/net/__init__.py index f83d3681..3642fb1f 100644 --- a/cloudinit/net/__init__.py +++ b/cloudinit/net/__init__.py @@ -12,6 +12,7 @@ import re  from cloudinit.net.network_state import mask_to_net_prefix  from cloudinit import util +from cloudinit.url_helper import UrlError, readurl  LOG = logging.getLogger(__name__)  SYS_CLASS_NET = "/sys/class/net/" @@ -612,7 +613,8 @@ def get_interfaces():      Bridges and any devices that have a 'stolen' mac are excluded."""      ret = []      devs = get_devicelist() -    empty_mac = '00:00:00:00:00:00' +    # 16 somewhat arbitrarily chosen.  Normally a mac is 6 '00:' tokens. +    zero_mac = ':'.join(('00',) * 16)      for name in devs:          if not interface_has_own_mac(name):              continue @@ -624,7 +626,8 @@ def get_interfaces():          # some devices may not have a mac (tun0)          if not mac:              continue -        if mac == empty_mac and name != 'lo': +        # skip nics that have no mac (00:00....) +        if name != 'lo' and mac == zero_mac[:len(mac)]:              continue          ret.append((name, mac, device_driver(name), device_devid(name)))      return ret @@ -645,16 +648,36 @@ def get_ib_hwaddrs_by_interface():      return ret +def has_url_connectivity(url): +    """Return true when the instance has access to the provided URL + +    Logs a warning if url is not the expected format. +    """ +    if not any([url.startswith('http://'), url.startswith('https://')]): +        LOG.warning( +            "Ignoring connectivity check. Expected URL beginning with http*://" +            " received '%s'", url) +        return False +    try: +        readurl(url, timeout=5) +    except UrlError: +        return False +    return True + +  class EphemeralIPv4Network(object):      """Context manager which sets up temporary static network configuration. -    No operations are performed if the provided interface is already connected. +    No operations are performed if the provided interface already has the +    specified configuration. +    This can be verified with the connectivity_url.      If unconnected, bring up the interface with valid ip, prefix and broadcast.      If router is provided setup a default route for that interface. Upon      context exit, clean up the interface leaving no configuration behind.      """ -    def __init__(self, interface, ip, prefix_or_mask, broadcast, router=None): +    def __init__(self, interface, ip, prefix_or_mask, broadcast, router=None, +                 connectivity_url=None):          """Setup context manager and validate call signature.          @param interface: Name of the network interface to bring up. @@ -663,6 +686,8 @@ class EphemeralIPv4Network(object):              prefix.          @param broadcast: Broadcast address for the IPv4 network.          @param router: Optionally the default gateway IP. +        @param connectivity_url: Optionally, a URL to verify if a usable +           connection already exists.          """          if not all([interface, ip, prefix_or_mask, broadcast]):              raise ValueError( @@ -673,6 +698,8 @@ class EphemeralIPv4Network(object):          except ValueError as e:              raise ValueError(                  'Cannot setup network: {0}'.format(e)) + +        self.connectivity_url = connectivity_url          self.interface = interface          self.ip = ip          self.broadcast = broadcast @@ -681,6 +708,13 @@ class EphemeralIPv4Network(object):      def __enter__(self):          """Perform ephemeral network setup if interface is not connected.""" +        if self.connectivity_url: +            if has_url_connectivity(self.connectivity_url): +                LOG.debug( +                    'Skip ephemeral network setup, instance has connectivity' +                    ' to %s', self.connectivity_url) +                return +          self._bringup_device()          if self.router:              self._bringup_router() | 
