Merge "Consume new RoleConfig data in config download"

This commit is contained in:
Jenkins 2017-09-06 11:01:39 +00:00 committed by Gerrit Code Review
commit 4f25a69d17
4 changed files with 108 additions and 94 deletions

View File

@ -26,55 +26,54 @@ FAKE_STACK = {
}, },
'stack_name': 'overcloud', 'stack_name': 'overcloud',
'stack_status': "CREATE_COMPLETE", 'stack_status': "CREATE_COMPLETE",
'outputs': [{ 'outputs': [
'output_key': 'RoleData', {'output_key': 'RoleConfig',
'output_value': { 'output_value': {
'FakeCompute': { 'foo_config': 'foo'}},
'config_settings': {'nova::compute::libvirt::services::' {'output_key': 'RoleData',
'libvirt_virt_type': 'qemu'}, 'output_value': {
'global_config_settings': {}, 'FakeCompute': {
'logging_groups': ['root', 'neutron', 'nova'], 'config_settings': {'nova::compute::libvirt::services::'
'logging_sources': [{'path': '/var/log/nova/nova-compute.log', 'libvirt_virt_type': 'qemu'},
'type': 'tail'}], 'global_config_settings': {},
'monitoring_subscriptions': ['overcloud-nova-compute'], 'logging_groups': ['root', 'neutron', 'nova'],
'service_config_settings': {'horizon': {'neutron::' 'logging_sources': [{'path': '/var/log/nova/nova-compute.log',
'plugins': ['ovs']} 'type': 'tail'}],
}, 'monitoring_subscriptions': ['overcloud-nova-compute'],
'service_metadata_settings': None, 'service_config_settings': {'horizon': {'neutron::'
'service_names': ['nova_compute', 'fake_service'], 'plugins': ['ovs']}
'step_config': ['include ::tripleo::profile::base::sshd', },
'include ::timezone'], 'service_metadata_settings': None,
'upgrade_batch_tasks': [], 'service_names': ['nova_compute', 'fake_service'],
'upgrade_tasks': [{'name': 'Stop fake service', 'step_config': ['include ::tripleo::profile::base::sshd',
'service': 'name=fake state=stopped', 'include ::timezone'],
'tags': 'step1'}, 'upgrade_batch_tasks': [],
{'name': 'Stop nova-compute service', 'upgrade_tasks': [{'name': 'Stop fake service',
'service': 'name=openstack-nova-compute ' 'service': 'name=fake state=stopped',
'state=stopped', 'tags': 'step1'},
'tags': 'step1'}] {'name': 'Stop nova-compute service',
}, 'service': 'name=openstack-nova-compute '
'FakeController': { 'state=stopped',
'config_settings': {'tripleo::haproxy::user': 'admin'}, 'tags': 'step1'}]
'global_config_settings': {}, },
'logging_groups': ['root', 'keystone', 'neutron'], 'FakeController': {
'logging_sources': [{'path': '/var/log/keystone/keystone.log', 'config_settings': {'tripleo::haproxy::user': 'admin'},
'type': 'tail'}], 'global_config_settings': {},
'monitoring_subscriptions': ['overcloud-keystone'], 'logging_groups': ['root', 'keystone', 'neutron'],
'service_config_settings': {'horizon': {'neutron::' 'logging_sources': [{'path': '/var/log/keystone/keystone.log',
'plugins': ['ovs']} 'type': 'tail'}],
}, 'monitoring_subscriptions': ['overcloud-keystone'],
'service_metadata_settings': None, 'service_config_settings': {'horizon': {'neutron::'
'service_names': ['pacemaker', 'fake_service'], 'plugins': ['ovs']}
'step_config': ['include ::tripleo::profile::base::sshd', },
'include ::timezone'], 'service_metadata_settings': None,
'upgrade_batch_tasks': [], 'service_names': ['pacemaker', 'fake_service'],
'upgrade_tasks': [{'name': 'Stop fake service', 'step_config': ['include ::tripleo::profile::base::sshd',
'service': 'name=fake state=stopped', 'include ::timezone'],
'tags': 'step1'}] 'upgrade_batch_tasks': [],
} 'upgrade_tasks': [{'name': 'Stop fake service',
} 'service': 'name=fake state=stopped',
}] 'tags': 'step1'}]}}}]}
}
def create_to_dict_mock(**kwargs): def create_to_dict_mock(**kwargs):

