예제 #1
0
 def test_missing_ovf_env_xml_raises_non_azure_datasource_error(self):
     """load_azure_ds_dir raises an error When ovf-env.xml doesn't exit."""
     with self.assertRaises(dsaz.NonAzureDataSource) as context_manager:
         dsaz.load_azure_ds_dir(self.source_dir)
     self.assertEqual(
         'No ovf-env file found',
         str(context_manager.exception))
예제 #2
0
 def test_wb_invalid_ovf_env_xml_calls_read_azure_ovf(self):
     """load_azure_ds_dir calls read_azure_ovf to parse the xml."""
     ovf_path = os.path.join(self.source_dir, 'ovf-env.xml')
     with open(ovf_path, 'wb') as stream:
         stream.write(b'invalid xml')
     with self.assertRaises(dsaz.BrokenAzureDataSource) as context_manager:
         dsaz.load_azure_ds_dir(self.source_dir)
     self.assertEqual('Invalid ovf-env.xml: syntax error: line 1, column 0',
                      str(context_manager.exception))
예제 #3
0
 def test_three_partition_through_realpath_is_false(self):
     """A symlink to a device with 3 partitions can not be formatted."""
     epath = '/dev/disk/cloud/azure_resource'
     self.patchup({
         epath: {
             'realpath': '/dev/sdb',
             'partitions': {
                 epath + '-part1': {
                     'num': 1,
                     'fs': 'ntfs',
                     'files': [self.warning_file],
                     'realpath': '/dev/sdb1'
                 },
                 epath + '-part2': {
                     'num': 2,
                     'fs': 'ext3',
                     'realpath': '/dev/sdb2'
                 },
                 epath + '-part3': {
                     'num': 3,
                     'fs': 'ext',
                     'realpath': '/dev/sdb3'
                 }
             }
         }
     })
     value, msg = dsaz.can_dev_be_reformatted(epath)
     self.assertEqual(False, value)
     self.assertIn("3 or more", msg.lower())
예제 #4
0
 def _get_ds(self, ovfcontent=None):
     if ovfcontent is not None:
         populate_dir(os.path.join(self.paths.seed_dir, "azure"),
                      {'ovf-env.xml': ovfcontent})
     return DataSourceAzure.DataSourceAzureNet({},
                                               distro=None,
                                               paths=self.paths)
예제 #5
0
 def test_load_with_pubkeys(self):
     mypklist = [{'fingerprint': 'fp1', 'path': 'path1'}]
     pubkeys = [(x['fingerprint'], x['path']) for x in mypklist]
     content = construct_valid_ovf_env(pubkeys=pubkeys)
     (_md, _ud, cfg) = DataSourceAzure.read_azure_ovf(content)
     for mypk in mypklist:
         self.assertIn(mypk, cfg['_pubkeys'])
예제 #6
0
 def test_load_with_pubkeys(self):
     mypklist = [{'fingerprint': 'fp1', 'path': 'path1'}]
     pubkeys = [(x['fingerprint'], x['path']) for x in mypklist]
     content = construct_valid_ovf_env(pubkeys=pubkeys)
     (_md, _ud, cfg) = DataSourceAzure.read_azure_ovf(content)
     for mypk in mypklist:
         self.assertIn(mypk, cfg['_pubkeys'])
예제 #7
0
 def test_list_possible_azure_ds_devs(self, m_check_fbsd_cdrom,
                                      m_is_FreeBSD):
     """On FreeBSD, possible devs should show /dev/cd0."""
     m_is_FreeBSD.return_value = True
     m_check_fbsd_cdrom.return_value = True
     self.assertEqual(dsaz.list_possible_azure_ds_devs(), ['/dev/cd0'])
     self.assertEqual(
         [mock.call("/dev/cd0")], m_check_fbsd_cdrom.call_args_list)
예제 #8
0
 def _get_ds(self, ovfcontent=None, agent_command=None):
     if ovfcontent is not None:
         populate_dir(os.path.join(self.paths.seed_dir, "azure"),
                      {'ovf-env.xml': ovfcontent})
     dsrc = dsaz.DataSourceAzureNet({}, distro=None, paths=self.paths)
     if agent_command is not None:
         dsrc.ds_cfg['agent_command'] = agent_command
     return dsrc
