Blame tests/unittests/test_datasource/test_ibmcloud.py

Packit Service a04d08
# This file is part of cloud-init. See LICENSE file for license information.
Packit Service a04d08
Packit Service a04d08
from cloudinit.helpers import Paths
Packit Service a04d08
from cloudinit.sources import DataSourceIBMCloud as ibm
Packit Service a04d08
from cloudinit.tests import helpers as test_helpers
Packit Service a04d08
from cloudinit import util
Packit Service a04d08
Packit Service a04d08
import base64
Packit Service a04d08
import copy
Packit Service a04d08
import json
Packit Service a04d08
from textwrap import dedent
Packit Service a04d08
Packit Service a04d08
mock = test_helpers.mock
Packit Service a04d08
Packit Service a04d08
D_PATH = "cloudinit.sources.DataSourceIBMCloud."
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
@mock.patch(D_PATH + "_is_xen", return_value=True)
Packit Service a04d08
@mock.patch(D_PATH + "_is_ibm_provisioning")
Packit Service a04d08
@mock.patch(D_PATH + "util.blkid")
Packit Service a04d08
class TestGetIBMPlatform(test_helpers.CiTestCase):
Packit Service a04d08
    """Test the get_ibm_platform helper."""
Packit Service a04d08
Packit Service a04d08
    blkid_base = {
Packit Service a04d08
        "/dev/xvda1": {
Packit Service a04d08
            "DEVNAME": "/dev/xvda1", "LABEL": "cloudimg-bootfs",
Packit Service a04d08
            "TYPE": "ext3"},
Packit Service a04d08
        "/dev/xvda2": {
Packit Service a04d08
            "DEVNAME": "/dev/xvda2", "LABEL": "cloudimg-rootfs",
Packit Service a04d08
            "TYPE": "ext4"},
Packit Service a04d08
    }
Packit Service a04d08
Packit Service a04d08
    blkid_metadata_disk = {
Packit Service a04d08
        "/dev/xvdh1": {
Packit Service a04d08
            "DEVNAME": "/dev/xvdh1", "LABEL": "METADATA", "TYPE": "vfat",
Packit Service a04d08
            "SEC_TYPE": "msdos", "UUID": "681B-8C5D",
Packit Service a04d08
            "PARTUUID": "3d631e09-01"},
Packit Service a04d08
    }
Packit Service a04d08
Packit Service a04d08
    blkid_oscode_disk = {
Packit Service a04d08
        "/dev/xvdh": {
Packit Service a04d08
            "DEVNAME": "/dev/xvdh", "LABEL": "config-2", "TYPE": "vfat",
Packit Service a04d08
            "SEC_TYPE": "msdos", "UUID": ibm.IBM_CONFIG_UUID}
Packit Service a04d08
    }
Packit Service a04d08
Packit Service a04d08
    def setUp(self):
Packit Service a04d08
        self.blkid_metadata = copy.deepcopy(self.blkid_base)
Packit Service a04d08
        self.blkid_metadata.update(copy.deepcopy(self.blkid_metadata_disk))
Packit Service a04d08
Packit Service a04d08
        self.blkid_oscode = copy.deepcopy(self.blkid_base)
Packit Service a04d08
        self.blkid_oscode.update(copy.deepcopy(self.blkid_oscode_disk))
Packit Service a04d08
Packit Service a04d08
    def test_id_template_live_metadata(self, m_blkid, m_is_prov, _m_xen):
Packit Service a04d08
        """identify TEMPLATE_LIVE_METADATA."""
Packit Service a04d08
        m_blkid.return_value = self.blkid_metadata
Packit Service a04d08
        m_is_prov.return_value = False
Packit Service a04d08
        self.assertEqual(
Packit Service a04d08
            (ibm.Platforms.TEMPLATE_LIVE_METADATA, "/dev/xvdh1"),
Packit Service a04d08
            ibm.get_ibm_platform())