View File

@ -11,9 +11,9 @@
# under the License. # under the License.
import mock import mock
import stat
from mock import call from mock import call
from mock import patch
from osc_lib.tests import utils from osc_lib.tests import utils
from tripleoclient.tests.v1.overcloud_config import fakes from tripleoclient.tests.v1.overcloud_config import fakes
@ -30,8 +30,13 @@ class TestOvercloudConfig(utils.TestCommand):
self.app.client_manager.orchestration = mock.Mock() self.app.client_manager.orchestration = mock.Mock()
self.workflow = self.app.client_manager.workflow_engine self.workflow = self.app.client_manager.workflow_engine
@patch.object(overcloud_config.DownloadConfig, '_mkdir')
@patch.object(overcloud_config.DownloadConfig, '_open_file')
@mock.patch('tempfile.mkdtemp', autospec=True) @mock.patch('tempfile.mkdtemp', autospec=True)
def test_overcloud_config_generate_config(self, mock_tmpdir): def test_overcloud_config_generate_config(self,
mock_tmpdir,
mock_open,
mock_mkdir):
arglist = ['--name', 'overcloud', '--config-dir', '/tmp'] arglist = ['--name', 'overcloud', '--config-dir', '/tmp']
verifylist = [ verifylist = [
('name', 'overcloud'), ('name', 'overcloud'),
@ -44,34 +49,34 @@ class TestOvercloudConfig(utils.TestCommand):
'service_names', 'service_names',
'upgrade_batch_tasks', 'upgrade_tasks'] 'upgrade_batch_tasks', 'upgrade_tasks']
fake_role = [role for role in fake_role = [role for role in
fakes.FAKE_STACK['outputs'][0]['output_value']] fakes.FAKE_STACK['outputs'][1]['output_value']]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
clients = self.app.client_manager clients = self.app.client_manager
orchestration_client = clients.orchestration orchestration_client = clients.orchestration
orchestration_client.stacks.get.return_value = fakes.create_tht_stack() orchestration_client.stacks.get.return_value = fakes.create_tht_stack()
mock_tmpdir.return_value = "/tmp/tht" mock_tmpdir.return_value = "/tmp/tht"
with mock.patch('os.open') as open, \ self.cmd.take_action(parsed_args)
mock.patch('os.fdopen'), mock.patch('os.mkdir') as mkdir: expected_mkdir_calls = [call('/tmp/tht/%s' % r) for r in fake_role]
self.cmd.take_action(parsed_args) mock_mkdir.assert_has_calls(expected_mkdir_calls, any_order=True)
expected_mkdir_calls = [call('/tmp/tht/%s' % r, expected_calls = []
stat.S_IRWXU) for r in fake_role] for config in config_type_list:
mkdir.assert_has_calls(expected_mkdir_calls, any_order=True) for role in fake_role:
expected_calls = [] if config == 'step_config':
for config in config_type_list: expected_calls += [call('/tmp/tht/%s/%s.pp' %
for role in fake_role: (role, config))]
if config == 'step_config': else:
expected_calls += [call('/tmp/tht/%s/%s.pp' % expected_calls += [call('/tmp/tht/%s/%s.yaml' %
(role, config), 65, (role, config))]
stat.S_IRUSR | stat.S_IWUSR)] mock_open.assert_has_calls(expected_calls, any_order=True)
else:
expected_calls += [call('/tmp/tht/%s/%s.yaml' %
(role, config), 65,
stat.S_IRUSR | stat.S_IWUSR)]
open.assert_has_calls(expected_calls, any_order=True)
@patch.object(overcloud_config.DownloadConfig, '_mkdir')
@patch.object(overcloud_config.DownloadConfig, '_open_file')
@mock.patch('tempfile.mkdtemp', autospec=True) @mock.patch('tempfile.mkdtemp', autospec=True)
def test_overcloud_config_one_config_type(self, mock_tmpdir): def test_overcloud_config_one_config_type(self,
mock_tmpdir,
mock_open,
mock_mkdir):
arglist = ['--name', 'overcloud', '--config-dir', '/tmp', arglist = ['--name', 'overcloud', '--config-dir', '/tmp',
'--config-type', ['config_settings']] '--config-type', ['config_settings']]
@ -82,25 +87,20 @@ class TestOvercloudConfig(utils.TestCommand):
] ]
expected_config_type = 'config_settings' expected_config_type = 'config_settings'
fake_role = [role for role in fake_role = [role for role in
fakes.FAKE_STACK['outputs'][0]['output_value']] fakes.FAKE_STACK['outputs'][1]['output_value']]
parsed_args = self.check_parser(self.cmd, arglist, verifylist) parsed_args = self.check_parser(self.cmd, arglist, verifylist)
clients = self.app.client_manager clients = self.app.client_manager
orchestration_client = clients.orchestration orchestration_client = clients.orchestration
orchestration_client.stacks.get.return_value = fakes.create_tht_stack() orchestration_client.stacks.get.return_value = fakes.create_tht_stack()
mock_tmpdir.return_value = "/tmp/tht" mock_tmpdir.return_value = "/tmp/tht"
with mock.patch('os.open') as open, \ self.cmd.take_action(parsed_args)
mock.patch('os.fdopen'), mock.patch('os.mkdir') as mkdir: expected_mkdir_calls = [call('/tmp/tht/%s' % r) for r in fake_role]
self.cmd.take_action(parsed_args) expected_calls = [call('/tmp/tht/%s/%s.yaml'
expected_mkdir_calls = [call('/tmp/tht/%s' % r, % (r, expected_config_type))
stat.S_IRWXU) for r in fake_role] for r in fake_role]
mkdir.assert_has_calls(expected_mkdir_calls, any_order=True) mock_mkdir.assert_has_calls(expected_mkdir_calls, any_order=True)
expected_calls = [call('/tmp/tht/%s/%s.yaml' % mock_open.assert_has_calls(expected_calls, any_order=True)
(r, expected_config_type), 65,
stat.S_IRUSR | stat.S_IWUSR)
for r in fake_role]
open.assert_has_calls(expected_calls, any_order=True)
@mock.patch('os.mkdir') @mock.patch('os.mkdir')
@mock.patch('six.moves.builtins.open') @mock.patch('six.moves.builtins.open')
@ -140,7 +140,7 @@ class TestOvercloudConfig(utils.TestCommand):
orchestration_client.stacks.get.return_value = fakes.create_tht_stack() orchestration_client.stacks.get.return_value = fakes.create_tht_stack()
mock_tmpdir.return_value = "/tmp/tht" mock_tmpdir.return_value = "/tmp/tht"
fake_role = [role for role in fake_role = [role for role in
fakes.FAKE_STACK['outputs'][0]['output_value']] fakes.FAKE_STACK['outputs'][1]['output_value']]
fake_tasks = {'FakeController': [{'name': 'Stop fake service', fake_tasks = {'FakeController': [{'name': 'Stop fake service',
'service': 'name=fake ' 'service': 'name=fake '
'state=stopped', 'state=stopped',
@ -165,7 +165,7 @@ class TestOvercloudConfig(utils.TestCommand):
with mock.patch('os.fdopen'), \ with mock.patch('os.fdopen'), \
mock.patch('os.mkdir'), mock.patch('os.open') as open: mock.patch('os.mkdir'), mock.patch('os.open') as open:
playbook_tasks = self.cmd._write_playbook_get_tasks( playbook_tasks = self.cmd._write_playbook_get_tasks(
fakes.FAKE_STACK['outputs'][0]['output_value'][role] fakes.FAKE_STACK['outputs'][1]['output_value'][role]
['upgrade_tasks'], role, filepath) ['upgrade_tasks'], role, filepath)
self.assertEqual(fake_tasks[role], playbook_tasks) self.assertEqual(fake_tasks[role], playbook_tasks)
open.assert_called() open.assert_called()

View File

@ -332,6 +332,15 @@ def get_role_data(stack):
return role_data return role_data
def get_role_config(stack):
role_data = {}
for output in stack.to_dict().get('outputs', {}):
if output['output_key'] == 'RoleConfig':
for role in output['output_value']:
role_data[role] = output['output_value'][role]
return role_data
def get_endpoint(key, stack): def get_endpoint(key, stack):
endpoint_map = get_endpoint_map(stack) endpoint_map = get_endpoint_map(stack)
if endpoint_map: if endpoint_map:

View File

@ -54,6 +54,12 @@ class DownloadConfig(command.Command):
) )
return parser return parser
@staticmethod
def _open_file(path):
return os.fdopen(os.open(path,
os.O_WRONLY | os.O_CREAT, 0o600),
'w')
def _step_tags_to_when(self, sorted_tasks): def _step_tags_to_when(self, sorted_tasks):
for task in sorted_tasks: for task in sorted_tasks:
tag = task.get('tags', '') tag = task.get('tags', '')
@ -77,8 +83,7 @@ class DownloadConfig(command.Command):
playbook.append({'name': '%s playbook' % role, playbook.append({'name': '%s playbook' % role,
'hosts': role, 'hosts': role,
'tasks': sorted_tasks}) 'tasks': sorted_tasks})
with os.fdopen(os.open(filepath, os.O_WRONLY | os.O_CREAT, 0o600), with self._open_file(filepath) as conf_file:
'w') as conf_file:
yaml.safe_dump(playbook, conf_file, default_flow_style=False) yaml.safe_dump(playbook, conf_file, default_flow_style=False)
return sorted_tasks return sorted_tasks
@ -111,9 +116,7 @@ class DownloadConfig(command.Command):
for config in parsed_args.config_type or role.keys(): for config in parsed_args.config_type or role.keys():
if config == 'step_config': if config == 'step_config':
filepath = os.path.join(role_path, 'step_config.pp') filepath = os.path.join(role_path, 'step_config.pp')
with os.fdopen(os.open(filepath, with self._open_file(filepath) as step_config:
os.O_WRONLY | os.O_CREAT, 0o600),
'w') as step_config:
step_config.write('\n'.join(step for step in step_config.write('\n'.join(step for step in
role[config] role[config]
if step is not None)) if step is not None))
@ -131,11 +134,14 @@ class DownloadConfig(command.Command):
str(e)) str(e))
raise KeyError(message) raise KeyError(message)
filepath = os.path.join(role_path, '%s.yaml' % config) filepath = os.path.join(role_path, '%s.yaml' % config)
with os.fdopen(os.open(filepath, with self._open_file(filepath) as conf_file:
os.O_WRONLY | os.O_CREAT, 0o600),
'w') as conf_file:
yaml.safe_dump(data, yaml.safe_dump(data,
conf_file, conf_file,
default_flow_style=False) default_flow_style=False)
role_config = utils.get_role_config(stack)
for config_name, config in six.iteritems(role_config):
conf_path = os.path.join(tmp_path, config_name + ".yaml")
with self._open_file(conf_path) as conf_file:
conf_file.write(config)
print("The TripleO configuration has been successfully generated " print("The TripleO configuration has been successfully generated "
"into: {0}".format(tmp_path)) "into: {0}".format(tmp_path))