예제 #9
0
 def test_one_partition_ntfs_empty_is_true(self):
     """1 mountable ntfs partition and no files can be formatted."""
     self.patchup({
         '/dev/sda': {
             'partitions': {
                 '/dev/sda1': {'num': 1, 'fs': 'ntfs', 'files': []}
             }}})
     value, msg = dsaz.can_dev_be_reformatted("/dev/sda")
     self.assertTrue(value)
     self.assertIn("safe for", msg.lower())
예제 #10
0
 def test_one_partition_not_ntfs_false(self):
     """1 partition witih fs other than ntfs can not be formatted."""
     self.patchup({
         '/dev/sda': {
             'partitions': {
                 '/dev/sda1': {'num': 1, 'fs': 'zfs'},
             }}})
     value, msg = dsaz.can_dev_be_reformatted("/dev/sda")
     self.assertFalse(value)
     self.assertIn("not ntfs", msg.lower())
예제 #11
0
    def _get_ds(self, data, agent_command=None):

        def dsdevs():
            return data.get('dsdevs', [])

        def _invoke_agent(cmd):
            data['agent_invoked'] = cmd

        def _wait_for_files(flist, _maxwait=None, _naplen=None):
            data['waited'] = flist
            return []

        def _pubkeys_from_crt_files(flist):
            data['pubkey_files'] = flist
            return ["pubkey_from: %s" % f for f in flist]

        if data.get('ovfcontent') is not None:
            populate_dir(os.path.join(self.paths.seed_dir, "azure"),
                         {'ovf-env.xml': data['ovfcontent']})

        dsaz.BUILTIN_DS_CONFIG['data_dir'] = self.waagent_d

        self.get_metadata_from_fabric = mock.MagicMock(return_value={
            'public-keys': [],
        })

        self.instance_id = 'test-instance-id'

        def _dmi_mocks(key):
            if key == 'system-uuid':
                return self.instance_id
            elif key == 'chassis-asset-tag':
                return '7783-7084-3265-9085-8269-3286-77'

        self.apply_patches([
            (dsaz, 'list_possible_azure_ds_devs', dsdevs),
            (dsaz, 'invoke_agent', _invoke_agent),
            (dsaz, 'pubkeys_from_crt_files', _pubkeys_from_crt_files),
            (dsaz, 'perform_hostname_bounce', mock.MagicMock()),
            (dsaz, 'get_hostname', mock.MagicMock()),
            (dsaz, 'set_hostname', mock.MagicMock()),
            (dsaz, 'get_metadata_from_fabric', self.get_metadata_from_fabric),
            (dsaz.util, 'which', lambda x: True),
            (dsaz.util, 'read_dmi_data', mock.MagicMock(
                side_effect=_dmi_mocks)),
            (dsaz.util, 'wait_for_files', mock.MagicMock(
                side_effect=_wait_for_files)),
        ])

        dsrc = dsaz.DataSourceAzure(
            data.get('sys_cfg', {}), distro=None, paths=self.paths)
        if agent_command is not None:
            dsrc.ds_cfg['agent_command'] = agent_command

        return dsrc
예제 #12
0
 def test_two_partitions_ntfs_empty_is_true(self):
     """2 partitions and empty ntfs fs on 2nd can be formatted."""
     self.patchup({
         '/dev/sda': {
             'partitions': {
                 '/dev/sda1': {'num': 1},
                 '/dev/sda2': {'num': 2, 'fs': 'ntfs', 'files': []},
             }}})
     value, msg = dsaz.can_dev_be_reformatted("/dev/sda")
     self.assertTrue(value)
     self.assertIn("safe for", msg.lower())
예제 #13
0
 def test_valid_content(self):
     xml = """<?xml version="1.0" encoding="utf-8"?>
         <SharedConfig>
          <Deployment name="MY_INSTANCE_ID">
           <Service name="myservice"/>
           <ServiceInstance name="INSTANCE_ID.0" guid="{abcd-uuid}" />
          </Deployment>
         <Incarnation number="1"/>
         </SharedConfig>"""
     ret = DataSourceAzure.iid_from_shared_config_content(xml)
     self.assertEqual("MY_INSTANCE_ID", ret)