Packit Service a04d08
Packit Service a04d08
    def test_id_template_prov_metadata(self, m_blkid, m_is_prov, _m_xen):
Packit Service a04d08
        """identify TEMPLATE_PROVISIONING_METADATA."""
Packit Service a04d08
        m_blkid.return_value = self.blkid_metadata
Packit Service a04d08
        m_is_prov.return_value = True
Packit Service a04d08
        self.assertEqual(
Packit Service a04d08
            (ibm.Platforms.TEMPLATE_PROVISIONING_METADATA, "/dev/xvdh1"),
Packit Service a04d08
            ibm.get_ibm_platform())
Packit Service a04d08
Packit Service a04d08
    def test_id_template_prov_nodata(self, m_blkid, m_is_prov, _m_xen):
Packit Service a04d08
        """identify TEMPLATE_PROVISIONING_NODATA."""
Packit Service a04d08
        m_blkid.return_value = self.blkid_base
Packit Service a04d08
        m_is_prov.return_value = True
Packit Service a04d08
        self.assertEqual(
Packit Service a04d08
            (ibm.Platforms.TEMPLATE_PROVISIONING_NODATA, None),
Packit Service a04d08
            ibm.get_ibm_platform())
Packit Service a04d08
Packit Service a04d08
    def test_id_os_code(self, m_blkid, m_is_prov, _m_xen):
Packit Service a04d08
        """Identify OS_CODE."""
Packit Service a04d08
        m_blkid.return_value = self.blkid_oscode
Packit Service a04d08
        m_is_prov.return_value = False
Packit Service a04d08
        self.assertEqual((ibm.Platforms.OS_CODE, "/dev/xvdh"),
Packit Service a04d08
                         ibm.get_ibm_platform())
Packit Service a04d08
Packit Service a04d08
    def test_id_os_code_must_match_uuid(self, m_blkid, m_is_prov, _m_xen):
Packit Service a04d08
        """Test against false positive on openstack with non-ibm UUID."""
Packit Service a04d08
        blkid = self.blkid_oscode
Packit Service a04d08
        blkid["/dev/xvdh"]["UUID"] = "9999-9999"
Packit Service a04d08
        m_blkid.return_value = blkid
Packit Service a04d08
        m_is_prov.return_value = False
Packit Service a04d08
        self.assertEqual((None, None), ibm.get_ibm_platform())
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
@mock.patch(D_PATH + "_read_system_uuid", return_value=None)
Packit Service a04d08
@mock.patch(D_PATH + "get_ibm_platform")
Packit Service a04d08
class TestReadMD(test_helpers.CiTestCase):
Packit Service a04d08
    """Test the read_datasource helper."""
Packit Service a04d08
Packit Service a04d08
    template_md = {
Packit Service a04d08
        "files": [],
Packit Service a04d08
        "network_config": {"content_path": "/content/interfaces"},
Packit Service a04d08
        "hostname": "ci-fond-ram",
Packit Service a04d08
        "name": "ci-fond-ram",
Packit Service a04d08
        "domain": "testing.ci.cloud-init.org",
Packit Service a04d08
        "meta": {"dsmode": "net"},
Packit Service a04d08
        "uuid": "8e636730-9f5d-c4a5-327c-d7123c46e82f",
Packit Service a04d08
        "public_keys": {"1091307": "ssh-rsa AAAAB3NzaC1...Hw== ci-pubkey"},
Packit Service a04d08
    }
Packit Service a04d08
Packit Service a04d08
    oscode_md = {
Packit Service a04d08
        "hostname": "ci-grand-gannet.testing.ci.cloud-init.org",
Packit Service a04d08
        "name": "ci-grand-gannet",
Packit Service a04d08
        "uuid": "2f266908-8e6c-4818-9b5c-42e9cc66a785",
Packit Service a04d08
        "random_seed": "bm90LXJhbmRvbQo=",
Packit Service a04d08
        "crypt_key": "ssh-rsa AAAAB3NzaC1yc2..n6z/",
Packit Service a04d08
        "configuration_token": "eyJhbGciOi..M3ZA",
Packit Service a04d08
        "public_keys": {"1091307": "ssh-rsa AAAAB3N..Hw== ci-pubkey"},
Packit Service a04d08
    }
