|
Packit Service |
a04d08 |
# This file is part of cloud-init. See LICENSE file for license information.
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
import copy
|
|
Packit Service |
a04d08 |
import inspect
|
|
Packit Service |
a04d08 |
import os
|
|
Packit Service |
a04d08 |
import stat
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
from cloudinit.event import EventType
|
|
Packit Service |
a04d08 |
from cloudinit.helpers import Paths
|
|
Packit Service |
a04d08 |
from cloudinit import importer
|
|
Packit Service |
a04d08 |
from cloudinit.sources import (
|
|
Packit Service |
a04d08 |
EXPERIMENTAL_TEXT, INSTANCE_JSON_FILE, INSTANCE_JSON_SENSITIVE_FILE,
|
|
Packit Service |
a04d08 |
METADATA_UNKNOWN, REDACT_SENSITIVE_VALUE, UNSET, DataSource,
|
|
Packit Service |
a04d08 |
canonical_cloud_id, redact_sensitive_keys)
|
|
Packit Service |
751c4a |
from cloudinit.tests.helpers import CiTestCase, mock
|
|
Packit Service |
a04d08 |
from cloudinit.user_data import UserDataProcessor
|
|
Packit Service |
a04d08 |
from cloudinit import util
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
class DataSourceTestSubclassNet(DataSource):
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
dsname = 'MyTestSubclass'
|
|
Packit Service |
a04d08 |
url_max_wait = 55
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def __init__(self, sys_cfg, distro, paths, custom_metadata=None,
|
|
Packit Service |
a04d08 |
custom_userdata=None, get_data_retval=True):
|
|
Packit Service |
a04d08 |
super(DataSourceTestSubclassNet, self).__init__(
|
|
Packit Service |
a04d08 |
sys_cfg, distro, paths)
|
|
Packit Service |
a04d08 |
self._custom_userdata = custom_userdata
|
|
Packit Service |
a04d08 |
self._custom_metadata = custom_metadata
|
|
Packit Service |
a04d08 |
self._get_data_retval = get_data_retval
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def _get_cloud_name(self):
|
|
Packit Service |
a04d08 |
return 'SubclassCloudName'
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def _get_data(self):
|
|
Packit Service |
a04d08 |
if self._custom_metadata:
|
|
Packit Service |
a04d08 |
self.metadata = self._custom_metadata
|
|
Packit Service |
a04d08 |
else:
|
|
Packit Service |
a04d08 |
self.metadata = {'availability_zone': 'myaz',
|
|
Packit Service |
a04d08 |
'local-hostname': 'test-subclass-hostname',
|
|
Packit Service |
a04d08 |
'region': 'myregion'}
|
|
Packit Service |
a04d08 |
if self._custom_userdata:
|
|
Packit Service |
a04d08 |
self.userdata_raw = self._custom_userdata
|
|
Packit Service |
a04d08 |
else:
|
|
Packit Service |
a04d08 |
self.userdata_raw = 'userdata_raw'
|
|
Packit Service |
a04d08 |
self.vendordata_raw = 'vendordata_raw'
|
|
Packit Service |
a04d08 |
return self._get_data_retval
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
class InvalidDataSourceTestSubclassNet(DataSource):
|
|
Packit Service |
a04d08 |
pass
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
class TestDataSource(CiTestCase):
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
with_logs = True
|
|
Packit Service |
751c4a |
maxDiff = None
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def setUp(self):
|
|
Packit Service |
a04d08 |
super(TestDataSource, self).setUp()
|
|
Packit Service |
a04d08 |
self.sys_cfg = {'datasource': {'_undef': {'key1': False}}}
|
|
Packit Service |
a04d08 |
self.distro = 'distrotest' # generally should be a Distro object
|
|
Packit Service |
a04d08 |
self.paths = Paths({})
|
|
Packit Service |
a04d08 |
self.datasource = DataSource(self.sys_cfg, self.distro, self.paths)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_datasource_init(self):
|
|
Packit Service |
a04d08 |
"""DataSource initializes metadata attributes, ds_cfg and ud_proc."""
|
|
Packit Service |
a04d08 |
self.assertEqual(self.paths, self.datasource.paths)
|
|
Packit Service |
a04d08 |
self.assertEqual(self.sys_cfg, self.datasource.sys_cfg)
|
|
Packit Service |
a04d08 |
self.assertEqual(self.distro, self.datasource.distro)
|
|
Packit Service |
a04d08 |
self.assertIsNone(self.datasource.userdata)
|
|
Packit Service |
a04d08 |
self.assertEqual({}, self.datasource.metadata)
|
|
Packit Service |
a04d08 |
self.assertIsNone(self.datasource.userdata_raw)
|
|
Packit Service |
a04d08 |
self.assertIsNone(self.datasource.vendordata)
|
|
Packit Service |
a04d08 |
self.assertIsNone(self.datasource.vendordata_raw)
|
|
Packit Service |
a04d08 |
self.assertEqual({'key1': False}, self.datasource.ds_cfg)
|
|
Packit Service |
a04d08 |
self.assertIsInstance(self.datasource.ud_proc, UserDataProcessor)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_datasource_init_gets_ds_cfg_using_dsname(self):
|
|
Packit Service |
a04d08 |
"""Init uses DataSource.dsname for sourcing ds_cfg."""
|
|
Packit Service |
a04d08 |
sys_cfg = {'datasource': {'MyTestSubclass': {'key2': False}}}
|
|
Packit Service |
a04d08 |
distro = 'distrotest' # generally should be a Distro object
|
|
Packit Service |
a04d08 |
datasource = DataSourceTestSubclassNet(sys_cfg, distro, self.paths)
|
|
Packit Service |
a04d08 |
self.assertEqual({'key2': False}, datasource.ds_cfg)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_str_is_classname(self):
|
|
Packit Service |
a04d08 |
"""The string representation of the datasource is the classname."""
|
|
Packit Service |
a04d08 |
self.assertEqual('DataSource', str(self.datasource))
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
'DataSourceTestSubclassNet',
|
|
Packit Service |
a04d08 |
str(DataSourceTestSubclassNet('', '', self.paths)))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_datasource_get_url_params_defaults(self):
|
|
Packit Service |
a04d08 |
"""get_url_params default url config settings for the datasource."""
|
|
Packit Service |
a04d08 |
params = self.datasource.get_url_params()
|
|
Packit Service |
a04d08 |
self.assertEqual(params.max_wait_seconds, self.datasource.url_max_wait)
|
|
Packit Service |
a04d08 |
self.assertEqual(params.timeout_seconds, self.datasource.url_timeout)
|
|
Packit Service |
a04d08 |
self.assertEqual(params.num_retries, self.datasource.url_retries)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_datasource_get_url_params_subclassed(self):
|
|
Packit Service |
a04d08 |
"""Subclasses can override get_url_params defaults."""
|
|
Packit Service |
a04d08 |
sys_cfg = {'datasource': {'MyTestSubclass': {'key2': False}}}
|
|
Packit Service |
a04d08 |
distro = 'distrotest' # generally should be a Distro object
|
|
Packit Service |
a04d08 |
datasource = DataSourceTestSubclassNet(sys_cfg, distro, self.paths)
|
|
Packit Service |
a04d08 |
expected = (datasource.url_max_wait, datasource.url_timeout,
|
|
Packit Service |
a04d08 |
datasource.url_retries)
|
|
Packit Service |
a04d08 |
url_params = datasource.get_url_params()
|
|
Packit Service |
a04d08 |
self.assertNotEqual(self.datasource.get_url_params(), url_params)
|
|
Packit Service |
a04d08 |
self.assertEqual(expected, url_params)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_datasource_get_url_params_ds_config_override(self):
|
|
Packit Service |
a04d08 |
"""Datasource configuration options can override url param defaults."""
|
|
Packit Service |
a04d08 |
sys_cfg = {
|
|
Packit Service |
a04d08 |
'datasource': {
|
|
Packit Service |
a04d08 |
'MyTestSubclass': {
|
|
Packit Service |
a04d08 |
'max_wait': '1', 'timeout': '2', 'retries': '3'}}}
|
|
Packit Service |
a04d08 |
datasource = DataSourceTestSubclassNet(
|
|
Packit Service |
a04d08 |
sys_cfg, self.distro, self.paths)
|
|
Packit Service |
a04d08 |
expected = (1, 2, 3)
|
|
Packit Service |
a04d08 |
url_params = datasource.get_url_params()
|
|
Packit Service |
a04d08 |
self.assertNotEqual(
|
|
Packit Service |
a04d08 |
(datasource.url_max_wait, datasource.url_timeout,
|
|
Packit Service |
a04d08 |
datasource.url_retries),
|
|
Packit Service |
a04d08 |
url_params)
|
|
Packit Service |
a04d08 |
self.assertEqual(expected, url_params)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_datasource_get_url_params_is_zero_or_greater(self):
|
|
Packit Service |
a04d08 |
"""get_url_params ignores timeouts with a value below 0."""
|
|
Packit Service |
a04d08 |
# Set an override that is below 0 which gets ignored.
|
|
Packit Service |
a04d08 |
sys_cfg = {'datasource': {'_undef': {'timeout': '-1'}}}
|
|
Packit Service |
a04d08 |
datasource = DataSource(sys_cfg, self.distro, self.paths)
|
|
Packit Service |
a04d08 |
(_max_wait, timeout, _retries) = datasource.get_url_params()
|
|
Packit Service |
a04d08 |
self.assertEqual(0, timeout)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_datasource_get_url_uses_defaults_on_errors(self):
|
|
Packit Service |
a04d08 |
"""On invalid system config values for url_params defaults are used."""
|
|
Packit Service |
a04d08 |
# All invalid values should be logged
|
|
Packit Service |
a04d08 |
sys_cfg = {'datasource': {
|
|
Packit Service |
a04d08 |
'_undef': {
|
|
Packit Service |
a04d08 |
'max_wait': 'nope', 'timeout': 'bug', 'retries': 'nonint'}}}
|
|
Packit Service |
a04d08 |
datasource = DataSource(sys_cfg, self.distro, self.paths)
|
|
Packit Service |
a04d08 |
url_params = datasource.get_url_params()
|
|
Packit Service |
a04d08 |
expected = (datasource.url_max_wait, datasource.url_timeout,
|
|
Packit Service |
a04d08 |
datasource.url_retries)
|
|
Packit Service |
a04d08 |
self.assertEqual(expected, url_params)
|
|
Packit Service |
a04d08 |
logs = self.logs.getvalue()
|
|
Packit Service |
a04d08 |
expected_logs = [
|
|
Packit Service |
a04d08 |
"Config max_wait 'nope' is not an int, using default '-1'",
|
|
Packit Service |
a04d08 |
"Config timeout 'bug' is not an int, using default '10'",
|
|
Packit Service |
a04d08 |
"Config retries 'nonint' is not an int, using default '5'",
|
|
Packit Service |
a04d08 |
]
|
|
Packit Service |
a04d08 |
for log in expected_logs:
|
|
Packit Service |
a04d08 |
self.assertIn(log, logs)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
@mock.patch('cloudinit.sources.net.find_fallback_nic')
|
|
Packit Service |
a04d08 |
def test_fallback_interface_is_discovered(self, m_get_fallback_nic):
|
|
Packit Service |
a04d08 |
"""The fallback_interface is discovered via find_fallback_nic."""
|
|
Packit Service |
a04d08 |
m_get_fallback_nic.return_value = 'nic9'
|
|
Packit Service |
a04d08 |
self.assertEqual('nic9', self.datasource.fallback_interface)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
@mock.patch('cloudinit.sources.net.find_fallback_nic')
|
|
Packit Service |
a04d08 |
def test_fallback_interface_logs_undiscovered(self, m_get_fallback_nic):
|
|
Packit Service |
a04d08 |
"""Log a warning when fallback_interface can not discover the nic."""
|
|
Packit Service |
a04d08 |
self.datasource._cloud_name = 'MySupahCloud'
|
|
Packit Service |
a04d08 |
m_get_fallback_nic.return_value = None # Couldn't discover nic
|
|
Packit Service |
a04d08 |
self.assertIsNone(self.datasource.fallback_interface)
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
'WARNING: Did not find a fallback interface on MySupahCloud.\n',
|
|
Packit Service |
a04d08 |
self.logs.getvalue())
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
@mock.patch('cloudinit.sources.net.find_fallback_nic')
|
|
Packit Service |
a04d08 |
def test_wb_fallback_interface_is_cached(self, m_get_fallback_nic):
|
|
Packit Service |
a04d08 |
"""The fallback_interface is cached and won't be rediscovered."""
|
|
Packit Service |
a04d08 |
self.datasource._fallback_interface = 'nic10'
|
|
Packit Service |
a04d08 |
self.assertEqual('nic10', self.datasource.fallback_interface)
|
|
Packit Service |
a04d08 |
m_get_fallback_nic.assert_not_called()
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test__get_data_unimplemented(self):
|
|
Packit Service |
a04d08 |
"""Raise an error when _get_data is not implemented."""
|
|
Packit Service |
a04d08 |
with self.assertRaises(NotImplementedError) as context_manager:
|
|
Packit Service |
a04d08 |
self.datasource.get_data()
|
|
Packit Service |
a04d08 |
self.assertIn(
|
|
Packit Service |
a04d08 |
'Subclasses of DataSource must implement _get_data',
|
|
Packit Service |
a04d08 |
str(context_manager.exception))
|
|
Packit Service |
a04d08 |
datasource2 = InvalidDataSourceTestSubclassNet(
|
|
Packit Service |
a04d08 |
self.sys_cfg, self.distro, self.paths)
|
|
Packit Service |
a04d08 |
with self.assertRaises(NotImplementedError) as context_manager:
|
|
Packit Service |
a04d08 |
datasource2.get_data()
|
|
Packit Service |
a04d08 |
self.assertIn(
|
|
Packit Service |
a04d08 |
'Subclasses of DataSource must implement _get_data',
|
|
Packit Service |
a04d08 |
str(context_manager.exception))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_get_data_calls_subclass__get_data(self):
|
|
Packit Service |
a04d08 |
"""Datasource.get_data uses the subclass' version of _get_data."""
|
|
Packit Service |
a04d08 |
tmp = self.tmp_dir()
|
|
Packit Service |
a04d08 |
datasource = DataSourceTestSubclassNet(
|
|
Packit Service |
a04d08 |
self.sys_cfg, self.distro, Paths({'run_dir': tmp}))
|
|
Packit Service |
a04d08 |
self.assertTrue(datasource.get_data())
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
{'availability_zone': 'myaz',
|
|
Packit Service |
a04d08 |
'local-hostname': 'test-subclass-hostname',
|
|
Packit Service |
a04d08 |
'region': 'myregion'},
|
|
Packit Service |
a04d08 |
datasource.metadata)
|
|
Packit Service |
a04d08 |
self.assertEqual('userdata_raw', datasource.userdata_raw)
|
|
Packit Service |
a04d08 |
self.assertEqual('vendordata_raw', datasource.vendordata_raw)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_get_hostname_strips_local_hostname_without_domain(self):
|
|
Packit Service |
a04d08 |
"""Datasource.get_hostname strips metadata local-hostname of domain."""
|
|
Packit Service |
a04d08 |
tmp = self.tmp_dir()
|
|
Packit Service |
a04d08 |
datasource = DataSourceTestSubclassNet(
|
|
Packit Service |
a04d08 |
self.sys_cfg, self.distro, Paths({'run_dir': tmp}))
|
|
Packit Service |
a04d08 |
self.assertTrue(datasource.get_data())
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
'test-subclass-hostname', datasource.metadata['local-hostname'])
|
|
Packit Service |
a04d08 |
self.assertEqual('test-subclass-hostname', datasource.get_hostname())
|
|
Packit Service |
a04d08 |
datasource.metadata['local-hostname'] = 'hostname.my.domain.com'
|
|
Packit Service |
a04d08 |
self.assertEqual('hostname', datasource.get_hostname())
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_get_hostname_with_fqdn_returns_local_hostname_with_domain(self):
|
|
Packit Service |
a04d08 |
"""Datasource.get_hostname with fqdn set gets qualified hostname."""
|
|
Packit Service |
a04d08 |
tmp = self.tmp_dir()
|
|
Packit Service |
a04d08 |
datasource = DataSourceTestSubclassNet(
|
|
Packit Service |
a04d08 |
self.sys_cfg, self.distro, Paths({'run_dir': tmp}))
|
|
Packit Service |
a04d08 |
self.assertTrue(datasource.get_data())
|
|
Packit Service |
a04d08 |
datasource.metadata['local-hostname'] = 'hostname.my.domain.com'
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
'hostname.my.domain.com', datasource.get_hostname(fqdn=True))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_get_hostname_without_metadata_uses_system_hostname(self):
|
|
Packit Service |
a04d08 |
"""Datasource.gethostname runs util.get_hostname when no metadata."""
|
|
Packit Service |
a04d08 |
tmp = self.tmp_dir()
|
|
Packit Service |
a04d08 |
datasource = DataSourceTestSubclassNet(
|
|
Packit Service |
a04d08 |
self.sys_cfg, self.distro, Paths({'run_dir': tmp}))
|
|
Packit Service |
a04d08 |
self.assertEqual({}, datasource.metadata)
|
|
Packit Service |
a04d08 |
mock_fqdn = 'cloudinit.sources.util.get_fqdn_from_hosts'
|
|
Packit Service |
a04d08 |
with mock.patch('cloudinit.sources.util.get_hostname') as m_gethost:
|
|
Packit Service |
a04d08 |
with mock.patch(mock_fqdn) as m_fqdn:
|
|
Packit Service |
a04d08 |
m_gethost.return_value = 'systemhostname.domain.com'
|
|
Packit Service |
a04d08 |
m_fqdn.return_value = None # No maching fqdn in /etc/hosts
|
|
Packit Service |
a04d08 |
self.assertEqual('systemhostname', datasource.get_hostname())
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
'systemhostname.domain.com',
|
|
Packit Service |
a04d08 |
datasource.get_hostname(fqdn=True))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_get_hostname_without_metadata_returns_none(self):
|
|
Packit Service |
a04d08 |
"""Datasource.gethostname returns None when metadata_only and no MD."""
|
|
Packit Service |
a04d08 |
tmp = self.tmp_dir()
|
|
Packit Service |
a04d08 |
datasource = DataSourceTestSubclassNet(
|
|
Packit Service |
a04d08 |
self.sys_cfg, self.distro, Paths({'run_dir': tmp}))
|
|
Packit Service |
a04d08 |
self.assertEqual({}, datasource.metadata)
|
|
Packit Service |
a04d08 |
mock_fqdn = 'cloudinit.sources.util.get_fqdn_from_hosts'
|
|
Packit Service |
a04d08 |
with mock.patch('cloudinit.sources.util.get_hostname') as m_gethost:
|
|
Packit Service |
a04d08 |
with mock.patch(mock_fqdn) as m_fqdn:
|
|
Packit Service |
a04d08 |
self.assertIsNone(datasource.get_hostname(metadata_only=True))
|
|
Packit Service |
a04d08 |
self.assertIsNone(
|
|
Packit Service |
a04d08 |
datasource.get_hostname(fqdn=True, metadata_only=True))
|
|
Packit Service |
a04d08 |
self.assertEqual([], m_gethost.call_args_list)
|
|
Packit Service |
a04d08 |
self.assertEqual([], m_fqdn.call_args_list)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_get_hostname_without_metadata_prefers_etc_hosts(self):
|
|
Packit Service |
a04d08 |
"""Datasource.gethostname prefers /etc/hosts to util.get_hostname."""
|
|
Packit Service |
a04d08 |
tmp = self.tmp_dir()
|
|
Packit Service |
a04d08 |
datasource = DataSourceTestSubclassNet(
|
|
Packit Service |
a04d08 |
self.sys_cfg, self.distro, Paths({'run_dir': tmp}))
|
|
Packit Service |
a04d08 |
self.assertEqual({}, datasource.metadata)
|
|
Packit Service |
a04d08 |
mock_fqdn = 'cloudinit.sources.util.get_fqdn_from_hosts'
|
|
Packit Service |
a04d08 |
with mock.patch('cloudinit.sources.util.get_hostname') as m_gethost:
|
|
Packit Service |
a04d08 |
with mock.patch(mock_fqdn) as m_fqdn:
|
|
Packit Service |
a04d08 |
m_gethost.return_value = 'systemhostname.domain.com'
|
|
Packit Service |
a04d08 |
m_fqdn.return_value = 'fqdnhostname.domain.com'
|
|
Packit Service |
a04d08 |
self.assertEqual('fqdnhostname', datasource.get_hostname())
|
|
Packit Service |
a04d08 |
self.assertEqual('fqdnhostname.domain.com',
|
|
Packit Service |
a04d08 |
datasource.get_hostname(fqdn=True))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_get_data_does_not_write_instance_data_on_failure(self):
|
|
Packit Service |
a04d08 |
"""get_data does not write INSTANCE_JSON_FILE on get_data False."""
|
|
Packit Service |
a04d08 |
tmp = self.tmp_dir()
|
|
Packit Service |
a04d08 |
datasource = DataSourceTestSubclassNet(
|
|
Packit Service |
a04d08 |
self.sys_cfg, self.distro, Paths({'run_dir': tmp}),
|
|
Packit Service |
a04d08 |
get_data_retval=False)
|
|
Packit Service |
a04d08 |
self.assertFalse(datasource.get_data())
|
|
Packit Service |
a04d08 |
json_file = self.tmp_path(INSTANCE_JSON_FILE, tmp)
|
|
Packit Service |
a04d08 |
self.assertFalse(
|
|
Packit Service |
a04d08 |
os.path.exists(json_file), 'Found unexpected file %s' % json_file)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_get_data_writes_json_instance_data_on_success(self):
|
|
Packit Service |
a04d08 |
"""get_data writes INSTANCE_JSON_FILE to run_dir as world readable."""
|
|
Packit Service |
a04d08 |
tmp = self.tmp_dir()
|
|
Packit Service |
a04d08 |
datasource = DataSourceTestSubclassNet(
|
|
Packit Service |
a04d08 |
self.sys_cfg, self.distro, Paths({'run_dir': tmp}))
|
|
Packit Service |
751c4a |
sys_info = {
|
|
Packit Service |
751c4a |
"python": "3.7",
|
|
Packit Service |
751c4a |
"platform":
|
|
Packit Service |
751c4a |
"Linux-5.4.0-24-generic-x86_64-with-Ubuntu-20.04-focal",
|
|
Packit Service |
751c4a |
"uname": ["Linux", "myhost", "5.4.0-24-generic", "SMP blah",
|
|
Packit Service |
751c4a |
"x86_64"],
|
|
Packit Service |
751c4a |
"variant": "ubuntu", "dist": ["ubuntu", "20.04", "focal"]}
|
|
Packit Service |
751c4a |
with mock.patch("cloudinit.util.system_info", return_value=sys_info):
|
|
Packit Service |
751c4a |
datasource.get_data()
|
|
Packit Service |
a04d08 |
json_file = self.tmp_path(INSTANCE_JSON_FILE, tmp)
|
|
Packit Service |
a04d08 |
content = util.load_file(json_file)
|
|
Packit Service |
a04d08 |
expected = {
|
|
Packit Service |
a04d08 |
'base64_encoded_keys': [],
|
|
Packit Service |
751c4a |
'merged_cfg': REDACT_SENSITIVE_VALUE,
|
|
Packit Service |
751c4a |
'sensitive_keys': ['merged_cfg'],
|
|
Packit Service |
751c4a |
'sys_info': sys_info,
|
|
Packit Service |
a04d08 |
'v1': {
|
|
Packit Service |
a04d08 |
'_beta_keys': ['subplatform'],
|
|
Packit Service |
a04d08 |
'availability-zone': 'myaz',
|
|
Packit Service |
a04d08 |
'availability_zone': 'myaz',
|
|
Packit Service |
a04d08 |
'cloud-name': 'subclasscloudname',
|
|
Packit Service |
a04d08 |
'cloud_name': 'subclasscloudname',
|
|
Packit Service |
751c4a |
'distro': 'ubuntu',
|
|
Packit Service |
751c4a |
'distro_release': 'focal',
|
|
Packit Service |
751c4a |
'distro_version': '20.04',
|
|
Packit Service |
a04d08 |
'instance-id': 'iid-datasource',
|
|
Packit Service |
a04d08 |
'instance_id': 'iid-datasource',
|
|
Packit Service |
a04d08 |
'local-hostname': 'test-subclass-hostname',
|
|
Packit Service |
a04d08 |
'local_hostname': 'test-subclass-hostname',
|
|
Packit Service |
751c4a |
'kernel_release': '5.4.0-24-generic',
|
|
Packit Service |
751c4a |
'machine': 'x86_64',
|
|
Packit Service |
a04d08 |
'platform': 'mytestsubclass',
|
|
Packit Service |
a04d08 |
'public_ssh_keys': [],
|
|
Packit Service |
751c4a |
'python_version': '3.7',
|
|
Packit Service |
a04d08 |
'region': 'myregion',
|
|
Packit Service |
751c4a |
'system_platform':
|
|
Packit Service |
751c4a |
'Linux-5.4.0-24-generic-x86_64-with-Ubuntu-20.04-focal',
|
|
Packit Service |
751c4a |
'subplatform': 'unknown',
|
|
Packit Service |
751c4a |
'variant': 'ubuntu'},
|
|
Packit Service |
a04d08 |
'ds': {
|
|
Packit Service |
751c4a |
|
|
Packit Service |
a04d08 |
'_doc': EXPERIMENTAL_TEXT,
|
|
Packit Service |
a04d08 |
'meta_data': {'availability_zone': 'myaz',
|
|
Packit Service |
a04d08 |
'local-hostname': 'test-subclass-hostname',
|
|
Packit Service |
a04d08 |
'region': 'myregion'}}}
|
|
Packit Service |
a04d08 |
self.assertEqual(expected, util.load_json(content))
|
|
Packit Service |
a04d08 |
file_stat = os.stat(json_file)
|
|
Packit Service |
a04d08 |
self.assertEqual(0o644, stat.S_IMODE(file_stat.st_mode))
|
|
Packit Service |
a04d08 |
self.assertEqual(expected, util.load_json(content))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
751c4a |
def test_get_data_writes_redacted_public_json_instance_data(self):
|
|
Packit Service |
751c4a |
"""get_data writes redacted content to public INSTANCE_JSON_FILE."""
|
|
Packit Service |
a04d08 |
tmp = self.tmp_dir()
|
|
Packit Service |
a04d08 |
datasource = DataSourceTestSubclassNet(
|
|
Packit Service |
a04d08 |
self.sys_cfg, self.distro, Paths({'run_dir': tmp}),
|
|
Packit Service |
a04d08 |
custom_metadata={
|
|
Packit Service |
a04d08 |
'availability_zone': 'myaz',
|
|
Packit Service |
a04d08 |
'local-hostname': 'test-subclass-hostname',
|
|
Packit Service |
a04d08 |
'region': 'myregion',
|
|
Packit Service |
a04d08 |
'some': {'security-credentials': {
|
|
Packit Service |
a04d08 |
'cred1': 'sekret', 'cred2': 'othersekret'}}})
|
|
Packit Service |
751c4a |
self.assertCountEqual(
|
|
Packit Service |
751c4a |
('merged_cfg', 'security-credentials',),
|
|
Packit Service |
751c4a |
datasource.sensitive_metadata_keys)
|
|
Packit Service |
751c4a |
sys_info = {
|
|
Packit Service |
751c4a |
"python": "3.7",
|
|
Packit Service |
751c4a |
"platform":
|
|
Packit Service |
751c4a |
"Linux-5.4.0-24-generic-x86_64-with-Ubuntu-20.04-focal",
|
|
Packit Service |
751c4a |
"uname": ["Linux", "myhost", "5.4.0-24-generic", "SMP blah",
|
|
Packit Service |
751c4a |
"x86_64"],
|
|
Packit Service |
751c4a |
"variant": "ubuntu", "dist": ["ubuntu", "20.04", "focal"]}
|
|
Packit Service |
751c4a |
with mock.patch("cloudinit.util.system_info", return_value=sys_info):
|
|
Packit Service |
751c4a |
datasource.get_data()
|
|
Packit Service |
11b429 |
json_file = self.tmp_path(INSTANCE_JSON_FILE, tmp)
|
|
Packit Service |
11b429 |
redacted = util.load_json(util.load_file(json_file))
|
|
Packit Service |
a04d08 |
expected = {
|
|
Packit Service |
a04d08 |
'base64_encoded_keys': [],
|
|
Packit Service |
751c4a |
'merged_cfg': REDACT_SENSITIVE_VALUE,
|
|
Packit Service |
751c4a |
'sensitive_keys': [
|
|
Packit Service |
751c4a |
'ds/meta_data/some/security-credentials', 'merged_cfg'],
|
|
Packit Service |
751c4a |
'sys_info': sys_info,
|
|
Packit Service |
a04d08 |
'v1': {
|
|
Packit Service |
a04d08 |
'_beta_keys': ['subplatform'],
|
|
Packit Service |
a04d08 |
'availability-zone': 'myaz',
|
|
Packit Service |
a04d08 |
'availability_zone': 'myaz',
|
|
Packit Service |
a04d08 |
'cloud-name': 'subclasscloudname',
|
|
Packit Service |
a04d08 |
'cloud_name': 'subclasscloudname',
|
|
Packit Service |
751c4a |
'distro': 'ubuntu',
|
|
Packit Service |
751c4a |
'distro_release': 'focal',
|
|
Packit Service |
751c4a |
'distro_version': '20.04',
|
|
Packit Service |
a04d08 |
'instance-id': 'iid-datasource',
|
|
Packit Service |
a04d08 |
'instance_id': 'iid-datasource',
|
|
Packit Service |
a04d08 |
'local-hostname': 'test-subclass-hostname',
|
|
Packit Service |
a04d08 |
'local_hostname': 'test-subclass-hostname',
|
|
Packit Service |
751c4a |
'kernel_release': '5.4.0-24-generic',
|
|
Packit Service |
751c4a |
'machine': 'x86_64',
|
|
Packit Service |
a04d08 |
'platform': 'mytestsubclass',
|
|
Packit Service |
a04d08 |
'public_ssh_keys': [],
|
|
Packit Service |
751c4a |
'python_version': '3.7',
|
|
Packit Service |
a04d08 |
'region': 'myregion',
|
|
Packit Service |
751c4a |
'system_platform':
|
|
Packit Service |
751c4a |
'Linux-5.4.0-24-generic-x86_64-with-Ubuntu-20.04-focal',
|
|
Packit Service |
751c4a |
'subplatform': 'unknown',
|
|
Packit Service |
751c4a |
'variant': 'ubuntu'},
|
|
Packit Service |
a04d08 |
'ds': {
|
|
Packit Service |
a04d08 |
'_doc': EXPERIMENTAL_TEXT,
|
|
Packit Service |
a04d08 |
'meta_data': {
|
|
Packit Service |
a04d08 |
'availability_zone': 'myaz',
|
|
Packit Service |
a04d08 |
'local-hostname': 'test-subclass-hostname',
|
|
Packit Service |
a04d08 |
'region': 'myregion',
|
|
Packit Service |
11b429 |
'some': {'security-credentials': REDACT_SENSITIVE_VALUE}}}
|
|
Packit Service |
a04d08 |
}
|
|
Packit Service |
751c4a |
self.assertCountEqual(expected, redacted)
|
|
Packit Service |
751c4a |
file_stat = os.stat(json_file)
|
|
Packit Service |
751c4a |
self.assertEqual(0o644, stat.S_IMODE(file_stat.st_mode))
|
|
Packit Service |
751c4a |
|
|
Packit Service |
751c4a |
def test_get_data_writes_json_instance_data_sensitive(self):
|
|
Packit Service |
751c4a |
"""
|
|
Packit Service |
751c4a |
get_data writes unmodified data to sensitive file as root-readonly.
|
|
Packit Service |
751c4a |
"""
|
|
Packit Service |
751c4a |
tmp = self.tmp_dir()
|
|
Packit Service |
751c4a |
datasource = DataSourceTestSubclassNet(
|
|
Packit Service |
751c4a |
self.sys_cfg, self.distro, Paths({'run_dir': tmp}),
|
|
Packit Service |
751c4a |
custom_metadata={
|
|
Packit Service |
751c4a |
'availability_zone': 'myaz',
|
|
Packit Service |
751c4a |
'local-hostname': 'test-subclass-hostname',
|
|
Packit Service |
751c4a |
'region': 'myregion',
|
|
Packit Service |
751c4a |
'some': {'security-credentials': {
|
|
Packit Service |
751c4a |
'cred1': 'sekret', 'cred2': 'othersekret'}}})
|
|
Packit Service |
751c4a |
sys_info = {
|
|
Packit Service |
751c4a |
"python": "3.7",
|
|
Packit Service |
751c4a |
"platform":
|
|
Packit Service |
751c4a |
"Linux-5.4.0-24-generic-x86_64-with-Ubuntu-20.04-focal",
|
|
Packit Service |
751c4a |
"uname": ["Linux", "myhost", "5.4.0-24-generic", "SMP blah",
|
|
Packit Service |
751c4a |
"x86_64"],
|
|
Packit Service |
751c4a |
"variant": "ubuntu", "dist": ["ubuntu", "20.04", "focal"]}
|
|
Packit Service |
751c4a |
|
|
Packit Service |
751c4a |
self.assertCountEqual(
|
|
Packit Service |
751c4a |
('merged_cfg', 'security-credentials',),
|
|
Packit Service |
751c4a |
datasource.sensitive_metadata_keys)
|
|
Packit Service |
751c4a |
with mock.patch("cloudinit.util.system_info", return_value=sys_info):
|
|
Packit Service |
751c4a |
datasource.get_data()
|
|
Packit Service |
751c4a |
sensitive_json_file = self.tmp_path(INSTANCE_JSON_SENSITIVE_FILE, tmp)
|
|
Packit Service |
751c4a |
content = util.load_file(sensitive_json_file)
|
|
Packit Service |
751c4a |
expected = {
|
|
Packit Service |
751c4a |
'base64_encoded_keys': [],
|
|
Packit Service |
751c4a |
'merged_cfg': {
|
|
Packit Service |
751c4a |
'_doc': (
|
|
Packit Service |
751c4a |
'Merged cloud-init system config from '
|
|
Packit Service |
751c4a |
'/etc/cloud/cloud.cfg and /etc/cloud/cloud.cfg.d/'
|
|
Packit Service |
751c4a |
),
|
|
Packit Service |
751c4a |
'datasource': {'_undef': {'key1': False}}},
|
|
Packit Service |
751c4a |
'sensitive_keys': [
|
|
Packit Service |
751c4a |
'ds/meta_data/some/security-credentials', 'merged_cfg'],
|
|
Packit Service |
751c4a |
'sys_info': sys_info,
|
|
Packit Service |
751c4a |
'v1': {
|
|
Packit Service |
751c4a |
'_beta_keys': ['subplatform'],
|
|
Packit Service |
751c4a |
'availability-zone': 'myaz',
|
|
Packit Service |
751c4a |
'availability_zone': 'myaz',
|
|
Packit Service |
751c4a |
'cloud-name': 'subclasscloudname',
|
|
Packit Service |
751c4a |
'cloud_name': 'subclasscloudname',
|
|
Packit Service |
751c4a |
'distro': 'ubuntu',
|
|
Packit Service |
751c4a |
'distro_release': 'focal',
|
|
Packit Service |
751c4a |
'distro_version': '20.04',
|
|
Packit Service |
751c4a |
'instance-id': 'iid-datasource',
|
|
Packit Service |
751c4a |
'instance_id': 'iid-datasource',
|
|
Packit Service |
751c4a |
'kernel_release': '5.4.0-24-generic',
|
|
Packit Service |
751c4a |
'local-hostname': 'test-subclass-hostname',
|
|
Packit Service |
751c4a |
'local_hostname': 'test-subclass-hostname',
|
|
Packit Service |
751c4a |
'machine': 'x86_64',
|
|
Packit Service |
751c4a |
'platform': 'mytestsubclass',
|
|
Packit Service |
751c4a |
'public_ssh_keys': [],
|
|
Packit Service |
751c4a |
'python_version': '3.7',
|
|
Packit Service |
751c4a |
'region': 'myregion',
|
|
Packit Service |
751c4a |
'subplatform': 'unknown',
|
|
Packit Service |
751c4a |
'system_platform':
|
|
Packit Service |
751c4a |
'Linux-5.4.0-24-generic-x86_64-with-Ubuntu-20.04-focal',
|
|
Packit Service |
751c4a |
'variant': 'ubuntu'},
|
|
Packit Service |
751c4a |
'ds': {
|
|
Packit Service |
751c4a |
'_doc': EXPERIMENTAL_TEXT,
|
|
Packit Service |
751c4a |
'meta_data': {
|
|
Packit Service |
751c4a |
'availability_zone': 'myaz',
|
|
Packit Service |
751c4a |
'local-hostname': 'test-subclass-hostname',
|
|
Packit Service |
751c4a |
'region': 'myregion',
|
|
Packit Service |
751c4a |
'some': {
|
|
Packit Service |
751c4a |
'security-credentials':
|
|
Packit Service |
751c4a |
{'cred1': 'sekret', 'cred2': 'othersekret'}}}}
|
|
Packit Service |
751c4a |
}
|
|
Packit Service |
751c4a |
self.assertCountEqual(expected, util.load_json(content))
|
|
Packit Service |
a04d08 |
file_stat = os.stat(sensitive_json_file)
|
|
Packit Service |
a04d08 |
self.assertEqual(0o600, stat.S_IMODE(file_stat.st_mode))
|
|
Packit Service |
a04d08 |
self.assertEqual(expected, util.load_json(content))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_get_data_handles_redacted_unserializable_content(self):
|
|
Packit Service |
a04d08 |
"""get_data warns unserializable content in INSTANCE_JSON_FILE."""
|
|
Packit Service |
a04d08 |
tmp = self.tmp_dir()
|
|
Packit Service |
a04d08 |
datasource = DataSourceTestSubclassNet(
|
|
Packit Service |
a04d08 |
self.sys_cfg, self.distro, Paths({'run_dir': tmp}),
|
|
Packit Service |
a04d08 |
custom_metadata={'key1': 'val1', 'key2': {'key2.1': self.paths}})
|
|
Packit Service |
a04d08 |
datasource.get_data()
|
|
Packit Service |
a04d08 |
json_file = self.tmp_path(INSTANCE_JSON_FILE, tmp)
|
|
Packit Service |
a04d08 |
content = util.load_file(json_file)
|
|
Packit Service |
a04d08 |
expected_metadata = {
|
|
Packit Service |
a04d08 |
'key1': 'val1',
|
|
Packit Service |
a04d08 |
'key2': {
|
|
Packit Service |
a04d08 |
'key2.1': "Warning: redacted unserializable type
|
|
Packit Service |
a04d08 |
" 'cloudinit.helpers.Paths'>"}}
|
|
Packit Service |
a04d08 |
instance_json = util.load_json(content)
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
expected_metadata, instance_json['ds']['meta_data'])
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_persist_instance_data_writes_ec2_metadata_when_set(self):
|
|
Packit Service |
a04d08 |
"""When ec2_metadata class attribute is set, persist to json."""
|
|
Packit Service |
a04d08 |
tmp = self.tmp_dir()
|
|
Packit Service |
a04d08 |
datasource = DataSourceTestSubclassNet(
|
|
Packit Service |
a04d08 |
self.sys_cfg, self.distro, Paths({'run_dir': tmp}))
|
|
Packit Service |
a04d08 |
datasource.ec2_metadata = UNSET
|
|
Packit Service |
a04d08 |
datasource.get_data()
|
|
Packit Service |
a04d08 |
json_file = self.tmp_path(INSTANCE_JSON_FILE, tmp)
|
|
Packit Service |
a04d08 |
instance_data = util.load_json(util.load_file(json_file))
|
|
Packit Service |
a04d08 |
self.assertNotIn('ec2_metadata', instance_data['ds'])
|
|
Packit Service |
a04d08 |
datasource.ec2_metadata = {'ec2stuff': 'is good'}
|
|
Packit Service |
a04d08 |
datasource.persist_instance_data()
|
|
Packit Service |
a04d08 |
instance_data = util.load_json(util.load_file(json_file))
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
{'ec2stuff': 'is good'},
|
|
Packit Service |
a04d08 |
instance_data['ds']['ec2_metadata'])
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_persist_instance_data_writes_network_json_when_set(self):
|
|
Packit Service |
a04d08 |
"""When network_data.json class attribute is set, persist to json."""
|
|
Packit Service |
a04d08 |
tmp = self.tmp_dir()
|
|
Packit Service |
a04d08 |
datasource = DataSourceTestSubclassNet(
|
|
Packit Service |
a04d08 |
self.sys_cfg, self.distro, Paths({'run_dir': tmp}))
|
|
Packit Service |
a04d08 |
datasource.get_data()
|
|
Packit Service |
a04d08 |
json_file = self.tmp_path(INSTANCE_JSON_FILE, tmp)
|
|
Packit Service |
a04d08 |
instance_data = util.load_json(util.load_file(json_file))
|
|
Packit Service |
a04d08 |
self.assertNotIn('network_json', instance_data['ds'])
|
|
Packit Service |
a04d08 |
datasource.network_json = {'network_json': 'is good'}
|
|
Packit Service |
a04d08 |
datasource.persist_instance_data()
|
|
Packit Service |
a04d08 |
instance_data = util.load_json(util.load_file(json_file))
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
{'network_json': 'is good'},
|
|
Packit Service |
a04d08 |
instance_data['ds']['network_json'])
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_get_data_base64encodes_unserializable_bytes(self):
|
|
Packit Service |
a04d08 |
"""On py3, get_data base64encodes any unserializable content."""
|
|
Packit Service |
a04d08 |
tmp = self.tmp_dir()
|
|
Packit Service |
a04d08 |
datasource = DataSourceTestSubclassNet(
|
|
Packit Service |
a04d08 |
self.sys_cfg, self.distro, Paths({'run_dir': tmp}),
|
|
Packit Service |
a04d08 |
custom_metadata={'key1': 'val1', 'key2': {'key2.1': b'\x123'}})
|
|
Packit Service |
a04d08 |
self.assertTrue(datasource.get_data())
|
|
Packit Service |
a04d08 |
json_file = self.tmp_path(INSTANCE_JSON_FILE, tmp)
|
|
Packit Service |
a04d08 |
content = util.load_file(json_file)
|
|
Packit Service |
a04d08 |
instance_json = util.load_json(content)
|
|
Packit Service |
751c4a |
self.assertCountEqual(
|
|
Packit Service |
a04d08 |
['ds/meta_data/key2/key2.1'],
|
|
Packit Service |
a04d08 |
instance_json['base64_encoded_keys'])
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
{'key1': 'val1', 'key2': {'key2.1': 'EjM='}},
|
|
Packit Service |
a04d08 |
instance_json['ds']['meta_data'])
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_get_hostname_subclass_support(self):
|
|
Packit Service |
a04d08 |
"""Validate get_hostname signature on all subclasses of DataSource."""
|
|
Packit Service |
751c4a |
base_args = inspect.getfullargspec(DataSource.get_hostname)
|
|
Packit Service |
a04d08 |
# Import all DataSource subclasses so we can inspect them.
|
|
Packit Service |
a04d08 |
modules = util.find_modules(os.path.dirname(os.path.dirname(__file__)))
|
|
Packit Service |
a04d08 |
for _loc, name in modules.items():
|
|
Packit Service |
a04d08 |
mod_locs, _ = importer.find_module(name, ['cloudinit.sources'], [])
|
|
Packit Service |
a04d08 |
if mod_locs:
|
|
Packit Service |
a04d08 |
importer.import_module(mod_locs[0])
|
|
Packit Service |
a04d08 |
for child in DataSource.__subclasses__():
|
|
Packit Service |
a04d08 |
if 'Test' in child.dsname:
|
|
Packit Service |
a04d08 |
continue
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
base_args,
|
|
Packit Service |
751c4a |
inspect.getfullargspec(child.get_hostname),
|
|
Packit Service |
a04d08 |
'%s does not implement DataSource.get_hostname params'
|
|
Packit Service |
a04d08 |
% child)
|
|
Packit Service |
a04d08 |
for grandchild in child.__subclasses__():
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
base_args,
|
|
Packit Service |
751c4a |
inspect.getfullargspec(grandchild.get_hostname),
|
|
Packit Service |
a04d08 |
'%s does not implement DataSource.get_hostname params'
|
|
Packit Service |
a04d08 |
% grandchild)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_clear_cached_attrs_resets_cached_attr_class_attributes(self):
|
|
Packit Service |
a04d08 |
"""Class attributes listed in cached_attr_defaults are reset."""
|
|
Packit Service |
a04d08 |
count = 0
|
|
Packit Service |
a04d08 |
# Setup values for all cached class attributes
|
|
Packit Service |
a04d08 |
for attr, value in self.datasource.cached_attr_defaults:
|
|
Packit Service |
a04d08 |
setattr(self.datasource, attr, count)
|
|
Packit Service |
a04d08 |
count += 1
|
|
Packit Service |
a04d08 |
self.datasource._dirty_cache = True
|
|
Packit Service |
a04d08 |
self.datasource.clear_cached_attrs()
|
|
Packit Service |
a04d08 |
for attr, value in self.datasource.cached_attr_defaults:
|
|
Packit Service |
a04d08 |
self.assertEqual(value, getattr(self.datasource, attr))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_clear_cached_attrs_noops_on_clean_cache(self):
|
|
Packit Service |
a04d08 |
"""Class attributes listed in cached_attr_defaults are reset."""
|
|
Packit Service |
a04d08 |
count = 0
|
|
Packit Service |
a04d08 |
# Setup values for all cached class attributes
|
|
Packit Service |
a04d08 |
for attr, _ in self.datasource.cached_attr_defaults:
|
|
Packit Service |
a04d08 |
setattr(self.datasource, attr, count)
|
|
Packit Service |
a04d08 |
count += 1
|
|
Packit Service |
a04d08 |
self.datasource._dirty_cache = False # Fake clean cache
|
|
Packit Service |
a04d08 |
self.datasource.clear_cached_attrs()
|
|
Packit Service |
a04d08 |
count = 0
|
|
Packit Service |
a04d08 |
for attr, _ in self.datasource.cached_attr_defaults:
|
|
Packit Service |
a04d08 |
self.assertEqual(count, getattr(self.datasource, attr))
|
|
Packit Service |
a04d08 |
count += 1
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_clear_cached_attrs_skips_non_attr_class_attributes(self):
|
|
Packit Service |
a04d08 |
"""Skip any cached_attr_defaults which aren't class attributes."""
|
|
Packit Service |
a04d08 |
self.datasource._dirty_cache = True
|
|
Packit Service |
a04d08 |
self.datasource.clear_cached_attrs()
|
|
Packit Service |
a04d08 |
for attr in ('ec2_metadata', 'network_json'):
|
|
Packit Service |
a04d08 |
self.assertFalse(hasattr(self.datasource, attr))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_clear_cached_attrs_of_custom_attrs(self):
|
|
Packit Service |
a04d08 |
"""Custom attr_values can be passed to clear_cached_attrs."""
|
|
Packit Service |
a04d08 |
self.datasource._dirty_cache = True
|
|
Packit Service |
a04d08 |
cached_attr_name = self.datasource.cached_attr_defaults[0][0]
|
|
Packit Service |
a04d08 |
setattr(self.datasource, cached_attr_name, 'himom')
|
|
Packit Service |
a04d08 |
self.datasource.myattr = 'orig'
|
|
Packit Service |
a04d08 |
self.datasource.clear_cached_attrs(
|
|
Packit Service |
a04d08 |
attr_defaults=(('myattr', 'updated'),))
|
|
Packit Service |
a04d08 |
self.assertEqual('himom', getattr(self.datasource, cached_attr_name))
|
|
Packit Service |
a04d08 |
self.assertEqual('updated', self.datasource.myattr)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_update_metadata_only_acts_on_supported_update_events(self):
|
|
Packit Service |
a04d08 |
"""update_metadata won't get_data on unsupported update events."""
|
|
Packit Service |
a04d08 |
self.datasource.update_events['network'].discard(EventType.BOOT)
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
{'network': set([EventType.BOOT_NEW_INSTANCE])},
|
|
Packit Service |
a04d08 |
self.datasource.update_events)
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def fake_get_data():
|
|
Packit Service |
a04d08 |
raise Exception('get_data should not be called')
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
self.datasource.get_data = fake_get_data
|
|
Packit Service |
a04d08 |
self.assertFalse(
|
|
Packit Service |
a04d08 |
self.datasource.update_metadata(
|
|
Packit Service |
a04d08 |
source_event_types=[EventType.BOOT]))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_update_metadata_returns_true_on_supported_update_event(self):
|
|
Packit Service |
a04d08 |
"""update_metadata returns get_data response on supported events."""
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def fake_get_data():
|
|
Packit Service |
a04d08 |
return True
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
self.datasource.get_data = fake_get_data
|
|
Packit Service |
a04d08 |
self.datasource._network_config = 'something'
|
|
Packit Service |
a04d08 |
self.datasource._dirty_cache = True
|
|
Packit Service |
a04d08 |
self.assertTrue(
|
|
Packit Service |
a04d08 |
self.datasource.update_metadata(
|
|
Packit Service |
a04d08 |
source_event_types=[
|
|
Packit Service |
a04d08 |
EventType.BOOT, EventType.BOOT_NEW_INSTANCE]))
|
|
Packit Service |
a04d08 |
self.assertEqual(UNSET, self.datasource._network_config)
|
|
Packit Service |
a04d08 |
self.assertIn(
|
|
Packit Service |
a04d08 |
"DEBUG: Update datasource metadata and network config due to"
|
|
Packit Service |
a04d08 |
" events: New instance first boot",
|
|
Packit Service |
a04d08 |
self.logs.getvalue())
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
class TestRedactSensitiveData(CiTestCase):
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_redact_sensitive_data_noop_when_no_sensitive_keys_present(self):
|
|
Packit Service |
a04d08 |
"""When sensitive_keys is absent or empty from metadata do nothing."""
|
|
Packit Service |
a04d08 |
md = {'my': 'data'}
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
md, redact_sensitive_keys(md, redact_value='redacted'))
|
|
Packit Service |
a04d08 |
md['sensitive_keys'] = []
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
md, redact_sensitive_keys(md, redact_value='redacted'))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_redact_sensitive_data_redacts_exact_match_name(self):
|
|
Packit Service |
a04d08 |
"""Only exact matched sensitive_keys are redacted from metadata."""
|
|
Packit Service |
a04d08 |
md = {'sensitive_keys': ['md/secure'],
|
|
Packit Service |
a04d08 |
'md': {'secure': 's3kr1t', 'insecure': 'publik'}}
|
|
Packit Service |
a04d08 |
secure_md = copy.deepcopy(md)
|
|
Packit Service |
a04d08 |
secure_md['md']['secure'] = 'redacted'
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
secure_md,
|
|
Packit Service |
a04d08 |
redact_sensitive_keys(md, redact_value='redacted'))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_redact_sensitive_data_does_redacts_with_default_string(self):
|
|
Packit Service |
a04d08 |
"""When redact_value is absent, REDACT_SENSITIVE_VALUE is used."""
|
|
Packit Service |
a04d08 |
md = {'sensitive_keys': ['md/secure'],
|
|
Packit Service |
a04d08 |
'md': {'secure': 's3kr1t', 'insecure': 'publik'}}
|
|
Packit Service |
a04d08 |
secure_md = copy.deepcopy(md)
|
|
Packit Service |
a04d08 |
secure_md['md']['secure'] = 'redacted for non-root user'
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
secure_md,
|
|
Packit Service |
a04d08 |
redact_sensitive_keys(md))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
class TestCanonicalCloudID(CiTestCase):
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_cloud_id_returns_platform_on_unknowns(self):
|
|
Packit Service |
a04d08 |
"""When region and cloud_name are unknown, return platform."""
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
'platform',
|
|
Packit Service |
a04d08 |
canonical_cloud_id(cloud_name=METADATA_UNKNOWN,
|
|
Packit Service |
a04d08 |
region=METADATA_UNKNOWN,
|
|
Packit Service |
a04d08 |
platform='platform'))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_cloud_id_returns_platform_on_none(self):
|
|
Packit Service |
a04d08 |
"""When region and cloud_name are unknown, return platform."""
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
'platform',
|
|
Packit Service |
a04d08 |
canonical_cloud_id(cloud_name=None,
|
|
Packit Service |
a04d08 |
region=None,
|
|
Packit Service |
a04d08 |
platform='platform'))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_cloud_id_returns_cloud_name_on_unknown_region(self):
|
|
Packit Service |
a04d08 |
"""When region is unknown, return cloud_name."""
|
|
Packit Service |
a04d08 |
for region in (None, METADATA_UNKNOWN):
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
'cloudname',
|
|
Packit Service |
a04d08 |
canonical_cloud_id(cloud_name='cloudname',
|
|
Packit Service |
a04d08 |
region=region,
|
|
Packit Service |
a04d08 |
platform='platform'))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_cloud_id_returns_platform_on_unknown_cloud_name(self):
|
|
Packit Service |
a04d08 |
"""When region is set but cloud_name is unknown return cloud_name."""
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
'platform',
|
|
Packit Service |
a04d08 |
canonical_cloud_id(cloud_name=METADATA_UNKNOWN,
|
|
Packit Service |
a04d08 |
region='region',
|
|
Packit Service |
a04d08 |
platform='platform'))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_cloud_id_aws_based_on_region_and_cloud_name(self):
|
|
Packit Service |
a04d08 |
"""When cloud_name is aws, return proper cloud-id based on region."""
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
'aws-china',
|
|
Packit Service |
a04d08 |
canonical_cloud_id(cloud_name='aws',
|
|
Packit Service |
a04d08 |
region='cn-north-1',
|
|
Packit Service |
a04d08 |
platform='platform'))
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
'aws',
|
|
Packit Service |
a04d08 |
canonical_cloud_id(cloud_name='aws',
|
|
Packit Service |
a04d08 |
region='us-east-1',
|
|
Packit Service |
a04d08 |
platform='platform'))
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
'aws-gov',
|
|
Packit Service |
a04d08 |
canonical_cloud_id(cloud_name='aws',
|
|
Packit Service |
a04d08 |
region='us-gov-1',
|
|
Packit Service |
a04d08 |
platform='platform'))
|
|
Packit Service |
a04d08 |
self.assertEqual( # Overrideen non-aws cloud_name is returned
|
|
Packit Service |
a04d08 |
'!aws',
|
|
Packit Service |
a04d08 |
canonical_cloud_id(cloud_name='!aws',
|
|
Packit Service |
a04d08 |
region='us-gov-1',
|
|
Packit Service |
a04d08 |
platform='platform'))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
def test_cloud_id_azure_based_on_region_and_cloud_name(self):
|
|
Packit Service |
a04d08 |
"""Report cloud-id when cloud_name is azure and region is in china."""
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
'azure-china',
|
|
Packit Service |
a04d08 |
canonical_cloud_id(cloud_name='azure',
|
|
Packit Service |
a04d08 |
region='chinaeast',
|
|
Packit Service |
a04d08 |
platform='platform'))
|
|
Packit Service |
a04d08 |
self.assertEqual(
|
|
Packit Service |
a04d08 |
'azure',
|
|
Packit Service |
a04d08 |
canonical_cloud_id(cloud_name='azure',
|
|
Packit Service |
a04d08 |
region='!chinaeast',
|
|
Packit Service |
a04d08 |
platform='platform'))
|
|
Packit Service |
a04d08 |
|
|
Packit Service |
a04d08 |
# vi: ts=4 expandtab
|