예제 #14
0
 def test_one_partition_ntfs_empty_with_dataloss_file_is_true(self):
     """1 mountable ntfs partition and only warn file can be formatted."""
     self.patchup({
         '/dev/sda': {
             'partitions': {
                 '/dev/sda1': {'num': 1, 'fs': 'ntfs',
                               'files': ['dataloss_warning_readme.txt']}
             }}})
     value, msg = dsaz.can_dev_be_reformatted("/dev/sda")
     self.assertTrue(value)
     self.assertIn("safe for", msg.lower())
예제 #15
0
 def test_one_partition_ntfs_populated_false(self):
     """1 mountable ntfs partition with many files can not be formatted."""
     self.patchup({
         '/dev/sda': {
             'partitions': {
                 '/dev/sda1': {'num': 1, 'fs': 'ntfs',
                               'files': ['file1.txt', 'file2.exe']},
             }}})
     value, msg = dsaz.can_dev_be_reformatted("/dev/sda")
     self.assertFalse(value)
     self.assertIn("files on it", msg.lower())
예제 #16
0
 def test_two_partitions_not_ntfs_false(self):
     """2 partitions and 2nd not ntfs can not be formatted."""
     self.patchup({
         '/dev/sda': {
             'partitions': {
                 '/dev/sda1': {'num': 1},
                 '/dev/sda2': {'num': 2, 'fs': 'ext4', 'files': []},
             }}})
     value, msg = dsaz.can_dev_be_reformatted("/dev/sda")
     self.assertFalse(value)
     self.assertIn("not ntfs", msg.lower())
예제 #17
0
 def test_valid_content(self):
     xml = """<?xml version="1.0" encoding="utf-8"?>
         <SharedConfig>
          <Deployment name="MY_INSTANCE_ID">
           <Service name="myservice"/>
           <ServiceInstance name="INSTANCE_ID.0" guid="{abcd-uuid}" />
          </Deployment>
         <Incarnation number="1"/>
         </SharedConfig>"""
     ret = DataSourceAzure.iid_from_shared_config_content(xml)
     self.assertEqual("MY_INSTANCE_ID", ret)
예제 #18
0
 def test_two_partitions_ntfs_populated_false(self):
     """2 partitions and populated ntfs fs on 2nd can not be formatted."""
     self.patchup({
         '/dev/sda': {
             'partitions': {
                 '/dev/sda1': {'num': 1},
                 '/dev/sda2': {'num': 2, 'fs': 'ntfs',
                               'files': ['secret.txt']},
             }}})
     value, msg = dsaz.can_dev_be_reformatted("/dev/sda")
     self.assertFalse(value)
     self.assertIn("files on it", msg.lower())
예제 #19
0
 def test_three_partitions_is_false(self):
     """A disk with 3 partitions can not be formatted."""
     self.patchup({
         '/dev/sda': {
             'partitions': {
                 '/dev/sda1': {'num': 1},
                 '/dev/sda2': {'num': 2},
                 '/dev/sda3': {'num': 3},
             }}})
     value, msg = dsaz.can_dev_be_reformatted("/dev/sda")
     self.assertFalse(value)
     self.assertIn("3 or more", msg.lower())
예제 #20
0
 def test_one_partition_through_realpath_is_true(self):
     """A symlink to a device with 1 ntfs partition can be formatted."""
     epath = '/dev/disk/cloud/azure_resource'
     self.patchup({
         epath: {
             'realpath': '/dev/sdb',
             'partitions': {
                 epath + '-part1': {
                     'num': 1, 'fs': 'ntfs', 'files': [self.warning_file],
                     'realpath': '/dev/sdb1'}
             }}})
     value, msg = dsaz.can_dev_be_reformatted(epath)
     self.assertTrue(value)
     self.assertIn("safe for", msg.lower())
예제 #21
0
    def test_non_azure_dmi_chassis_asset_tag(self, m_read_dmi_data):
        """Report non-azure when DMI's chassis asset tag doesn't match.

        Return False when the asset tag doesn't match Azure's static
        AZURE_CHASSIS_ASSET_TAG.
        """
        # Return a non-matching asset tag value
        nonazure_tag = dsaz.AZURE_CHASSIS_ASSET_TAG + 'X'
        m_read_dmi_data.return_value = nonazure_tag
        dsrc = dsaz.DataSourceAzureNet({}, distro=None, paths=self.paths)
        self.assertFalse(dsrc.get_data())
        self.assertEqual(
            "Non-Azure DMI asset tag '{0}' discovered.\n".format(nonazure_tag),
            self.logs.getvalue())