Packit Service a04d08
Packit Service a04d08
    content_interfaces = dedent("""\
Packit Service a04d08
        auto lo
Packit Service a04d08
        iface lo inet loopback
Packit Service a04d08
Packit Service a04d08
        auto eth0
Packit Service a04d08
        allow-hotplug eth0
Packit Service a04d08
        iface eth0 inet static
Packit Service a04d08
        address 10.82.43.5
Packit Service a04d08
        netmask 255.255.255.192
Packit Service a04d08
        """)
Packit Service a04d08
Packit Service a04d08
    userdata = b"#!/bin/sh\necho hi mom\n"
Packit Service a04d08
    # meta.js file gets json encoded userdata as a list.
Packit Service a04d08
    meta_js = '["#!/bin/sh\necho hi mom\n"]'
Packit Service a04d08
    vendor_data = {
Packit Service a04d08
        "cloud-init": "#!/bin/bash\necho 'root:$6$5ab01p1m1' | chpasswd -e"}
Packit Service a04d08
Packit Service a04d08
    network_data = {
Packit Service a04d08
        "links": [
Packit Service a04d08
            {"id": "interface_29402281", "name": "eth0", "mtu": None,
Packit Service a04d08
             "type": "phy", "ethernet_mac_address": "06:00:f1:bd:da:25"},
Packit Service a04d08
            {"id": "interface_29402279", "name": "eth1", "mtu": None,
Packit Service a04d08
             "type": "phy", "ethernet_mac_address": "06:98:5e:d0:7f:86"}
Packit Service a04d08
        ],
Packit Service a04d08
        "networks": [
Packit Service a04d08
            {"id": "network_109887563", "link": "interface_29402281",
Packit Service a04d08
             "type": "ipv4", "ip_address": "10.82.43.2",
Packit Service a04d08
             "netmask": "255.255.255.192",
Packit Service a04d08
             "routes": [
Packit Service a04d08
                 {"network": "10.0.0.0", "netmask": "255.0.0.0",
Packit Service a04d08
                  "gateway": "10.82.43.1"},
Packit Service a04d08
                 {"network": "161.26.0.0", "netmask": "255.255.0.0",
Packit Service a04d08
                  "gateway": "10.82.43.1"}]},
Packit Service a04d08
            {"id": "network_109887551", "link": "interface_29402279",
Packit Service a04d08
             "type": "ipv4", "ip_address": "108.168.194.252",
Packit Service a04d08
             "netmask": "255.255.255.248",
Packit Service a04d08
             "routes": [
Packit Service a04d08
                 {"network": "0.0.0.0", "netmask": "0.0.0.0",
Packit Service a04d08
                  "gateway": "108.168.194.249"}]}
Packit Service a04d08
        ],
Packit Service a04d08
        "services": [
Packit Service a04d08
            {"type": "dns", "address": "10.0.80.11"},
Packit Service a04d08
            {"type": "dns", "address": "10.0.80.12"}
Packit Service a04d08
        ],
Packit Service a04d08
    }
Packit Service a04d08
Packit Service a04d08
    sysuuid = '7f79ebf5-d791-43c3-a723-854e8389d59f'
Packit Service a04d08
Packit Service a04d08
    def _get_expected_metadata(self, os_md):
Packit Service a04d08
        """return expected 'metadata' for data loaded from meta_data.json."""
Packit Service a04d08
        os_md = copy.deepcopy(os_md)
Packit Service a04d08
        renames = (
Packit Service a04d08
            ('hostname', 'local-hostname'),
Packit Service a04d08
            ('uuid', 'instance-id'),
Packit Service a04d08
            ('public_keys', 'public-keys'))
Packit Service a04d08
        ret = {}
Packit Service a04d08
        for osname, mdname in renames:
