overcloud deploy - provision virtual ips
When the --vip-file argument provides the vip_data.yaml provision Virtual IPs and include the deployed network environment file in user environments. Depends-On: https://review.opendev.org/795080 Change-Id: I1e4f8dde9f56311bed8dcbe1b08ade09225fd595
This commit is contained in:
parent
15f2539428
commit
ef077696a0
|
@ -30,6 +30,7 @@ UNDERCLOUD_ROLES_FILE = "roles_data_undercloud.yaml"
|
|||
STANDALONE_EPHEMERAL_STACK_VSTATE = '/var/lib/tripleo-heat-installer'
|
||||
UNDERCLOUD_LOG_FILE = "install-undercloud.log"
|
||||
OVERCLOUD_NETWORKS_FILE = "network_data.yaml"
|
||||
OVERCLOUD_VIP_FILE = "vip_data_default.yaml"
|
||||
STANDALONE_NETWORKS_FILE = "/dev/null"
|
||||
UNDERCLOUD_NETWORKS_FILE = "network_data_undercloud.yaml"
|
||||
ANSIBLE_HOSTS_FILENAME = "hosts.yaml"
|
||||
|
|
|
@ -110,6 +110,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
|||
os.unlink(self.parameter_defaults_env_file)
|
||||
shutil.rmtree = self.real_shutil
|
||||
|
||||
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||
'_provision_virtual_ips', autospec=True)
|
||||
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||
'_provision_networks', autospec=True)
|
||||
@mock.patch('tripleoclient.utils.check_service_vips_migrated_to_service')
|
||||
|
@ -156,7 +158,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
|||
mock_container_prepare, mock_generate_password,
|
||||
mock_rc_params, mock_default_image_params,
|
||||
mock_stack_data, mock_check_service_vip_migr,
|
||||
mock_provision_networks):
|
||||
mock_provision_networks, mock_provision_virtual_ips):
|
||||
fixture = deployment.DeploymentWorkflowFixture()
|
||||
self.useFixture(fixture)
|
||||
clients = self.app.client_manager
|
||||
|
@ -340,6 +342,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
|||
mock_validate_args.assert_called_once_with(parsed_args)
|
||||
self.assertFalse(mock_invoke_plan_env_wf.called)
|
||||
|
||||
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||
'_provision_virtual_ips', autospec=True)
|
||||
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||
'_provision_networks', autospec=True)
|
||||
@mock.patch('tripleoclient.utils.build_stack_data', autospec=True)
|
||||
|
@ -382,7 +386,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
|||
mock_process_env, mock_roles_data,
|
||||
mock_image_prepare, mock_generate_password,
|
||||
mock_rc_params, mock_stack_data,
|
||||
mock_provision_networks):
|
||||
mock_provision_networks, mock_provision_virtual_ips):
|
||||
fixture = deployment.DeploymentWorkflowFixture()
|
||||
self.useFixture(fixture)
|
||||
utils_fixture = deployment.UtilsFixture()
|
||||
|
@ -431,6 +435,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
|||
self.cmd.take_action(parsed_args)
|
||||
mock_copy.assert_called_once()
|
||||
|
||||
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||
'_provision_virtual_ips', autospec=True)
|
||||
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||
'_provision_networks', autospec=True)
|
||||
@mock.patch('tripleoclient.utils.check_service_vips_migrated_to_service')
|
||||
|
@ -476,7 +482,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
|||
mock_rc_params,
|
||||
mock_stack_data,
|
||||
mock_check_service_vip_migr,
|
||||
mock_provision_networks):
|
||||
mock_provision_networks,
|
||||
mock_provision_virtual_ips):
|
||||
fixture = deployment.DeploymentWorkflowFixture()
|
||||
self.useFixture(fixture)
|
||||
utils_fixture = deployment.UtilsFixture()
|
||||
|
@ -758,6 +765,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
|||
self.assertFalse(utils_fixture.mock_deploy_tht.called)
|
||||
self.assertFalse(mock_deploy.called)
|
||||
|
||||
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||
'_provision_virtual_ips', autospec=True)
|
||||
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||
'_provision_networks', autospec=True)
|
||||
@mock.patch('tripleoclient.utils.check_service_vips_migrated_to_service')
|
||||
|
@ -788,7 +797,7 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
|||
mock_roles_data, mock_image_prepare,
|
||||
mock_generate_password, mock_rc_params,
|
||||
mock_check_service_vip_migr,
|
||||
mock_provision_networks):
|
||||
mock_provision_networks, mock_provision_virtual_ips):
|
||||
fixture = deployment.DeploymentWorkflowFixture()
|
||||
self.useFixture(fixture)
|
||||
clients = self.app.client_manager
|
||||
|
@ -865,6 +874,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
|||
output_dir=self.cmd.working_dir)
|
||||
mock_copy.assert_called_once()
|
||||
|
||||
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||
'_provision_virtual_ips', autospec=True)
|
||||
@mock.patch('tripleoclient.v1.overcloud_deploy.DeployOvercloud.'
|
||||
'_provision_networks', autospec=True)
|
||||
@mock.patch('tripleoclient.utils.build_stack_data', autospec=True)
|
||||
|
@ -917,7 +928,8 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
|||
mock_rc_params,
|
||||
mock_default_image_params,
|
||||
mock_stack_data,
|
||||
mock_provision_networks):
|
||||
mock_provision_networks,
|
||||
mock_provision_virtual_ips):
|
||||
fixture = deployment.DeploymentWorkflowFixture()
|
||||
self.useFixture(fixture)
|
||||
utils_fixture = deployment.UtilsFixture()
|
||||
|
@ -1553,6 +1565,47 @@ class TestDeployOvercloud(fakes.TestDeployOvercloud):
|
|||
verbosity=3,
|
||||
workdir=mock.ANY)
|
||||
|
||||
def test__provision_virtual_ips(self):
|
||||
networks_file_path = self.tmp_dir.join('networks.yaml')
|
||||
network_data = [
|
||||
{'name': 'Network', 'name_lower': 'network', 'subnets': {}}
|
||||
]
|
||||
with open(networks_file_path, 'w') as temp_file:
|
||||
yaml.safe_dump(network_data, temp_file)
|
||||
vips_file_path = self.tmp_dir.join('virtual_ips.yaml')
|
||||
vip_data = [
|
||||
{'network': 'internal_api', 'subnet': 'internal_api_subnet'}
|
||||
]
|
||||
with open(vips_file_path, 'w') as temp_file:
|
||||
yaml.safe_dump(vip_data, temp_file)
|
||||
|
||||
stack_name = 'overcloud'
|
||||
arglist = ['--stack', stack_name,
|
||||
'--vip-file', vips_file_path,
|
||||
'--networks-file', networks_file_path]
|
||||
verifylist = [('stack', stack_name),
|
||||
('vip_file', vips_file_path),
|
||||
('networks_file', networks_file_path)]
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
tht_root = self.tmp_dir.join('tht')
|
||||
env_dir = os.path.join(tht_root, 'user-environments')
|
||||
env_path = os.path.join(env_dir, 'virtual-ips-deployed.yaml')
|
||||
os.makedirs(env_dir)
|
||||
|
||||
result = self.cmd._provision_virtual_ips(parsed_args, tht_root)
|
||||
self.assertEqual([env_path], result)
|
||||
self.mock_playbook.assert_called_once_with(
|
||||
extra_vars={'stack_name': stack_name,
|
||||
'vip_data_path': vips_file_path,
|
||||
'vip_deployed_path': env_path,
|
||||
'overwrite': True},
|
||||
inventory='localhost,',
|
||||
playbook='cli-overcloud-network-vip-provision.yaml',
|
||||
playbook_dir='/usr/share/ansible/tripleo-playbooks',
|
||||
verbosity=3,
|
||||
workdir=mock.ANY)
|
||||
|
||||
def test_check_limit_warning(self):
|
||||
mock_warning = mock.MagicMock()
|
||||
mock_log = mock.MagicMock()
|
||||
|
|
|
@ -1704,6 +1704,12 @@ def get_networks_file_path(networks_file, tht_root):
|
|||
return os.path.abspath(networks_file)
|
||||
|
||||
|
||||
def get_vip_file_path(vip_file, tht_root):
|
||||
vip_file = vip_file or os.path.join(
|
||||
tht_root, constants.OVERCLOUD_VIP_FILE)
|
||||
return os.path.abspath(vip_file)
|
||||
|
||||
|
||||
def build_stack_data(clients, stack_name, template,
|
||||
files, env_files):
|
||||
orchestration_client = clients.orchestration
|
||||
|
@ -2789,3 +2795,21 @@ def copy_env_files(files_dict, tht_root):
|
|||
relocate_path = os.path.join(tht_root, "user-environments",
|
||||
os.path.basename(path))
|
||||
safe_write(relocate_path, files_dict[full_path])
|
||||
|
||||
|
||||
def is_network_data_v2(networks_file_path):
|
||||
"""Parse the network data, if any network have 'ip_subnet' or
|
||||
'ipv6_subnet' keys this is not a network-v2 format file.
|
||||
|
||||
:param networks_file_path:
|
||||
:return: boolean
|
||||
"""
|
||||
with open(networks_file_path, 'r') as f:
|
||||
network_data = yaml.safe_load(f.read())
|
||||
|
||||
if isinstance(network_data, list):
|
||||
for network in network_data:
|
||||
if 'ip_subnet' in network or 'ipv6_subnet' in network:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
|
|
@ -89,8 +89,8 @@ def _validate_args(parsed_args):
|
|||
|
||||
not_found = [x for x in [parsed_args.networks_file,
|
||||
parsed_args.plan_environment_file,
|
||||
parsed_args.plan_environment_file,
|
||||
parsed_args.answers_file]
|
||||
parsed_args.answers_file,
|
||||
parsed_args.vip_file]
|
||||
if x and not os.path.isfile(x)]
|
||||
|
||||
jinja2_envs = []
|
||||
|
@ -118,6 +118,16 @@ def _validate_args(parsed_args):
|
|||
"mean {}?".format(' -e '.join(jinja2_envs),
|
||||
' -e '.join(rewritten_paths)))
|
||||
|
||||
if parsed_args.vip_file:
|
||||
# Check vip_file only used with network data v2
|
||||
networks_file_path = utils.get_networks_file_path(
|
||||
parsed_args.networks_file, parsed_args.templates)
|
||||
if not utils.is_network_data_v2(networks_file_path):
|
||||
raise exceptions.CommandError(
|
||||
'The --vip-file option can only be used in combination with a '
|
||||
'network data v2 format networks file. The provided file {} '
|
||||
'is network data v1 format'.format(networks_file_path))
|
||||
|
||||
|
||||
class DeployOvercloud(command.Command):
|
||||
"""Deploy Overcloud"""
|
||||
|
@ -274,6 +284,8 @@ class DeployOvercloud(command.Command):
|
|||
|
||||
created_env_files.extend(
|
||||
self._provision_networks(parsed_args, new_tht_root))
|
||||
created_env_files.extend(
|
||||
self._provision_virtual_ips(parsed_args, new_tht_root))
|
||||
created_env_files.extend(
|
||||
self._provision_baremetal(parsed_args, new_tht_root))
|
||||
|
||||
|
@ -472,24 +484,13 @@ class DeployOvercloud(command.Command):
|
|||
}
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _is_network_data_v2(networks_file_path):
|
||||
with open(networks_file_path, 'r') as f:
|
||||
network_data = yaml.safe_load(f.read())
|
||||
for network in network_data:
|
||||
if 'ip_subnet' in network or 'ipv6_subnet' in network:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def _provision_networks(self, parsed_args, tht_root):
|
||||
# Parse the network data, if any network have 'ip_subnet' or
|
||||
# 'ipv6_subnet' keys this is not a network-v2 format file. In this
|
||||
# case do nothing.
|
||||
networks_file_path = utils.get_networks_file_path(
|
||||
parsed_args.networks_file, parsed_args.templates)
|
||||
|
||||
if not self._is_network_data_v2(networks_file_path):
|
||||
if not utils.is_network_data_v2(networks_file_path):
|
||||
return []
|
||||
|
||||
output_path = utils.build_user_env_path(
|
||||
|
@ -513,6 +514,37 @@ class DeployOvercloud(command.Command):
|
|||
|
||||
return [output_path]
|
||||
|
||||
def _provision_virtual_ips(self, parsed_args, tht_root):
|
||||
networks_file_path = utils.get_networks_file_path(
|
||||
parsed_args.networks_file, parsed_args.templates)
|
||||
if not utils.is_network_data_v2(networks_file_path):
|
||||
return []
|
||||
|
||||
vip_file_path = utils.get_vip_file_path(parsed_args.vip_file,
|
||||
parsed_args.templates)
|
||||
output_path = utils.build_user_env_path(
|
||||
'virtual-ips-deployed.yaml',
|
||||
tht_root)
|
||||
|
||||
extra_vars = {
|
||||
"stack_name": parsed_args.stack,
|
||||
"vip_data_path": vip_file_path,
|
||||
"vip_deployed_path": output_path,
|
||||
"overwrite": True,
|
||||
}
|
||||
|
||||
with utils.TempDirs() as tmp:
|
||||
utils.run_ansible_playbook(
|
||||
playbook='cli-overcloud-network-vip-provision.yaml',
|
||||
inventory='localhost,',
|
||||
workdir=tmp,
|
||||
playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS,
|
||||
verbosity=utils.playbook_verbosity(self=self),
|
||||
extra_vars=extra_vars,
|
||||
)
|
||||
|
||||
return [output_path]
|
||||
|
||||
def setup_ephemeral_heat(self, parsed_args):
|
||||
self.log.info("Using ephemeral heat for stack operation")
|
||||
restore_db = (parsed_args.setup_only or
|
||||
|
@ -613,6 +645,9 @@ class DeployOvercloud(command.Command):
|
|||
help=_('Networks file, overrides the default %s in the '
|
||||
'--templates directory') % constants.OVERCLOUD_NETWORKS_FILE
|
||||
)
|
||||
parser.add_argument(
|
||||
'--vip-file', dest='vip_file',
|
||||
help=_('Configuration file describing the network Virtual IPs.'))
|
||||
parser.add_argument(
|
||||
'--plan-environment-file', '-p',
|
||||
help=_('Plan Environment file for derived parameters.')
|
||||
|
|
|
@ -201,7 +201,7 @@ class OvercloudVirtualIPsProvision(command.Command):
|
|||
parser.add_argument('vip_file',
|
||||
metavar='<vip_data.yaml>',
|
||||
help=_('Configuration file describing the network '
|
||||
'deployment.'))
|
||||
'Virtual IPs.'))
|
||||
parser.add_argument('--stack', dest='stack', required=True,
|
||||
help=_('Name of heat stack '
|
||||
'(default=Env: OVERCLOUD_STACK_NAME)'),
|
||||
|
|
Loading…
Reference in New Issue