예제 #22
0
def handle_args(name, args):
    if not args.directory.endswith("/"):
        args.directory += "/"

    if not os.path.isdir(args.directory):
        os.makedirs(args.directory)

    if args.debug:
        log.setupBasicLogging(level=log.DEBUG)
    else:
        log.setupBasicLogging(level=log.WARN)
    if args.mac:
        known_macs = {}
        for item in args.mac:
            iface_name, iface_mac = item.split(",", 1)
            known_macs[iface_mac] = iface_name
    else:
        known_macs = None

    net_data = args.network_data.read()
    if args.kind == "eni":
        pre_ns = eni.convert_eni_data(net_data)
        ns = network_state.parse_net_config_data(pre_ns)
    elif args.kind == "yaml":
        pre_ns = yaml.load(net_data)
        if 'network' in pre_ns:
            pre_ns = pre_ns.get('network')
        if args.debug:
            sys.stderr.write('\n'.join(
                ["Input YAML",
                 yaml.dump(pre_ns, default_flow_style=False, indent=4), ""]))
        ns = network_state.parse_net_config_data(pre_ns)
    elif args.kind == 'network_data.json':
        pre_ns = openstack.convert_net_json(
            json.loads(net_data), known_macs=known_macs)
        ns = network_state.parse_net_config_data(pre_ns)
    elif args.kind == 'azure-imds':
        pre_ns = azure.parse_network_config(json.loads(net_data))
        ns = network_state.parse_net_config_data(pre_ns)

    if not ns:
        raise RuntimeError("No valid network_state object created from"
                           "input data")

    if args.debug:
        sys.stderr.write('\n'.join([
            "", "Internal State",
            yaml.dump(ns, default_flow_style=False, indent=4), ""]))
    distro_cls = distros.fetch(args.distro)
    distro = distro_cls(args.distro, {}, None)
    config = {}
    if args.output_kind == "eni":
        r_cls = eni.Renderer
        config = distro.renderer_configs.get('eni')
    elif args.output_kind == "netplan":
        r_cls = netplan.Renderer
        config = distro.renderer_configs.get('netplan')
    else:
        r_cls = sysconfig.Renderer
        config = distro.renderer_configs.get('sysconfig')

    r = r_cls(config=config)
    sys.stderr.write(''.join([
        "Read input format '%s' from '%s'.\n" % (
            args.kind, args.network_data.name),
        "Wrote output format '%s' to '%s'\n" % (
            args.output_kind, args.directory)]) + "\n")
    r.render_network_state(network_state=ns, target=args.directory)
예제 #23
0
 def test_no_partitions_is_false(self):
     """A disk with no partitions can not be formatted."""
     self.patchup({'/dev/sda': {}})
     value, msg = dsaz.can_dev_be_reformatted("/dev/sda")
     self.assertEqual(False, value)
     self.assertIn("not partitioned", msg.lower())