Packit Service a04d08
            if osname in os_md:
Packit Service a04d08
                ret[mdname] = os_md[osname]
Packit Service a04d08
        if 'random_seed' in os_md:
Packit Service a04d08
            ret['random_seed'] = base64.b64decode(os_md['random_seed'])
Packit Service a04d08
Packit Service a04d08
        return ret
Packit Service a04d08
Packit Service a04d08
    def test_provisioning_md(self, m_platform, m_sysuuid):
Packit Service a04d08
        """Provisioning env with a metadata disk should return None."""
Packit Service a04d08
        m_platform.return_value = (
Packit Service a04d08
            ibm.Platforms.TEMPLATE_PROVISIONING_METADATA, "/dev/xvdh")
Packit Service a04d08
        self.assertIsNone(ibm.read_md())
Packit Service a04d08
Packit Service a04d08
    def test_provisioning_no_metadata(self, m_platform, m_sysuuid):
Packit Service a04d08
        """Provisioning env with no metadata disk should return None."""
Packit Service a04d08
        m_platform.return_value = (
Packit Service a04d08
            ibm.Platforms.TEMPLATE_PROVISIONING_NODATA, None)
Packit Service a04d08
        self.assertIsNone(ibm.read_md())
Packit Service a04d08
Packit Service a04d08
    def test_provisioning_not_ibm(self, m_platform, m_sysuuid):
Packit Service a04d08
        """Provisioning env but not identified as IBM should return None."""
Packit Service a04d08
        m_platform.return_value = (None, None)
Packit Service a04d08
        self.assertIsNone(ibm.read_md())
Packit Service a04d08
Packit Service a04d08
    def test_template_live(self, m_platform, m_sysuuid):
Packit Service a04d08
        """Template live environment should be identified."""
Packit Service a04d08
        tmpdir = self.tmp_dir()
Packit Service a04d08
        m_platform.return_value = (
Packit Service a04d08
            ibm.Platforms.TEMPLATE_LIVE_METADATA, tmpdir)
Packit Service a04d08
        m_sysuuid.return_value = self.sysuuid
Packit Service a04d08
Packit Service a04d08
        test_helpers.populate_dir(tmpdir, {
Packit Service a04d08
            'openstack/latest/meta_data.json': json.dumps(self.template_md),
Packit Service a04d08
            'openstack/latest/user_data': self.userdata,
Packit Service a04d08
            'openstack/content/interfaces': self.content_interfaces,
Packit Service a04d08
            'meta.js': self.meta_js})
Packit Service a04d08
Packit Service a04d08
        ret = ibm.read_md()
Packit Service a04d08
        self.assertEqual(ibm.Platforms.TEMPLATE_LIVE_METADATA,
Packit Service a04d08
                         ret['platform'])
Packit Service a04d08
        self.assertEqual(tmpdir, ret['source'])
Packit Service a04d08
        self.assertEqual(self.userdata, ret['userdata'])
Packit Service a04d08
        self.assertEqual(self._get_expected_metadata(self.template_md),
Packit Service a04d08
                         ret['metadata'])
Packit Service a04d08
        self.assertEqual(self.sysuuid, ret['system-uuid'])
Packit Service a04d08
Packit Service a04d08
    def test_os_code_live(self, m_platform, m_sysuuid):
Packit Service a04d08
        """Verify an os_code metadata path."""
Packit Service a04d08
        tmpdir = self.tmp_dir()
Packit Service a04d08
        m_platform.return_value = (ibm.Platforms.OS_CODE, tmpdir)
Packit Service a04d08
        netdata = json.dumps(self.network_data)
Packit Service a04d08
        test_helpers.populate_dir(tmpdir, {
Packit Service a04d08
            'openstack/latest/meta_data.json': json.dumps(self.oscode_md),
Packit Service a04d08
            'openstack/latest/user_data': self.userdata,
Packit Service a04d08
            'openstack/latest/vendor_data.json': json.dumps(self.vendor_data),
Packit Service a04d08
            'openstack/latest/network_data.json': netdata,
Packit Service a04d08
        })
