Example #1
0
def get_metadata_from_imds(fallback_nic, retries):
    """Query Azure's network metadata service, returning a dictionary.

    If network is not up, setup ephemeral dhcp on fallback_nic to talk to the
    IMDS. For more info on IMDS:
        https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service

    @param fallback_nic: String. The name of the nic which requires active
        network in order to query IMDS.
    @param retries: The number of retries of the IMDS_URL.

    @return: A dict of instance metadata containing compute and network
        info.
    """
    kwargs = {
        'logfunc': LOG.debug,
        'msg': 'Crawl of Azure Instance Metadata Service (IMDS)',
        'func': _get_metadata_from_imds,
        'args': (retries, )
    }
    if net.is_up(fallback_nic):
        return util.log_time(**kwargs)
    else:
        with EphemeralDHCPv4(fallback_nic):
            return util.log_time(**kwargs)
Example #2
0
 def test_is_up_false(self):
     """is_up is False if sys/net/devname/operstate is 'down' or invalid."""
     for state in ['down', 'incomprehensible']:
         write_file(os.path.join(self.sysdir, 'eth0', 'operstate'), state)
         self.assertFalse(net.is_up('eth0'))
Example #3
0
 def test_is_up_true(self):
     """is_up is True if sys/net/devname/operstate is 'up' or 'unknown'."""
     for state in ['up', 'unknown']:
         write_file(os.path.join(self.sysdir, 'eth0', 'operstate'), state)
         self.assertTrue(net.is_up('eth0'))
Example #4
0
    def crawl_metadata(self):
        """Walk all instance metadata sources returning a dict on success.

        @return: A dictionary of any metadata content for this instance.
        @raise: InvalidMetaDataException when the expected metadata service is
            unavailable, broken or disabled.
        """
        crawled_data = {}
        # azure removes/ejects the cdrom containing the ovf-env.xml
        # file on reboot.  So, in order to successfully reboot we
        # need to look in the datadir and consider that valid
        ddir = self.ds_cfg['data_dir']

        candidates = [self.seed_dir]
        if os.path.isfile(REPROVISION_MARKER_FILE):
            candidates.insert(0, "IMDS")
        candidates.extend(list_possible_azure_ds_devs())
        if ddir:
            candidates.append(ddir)

        found = None
        reprovision = False
        for cdev in candidates:
            try:
                if cdev == "IMDS":
                    ret = None
                    reprovision = True
                elif cdev.startswith("/dev/"):
                    if util.is_FreeBSD():
                        ret = util.mount_cb(cdev,
                                            load_azure_ds_dir,
                                            mtype="udf",
                                            sync=False)
                    else:
                        ret = util.mount_cb(cdev, load_azure_ds_dir)
                else:
                    ret = load_azure_ds_dir(cdev)

            except NonAzureDataSource:
                continue
            except BrokenAzureDataSource as exc:
                msg = 'BrokenAzureDataSource: %s' % exc
                raise sources.InvalidMetaDataException(msg)
            except util.MountFailedError:
                LOG.warning("%s was not mountable", cdev)
                continue

            perform_reprovision = reprovision or self._should_reprovision(ret)
            if perform_reprovision:
                if util.is_FreeBSD():
                    msg = "Free BSD is not supported for PPS VMs"
                    LOG.error(msg)
                    raise sources.InvalidMetaDataException(msg)
                ret = self._reprovision()
            imds_md = get_metadata_from_imds(self.fallback_interface,
                                             retries=10)
            (md, userdata_raw, cfg, files) = ret
            self.seed = cdev
            crawled_data.update({
                'cfg':
                cfg,
                'files':
                files,
                'metadata':
                util.mergemanydict([md, {
                    'imds': imds_md
                }]),
                'userdata_raw':
                userdata_raw
            })
            found = cdev

            LOG.debug("found datasource in %s", cdev)
            break

        if not found:
            raise sources.InvalidMetaDataException('No Azure metadata found')

        if found == ddir:
            LOG.debug("using files cached in %s", ddir)

        seed = _get_random_seed()
        if seed:
            crawled_data['metadata']['random_seed'] = seed
        crawled_data['metadata']['instance-id'] = util.read_dmi_data(
            'system-uuid')

        if perform_reprovision:
            LOG.info("Reporting ready to Azure after getting ReprovisionData")
            use_cached_ephemeral = (net.is_up(self.fallback_interface) and
                                    getattr(self, '_ephemeral_dhcp_ctx', None))
            if use_cached_ephemeral:
                self._report_ready(lease=self._ephemeral_dhcp_ctx.lease)
                self._ephemeral_dhcp_ctx.clean_network()  # Teardown ephemeral
            else:
                with EphemeralDHCPv4() as lease:
                    self._report_ready(lease=lease)

        return crawled_data
Example #5
0
 def is_up(self, devname: DeviceName) -> bool:
     return net.is_up(devname)
Example #6
0
 def test_is_up_false(self):
     """is_up is False if sys/net/devname/operstate is 'down' or invalid."""
     for state in ['down', 'incomprehensible']:
         write_file(os.path.join(self.sysdir, 'eth0', 'operstate'), state)
         self.assertFalse(net.is_up('eth0'))
Example #7
0
 def test_is_up_true(self):
     """is_up is True if sys/net/devname/operstate is 'up' or 'unknown'."""
     for state in ['up', 'unknown']:
         write_file(os.path.join(self.sysdir, 'eth0', 'operstate'), state)
         self.assertTrue(net.is_up('eth0'))