예제 #24
0
def handle_args(name, args):
    if not args.directory.endswith("/"):
        args.directory += "/"

    if not os.path.isdir(args.directory):
        os.makedirs(args.directory)

    if args.debug:
        log.setupBasicLogging(level=log.DEBUG)
    else:
        log.setupBasicLogging(level=log.WARN)
    if args.mac:
        known_macs = {}
        for item in args.mac:
            iface_name, iface_mac = item.split(",", 1)
            known_macs[iface_mac] = iface_name
    else:
        known_macs = None

    net_data = args.network_data.read()
    if args.kind == "eni":
        pre_ns = eni.convert_eni_data(net_data)
    elif args.kind == "yaml":
        pre_ns = safeyaml.load(net_data)
        if 'network' in pre_ns:
            pre_ns = pre_ns.get('network')
        if args.debug:
            sys.stderr.write('\n'.join(
                ["Input YAML", safeyaml.dumps(pre_ns), ""]))
    elif args.kind == 'network_data.json':
        pre_ns = openstack.convert_net_json(
            json.loads(net_data), known_macs=known_macs)
    elif args.kind == 'azure-imds':
        pre_ns = azure.parse_network_config(json.loads(net_data))
    elif args.kind == 'vmware-imc':
        config = ovf.Config(ovf.ConfigFile(args.network_data.name))
        pre_ns = ovf.get_network_config_from_conf(config, False)

    ns = network_state.parse_net_config_data(pre_ns)

    if args.debug:
        sys.stderr.write('\n'.join(
            ["", "Internal State", safeyaml.dumps(ns), ""]))
    distro_cls = distros.fetch(args.distro)
    distro = distro_cls(args.distro, {}, None)
    config = {}
    if args.output_kind == "eni":
        r_cls = eni.Renderer
        config = distro.renderer_configs.get('eni')
    elif args.output_kind == "netplan":
        r_cls = netplan.Renderer
        config = distro.renderer_configs.get('netplan')
        # don't run netplan generate/apply
        config['postcmds'] = False
        # trim leading slash
        config['netplan_path'] = config['netplan_path'][1:]
        # enable some netplan features
        config['features'] = ['dhcp-use-domains', 'ipv6-mtu']
    elif args.output_kind == "networkd":
        r_cls = networkd.Renderer
        config = distro.renderer_configs.get('networkd')
    elif args.output_kind == "sysconfig":
        r_cls = sysconfig.Renderer
        config = distro.renderer_configs.get('sysconfig')
    else:
        raise RuntimeError("Invalid output_kind")

    r = r_cls(config=config)
    sys.stderr.write(''.join([
        "Read input format '%s' from '%s'.\n" % (
            args.kind, args.network_data.name),
        "Wrote output format '%s' to '%s'\n" % (
            args.output_kind, args.directory)]) + "\n")
    r.render_network_state(network_state=ns, target=args.directory)
예제 #25
0
def handle_args(name, args):
    if not args.directory.endswith("/"):
        args.directory += "/"

    if not os.path.isdir(args.directory):
        os.makedirs(args.directory)

    if args.debug:
        log.setupBasicLogging(level=log.DEBUG)
    else:
        log.setupBasicLogging(level=log.WARN)
    if args.mac:
        known_macs = {}
        for item in args.mac:
            iface_name, iface_mac = item.split(",", 1)
            known_macs[iface_mac] = iface_name
    else:
        known_macs = None

    net_data = args.network_data.read()
    if args.kind == "eni":
        pre_ns = eni.convert_eni_data(net_data)
    elif args.kind == "yaml":
        pre_ns = yaml.load(net_data)
        if 'network' in pre_ns:
            pre_ns = pre_ns.get('network')
        if args.debug:
            sys.stderr.write('\n'.join(
                ["Input YAML",
                 yaml.dump(pre_ns, default_flow_style=False, indent=4), ""]))
    elif args.kind == 'network_data.json':
        pre_ns = openstack.convert_net_json(
            json.loads(net_data), known_macs=known_macs)
    elif args.kind == 'azure-imds':
        pre_ns = azure.parse_network_config(json.loads(net_data))
    elif args.kind == 'vmware-imc':
        config = ovf.Config(ovf.ConfigFile(args.network_data.name))
        pre_ns = ovf.get_network_config_from_conf(config, False)

    ns = network_state.parse_net_config_data(pre_ns)
    if not ns:
        raise RuntimeError("No valid network_state object created from"
                           "input data")

    if args.debug:
        sys.stderr.write('\n'.join([
            "", "Internal State",
            yaml.dump(ns, default_flow_style=False, indent=4), ""]))
    distro_cls = distros.fetch(args.distro)
    distro = distro_cls(args.distro, {}, None)
    config = {}
    if args.output_kind == "eni":
        r_cls = eni.Renderer
        config = distro.renderer_configs.get('eni')
    elif args.output_kind == "netplan":
        r_cls = netplan.Renderer
        config = distro.renderer_configs.get('netplan')
        # don't run netplan generate/apply
        config['postcmds'] = False
        # trim leading slash
        config['netplan_path'] = config['netplan_path'][1:]
    else:
        r_cls = sysconfig.Renderer
        config = distro.renderer_configs.get('sysconfig')

    r = r_cls(config=config)
    sys.stderr.write(''.join([
        "Read input format '%s' from '%s'.\n" % (
            args.kind, args.network_data.name),
        "Wrote output format '%s' to '%s'\n" % (
            args.output_kind, args.directory)]) + "\n")
    r.render_network_state(network_state=ns, target=args.directory)