Packit Service a04d08
Packit Service a04d08
        ret = ibm.read_md()
Packit Service a04d08
        self.assertEqual(ibm.Platforms.OS_CODE, ret['platform'])
Packit Service a04d08
        self.assertEqual(tmpdir, ret['source'])
Packit Service a04d08
        self.assertEqual(self.userdata, ret['userdata'])
Packit Service a04d08
        self.assertEqual(self._get_expected_metadata(self.oscode_md),
Packit Service a04d08
                         ret['metadata'])
Packit Service a04d08
Packit Service a04d08
    def test_os_code_live_no_userdata(self, m_platform, m_sysuuid):
Packit Service a04d08
        """Verify os_code without user-data."""
Packit Service a04d08
        tmpdir = self.tmp_dir()
Packit Service a04d08
        m_platform.return_value = (ibm.Platforms.OS_CODE, tmpdir)
Packit Service a04d08
        test_helpers.populate_dir(tmpdir, {
Packit Service a04d08
            'openstack/latest/meta_data.json': json.dumps(self.oscode_md),
Packit Service a04d08
            'openstack/latest/vendor_data.json': json.dumps(self.vendor_data),
Packit Service a04d08
        })
Packit Service a04d08
Packit Service a04d08
        ret = ibm.read_md()
Packit Service a04d08
        self.assertEqual(ibm.Platforms.OS_CODE, ret['platform'])
Packit Service a04d08
        self.assertEqual(tmpdir, ret['source'])
Packit Service a04d08
        self.assertIsNone(ret['userdata'])
Packit Service a04d08
        self.assertEqual(self._get_expected_metadata(self.oscode_md),
Packit Service a04d08
                         ret['metadata'])
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
class TestIsIBMProvisioning(test_helpers.FilesystemMockingTestCase):
Packit Service a04d08
    """Test the _is_ibm_provisioning method."""
Packit Service a04d08
    inst_log = "/root/swinstall.log"
Packit Service a04d08
    prov_cfg = "/root/provisioningConfiguration.cfg"
Packit Service a04d08
    boot_ref = "/proc/1/environ"
Packit Service a04d08
    with_logs = True
Packit Service a04d08
Packit Service a04d08
    def _call_with_root(self, rootd):
Packit Service a04d08
        self.reRoot(rootd)
Packit Service a04d08
        return ibm._is_ibm_provisioning()
Packit Service a04d08
Packit Service a04d08
    def test_no_config(self):
Packit Service a04d08
        """No provisioning config means not provisioning."""
Packit Service a04d08
        self.assertFalse(self._call_with_root(self.tmp_dir()))
Packit Service a04d08
Packit Service a04d08
    def test_config_only(self):
Packit Service a04d08
        """A provisioning config without a log means provisioning."""
Packit Service a04d08
        rootd = self.tmp_dir()
Packit Service a04d08
        test_helpers.populate_dir(rootd, {self.prov_cfg: "key=value"})
Packit Service a04d08
        self.assertTrue(self._call_with_root(rootd))
Packit Service a04d08
Packit Service a04d08
    def test_config_with_old_log(self):
Packit Service a04d08
        """A config with a log from previous boot is not provisioning."""
Packit Service a04d08
        rootd = self.tmp_dir()
Packit Service a04d08
        data = {self.prov_cfg: ("key=value\nkey2=val2\n", -10),
Packit Service a04d08
                self.inst_log: ("log data\n", -30),
Packit Service a04d08
                self.boot_ref: ("PWD=/", 0)}
Packit Service a04d08
        test_helpers.populate_dir_with_ts(rootd, data)
Packit Service a04d08
        self.assertFalse(self._call_with_root(rootd=rootd))
Packit Service a04d08
        self.assertIn("from previous boot", self.logs.getvalue())
Packit Service a04d08
Packit Service a04d08
    def test_config_with_new_log(self):
Packit Service a04d08
        """A config with a log from this boot is provisioning."""
Packit Service a04d08
        rootd = self.tmp_dir()
Packit Service a04d08
        data = {self.prov_cfg: ("key=value\nkey2=val2\n", -10),
Packit Service a04d08
                self.inst_log: ("log data\n", 30),
Packit Service a04d08
                self.boot_ref: ("PWD=/", 0)}
Packit Service a04d08
        test_helpers.populate_dir_with_ts(rootd, data)
Packit Service a04d08
        self.assertTrue(self._call_with_root(rootd=rootd))
Packit Service a04d08
        self.assertIn("from current boot", self.logs.getvalue())
Packit Service a04d08
Packit Service a04d08
    def test_config_and_log_no_reference(self):
Packit Service a04d08
        """If the config and log existed, but no reference, assume not."""
Packit Service a04d08
        rootd = self.tmp_dir()
Packit Service a04d08
        test_helpers.populate_dir(
Packit Service a04d08
            rootd, {self.prov_cfg: "key=value", self.inst_log: "log data\n"})
Packit Service a04d08
        self.assertFalse(self._call_with_root(rootd=rootd))
Packit Service a04d08
        self.assertIn("no reference file", self.logs.getvalue())
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
class TestDataSourceIBMCloud(test_helpers.CiTestCase):
Packit Service a04d08
Packit Service a04d08
    def setUp(self):
Packit Service a04d08
        super(TestDataSourceIBMCloud, self).setUp()
Packit Service a04d08
        self.tmp = self.tmp_dir()
Packit Service a04d08
        self.cloud_dir = self.tmp_path('cloud', dir=self.tmp)
Packit Service a04d08
        util.ensure_dir(self.cloud_dir)
Packit Service a04d08
        paths = Paths({'run_dir': self.tmp, 'cloud_dir': self.cloud_dir})
Packit Service a04d08
        self.ds = ibm.DataSourceIBMCloud(
Packit Service a04d08
            sys_cfg={}, distro=None, paths=paths)
Packit Service a04d08
Packit Service a04d08
    def test_get_data_false(self):
Packit Service a04d08
        """When read_md returns None, get_data returns False."""
Packit Service a04d08
        with mock.patch(D_PATH + 'read_md', return_value=None):
Packit Service a04d08
            self.assertFalse(self.ds.get_data())
Packit Service a04d08
Packit Service a04d08
    def test_get_data_processes_read_md(self):
Packit Service a04d08
        """get_data processes and caches content returned by read_md."""
Packit Service a04d08
        md = {
Packit Service a04d08
            'metadata': {}, 'networkdata': 'net', 'platform': 'plat',
Packit Service a04d08
            'source': 'src', 'system-uuid': 'uuid', 'userdata': 'ud',
Packit Service a04d08
            'vendordata': 'vd'}
Packit Service a04d08
        with mock.patch(D_PATH + 'read_md', return_value=md):
Packit Service a04d08
            self.assertTrue(self.ds.get_data())
Packit Service a04d08
        self.assertEqual('src', self.ds.source)
Packit Service a04d08
        self.assertEqual('plat', self.ds.platform)
Packit Service a04d08
        self.assertEqual({}, self.ds.metadata)
Packit Service a04d08
        self.assertEqual('ud', self.ds.userdata_raw)
Packit Service a04d08
        self.assertEqual('net', self.ds.network_json)
Packit Service a04d08
        self.assertEqual('vd', self.ds.vendordata_pure)
Packit Service a04d08
        self.assertEqual('uuid', self.ds.system_uuid)
Packit Service a04d08
        self.assertEqual('ibmcloud', self.ds.cloud_name)
Packit Service a04d08
        self.assertEqual('ibmcloud', self.ds.platform_type)
Packit Service a04d08
        self.assertEqual('plat (src)', self.ds.subplatform)
Packit Service a04d08
Packit Service a04d08
# vi: ts=4 expandtab