3 ##############################################################################
4 # Copyright (c) 2017 Tim Rozet (trozet@redhat.com) and others.
6 # All rights reserved. This program and the accompanying materials
7 # are made available under the terms of the Apache License, Version 2.0
8 # which accompanies this distribution, and is available at
9 # http://www.apache.org/licenses/LICENSE-2.0
10 ##############################################################################
24 import apex.virtual.configure_vm as vm_lib
25 import apex.virtual.utils as virt_utils
26 import apex.builders.common_builder as c_builder
27 import apex.builders.overcloud_builder as oc_builder
28 import apex.builders.undercloud_builder as uc_builder
29 from apex import DeploySettings
30 from apex import Inventory
31 from apex import NetworkEnvironment
32 from apex import NetworkSettings
33 from apex.common import utils
34 from apex.common import constants
35 from apex.common import parsers
36 from apex.common.exceptions import ApexDeployException
37 from apex.deployment.tripleo import ApexDeployment
38 from apex.network import jumphost
39 from apex.network import network_data
40 from apex.undercloud import undercloud as uc_lib
41 from apex.overcloud import config as oc_cfg
42 from apex.overcloud import deploy as oc_deploy
44 APEX_TEMP_DIR = tempfile.mkdtemp(prefix='apex_tmp')
45 SDN_IMAGE = 'overcloud-full-opendaylight.qcow2'
48 def deploy_quickstart(args, deploy_settings_file, network_settings_file,
53 def validate_cross_settings(deploy_settings, net_settings, inventory):
55 Used to validate compatibility across settings file.
56 :param deploy_settings: parsed settings for deployment
57 :param net_settings: parsed settings for network
58 :param inventory: parsed inventory file
62 if deploy_settings['deploy_options']['dataplane'] != 'ovs' and 'tenant' \
63 not in net_settings.enabled_network_list:
64 raise ApexDeployException("Setting a DPDK based dataplane requires"
65 "a dedicated NIC for tenant network")
67 if 'odl_vpp_routing_node' in deploy_settings['deploy_options']:
68 if deploy_settings['deploy_options']['dataplane'] != 'fdio':
69 raise ApexDeployException("odl_vpp_routing_node should only be set"
70 "when dataplane is set to fdio")
71 if deploy_settings['deploy_options'].get('dvr') is True:
72 raise ApexDeployException("odl_vpp_routing_node should only be set"
73 "when dvr is not enabled")
75 # TODO(trozet): add more checks here like RAM for ODL, etc
76 # check if odl_vpp_netvirt is true and vpp is set
77 # Check if fdio and nosdn:
78 # tenant_nic_mapping_controller_members" ==
79 # "$tenant_nic_mapping_compute_members
82 def build_vms(inventory, network_settings,
83 template_dir='/usr/share/opnfv-apex'):
85 Creates VMs and configures vbmc and host
87 :param network_settings:
91 for idx, node in enumerate(inventory['nodes']):
92 name = 'baremetal{}'.format(idx)
93 volume = name + ".qcow2"
94 volume_path = os.path.join(constants.LIBVIRT_VOLUME_PATH, volume)
95 # TODO(trozet): add error checking
98 baremetal_interfaces=network_settings.enabled_network_list,
99 memory=node['memory'], cpus=node['cpu'],
101 template_dir=template_dir)
102 virt_utils.host_setup({name: node['pm_port']})
105 def create_deploy_parser():
106 deploy_parser = argparse.ArgumentParser()
107 deploy_parser.add_argument('--debug', action='store_true', default=False,
108 help="Turn on debug messages")
109 deploy_parser.add_argument('-l', '--log-file',
110 default='./apex_deploy.log',
111 dest='log_file', help="Log file to log to")
112 deploy_parser.add_argument('-d', '--deploy-settings',
113 dest='deploy_settings_file',
115 help='File which contains Apex deploy settings')
116 deploy_parser.add_argument('-n', '--network-settings',
117 dest='network_settings_file',
119 help='File which contains Apex network '
121 deploy_parser.add_argument('-i', '--inventory-file',
122 dest='inventory_file',
124 help='Inventory file which contains POD '
126 deploy_parser.add_argument('-e', '--environment-file',
128 default='opnfv-environment.yaml',
129 help='Provide alternate base env file located '
131 deploy_parser.add_argument('-v', '--virtual', action='store_true',
134 help='Enable virtual deployment')
135 deploy_parser.add_argument('--interactive', action='store_true',
137 help='Enable interactive deployment mode which '
138 'requires user to confirm steps of '
140 deploy_parser.add_argument('--virtual-computes',
141 dest='virt_compute_nodes',
144 help='Number of Virtual Compute nodes to create'
145 ' and use during deployment (defaults to 1'
146 ' for noha and 2 for ha)')
147 deploy_parser.add_argument('--virtual-cpus',
151 help='Number of CPUs to use per Overcloud VM in'
152 ' a virtual deployment (defaults to 4)')
153 deploy_parser.add_argument('--virtual-default-ram',
154 dest='virt_default_ram',
157 help='Amount of default RAM to use per '
158 'Overcloud VM in GB (defaults to 8).')
159 deploy_parser.add_argument('--virtual-compute-ram',
160 dest='virt_compute_ram',
163 help='Amount of RAM to use per Overcloud '
164 'Compute VM in GB (defaults to 8). '
165 'Overrides --virtual-default-ram arg for '
167 deploy_parser.add_argument('--deploy-dir',
168 default='/usr/share/opnfv-apex',
169 help='Directory to deploy from which contains '
170 'base config files for deployment')
171 deploy_parser.add_argument('--image-dir',
172 default='/var/opt/opnfv/images',
173 help='Directory which contains '
174 'base disk images for deployment')
175 deploy_parser.add_argument('--lib-dir',
176 default='/usr/share/opnfv-apex',
177 help='Directory path for apex ansible '
178 'and third party libs')
179 deploy_parser.add_argument('--quickstart', action='store_true',
181 help='Use tripleo-quickstart to deploy')
182 deploy_parser.add_argument('--upstream', action='store_true',
184 help='Force deployment to use upstream '
185 'artifacts. This option is now '
186 'deprecated and only upstream '
187 'deployments are supported.')
188 deploy_parser.add_argument('--no-fetch', action='store_true',
190 help='Ignore fetching latest upstream and '
191 'use what is in cache')
192 deploy_parser.add_argument('-p', '--patches',
193 default='/etc/opnfv-apex/common-patches.yaml',
195 help='File to include for common patches '
196 'which apply to all deployment scenarios')
200 def validate_deploy_args(args):
202 Validates arguments for deploy
207 logging.debug('Validating arguments for deployment')
208 if args.virtual and args.inventory_file is not None:
209 logging.error("Virtual enabled but inventory file also given")
210 raise ApexDeployException('You should not specify an inventory file '
211 'with virtual deployments')
213 args.inventory_file = os.path.join(APEX_TEMP_DIR,
214 'inventory-virt.yaml')
215 elif os.path.isfile(args.inventory_file) is False:
216 logging.error("Specified inventory file does not exist: {}".format(
217 args.inventory_file))
218 raise ApexDeployException('Specified inventory file does not exist')
220 for settings_file in (args.deploy_settings_file,
221 args.network_settings_file):
222 if os.path.isfile(settings_file) is False:
223 logging.error("Specified settings file does not "
224 "exist: {}".format(settings_file))
225 raise ApexDeployException('Specified settings file does not '
226 'exist: {}'.format(settings_file))
230 parser = create_deploy_parser()
231 args = parser.parse_args(sys.argv[1:])
232 # FIXME (trozet): this is only needed as a workaround for CI. Remove
234 if os.getenv('IMAGES', False):
235 args.image_dir = os.getenv('IMAGES')
237 log_level = logging.DEBUG
239 log_level = logging.INFO
240 os.makedirs(os.path.dirname(args.log_file), exist_ok=True)
241 formatter = '%(asctime)s %(levelname)s: %(message)s'
242 logging.basicConfig(filename=args.log_file,
244 datefmt='%m/%d/%Y %I:%M:%S %p',
246 console = logging.StreamHandler()
247 console.setLevel(log_level)
248 console.setFormatter(logging.Formatter(formatter))
249 logging.getLogger('').addHandler(console)
250 utils.install_ansible()
251 validate_deploy_args(args)
253 deploy_settings = DeploySettings(args.deploy_settings_file)
254 logging.info("Deploy settings are:\n {}".format(pprint.pformat(
256 net_settings = NetworkSettings(args.network_settings_file)
257 logging.info("Network settings are:\n {}".format(pprint.pformat(
259 os_version = deploy_settings['deploy_options']['os_version']
260 net_env_file = os.path.join(args.deploy_dir, constants.NET_ENV_FILE)
261 net_env = NetworkEnvironment(net_settings, net_env_file,
262 os_version=os_version)
263 net_env_target = os.path.join(APEX_TEMP_DIR, constants.NET_ENV_FILE)
264 utils.dump_yaml(dict(net_env), net_env_target)
266 # get global deploy params
267 ha_enabled = deploy_settings['global_params']['ha_enabled']
268 introspect = deploy_settings['global_params'].get('introspect', True)
271 if args.virt_compute_ram is None:
272 compute_ram = args.virt_default_ram
274 compute_ram = args.virt_compute_ram
275 if deploy_settings['deploy_options']['sdn_controller'] == \
276 'opendaylight' and args.virt_default_ram < 12:
278 logging.warning('RAM per controller is too low. OpenDaylight '
279 'requires at least 12GB per controller.')
280 logging.info('Increasing RAM per controller to 12GB')
281 elif args.virt_default_ram < 10:
283 logging.warning('RAM per controller is too low. nosdn '
284 'requires at least 10GB per controller.')
285 logging.info('Increasing RAM per controller to 10GB')
287 control_ram = args.virt_default_ram
288 if ha_enabled and args.virt_compute_nodes < 2:
289 logging.debug('HA enabled, bumping number of compute nodes to 2')
290 args.virt_compute_nodes = 2
291 virt_utils.generate_inventory(args.inventory_file, ha_enabled,
292 num_computes=args.virt_compute_nodes,
293 controller_ram=control_ram * 1024,
294 compute_ram=compute_ram * 1024,
297 inventory = Inventory(args.inventory_file, ha_enabled, args.virtual)
298 logging.info("Inventory is:\n {}".format(pprint.pformat(
301 validate_cross_settings(deploy_settings, net_settings, inventory)
302 ds_opts = deploy_settings['deploy_options']
304 deploy_settings_file = os.path.join(APEX_TEMP_DIR,
305 'apex_deploy_settings.yaml')
306 utils.dump_yaml(utils.dict_objects_to_str(deploy_settings),
307 deploy_settings_file)
308 logging.info("File created: {}".format(deploy_settings_file))
309 network_settings_file = os.path.join(APEX_TEMP_DIR,
310 'apex_network_settings.yaml')
311 utils.dump_yaml(utils.dict_objects_to_str(net_settings),
312 network_settings_file)
313 logging.info("File created: {}".format(network_settings_file))
314 deploy_quickstart(args, deploy_settings_file, network_settings_file,
317 deployment = ApexDeployment(deploy_settings, args.patches_file,
318 args.deploy_settings_file)
319 # TODO (trozet): add logic back from:
320 # Iedb75994d35b5dc1dd5d5ce1a57277c8f3729dfd (FDIO DVR)
322 'virsh_enabled_networks': net_settings.enabled_network_list
324 utils.run_ansible(ansible_args,
325 os.path.join(args.lib_dir, constants.ANSIBLE_PATH,
326 'deploy_dependencies.yml'))
328 if 'external' in net_settings.enabled_network_list:
331 # create all overcloud VMs
332 build_vms(inventory, net_settings, args.deploy_dir)
334 # Attach interfaces to jumphost for baremetal deployment
335 jump_networks = ['admin']
337 jump_networks.append('external')
338 for network in jump_networks:
339 if network == 'external':
340 # TODO(trozet): enable vlan secondary external networks
341 iface = net_settings['networks'][network][0][
342 'installer_vm']['members'][0]
344 iface = net_settings['networks'][network]['installer_vm'][
346 bridge = "br-{}".format(network)
347 jumphost.attach_interface_to_ovs(bridge, iface, network)
348 instackenv_json = os.path.join(APEX_TEMP_DIR, 'instackenv.json')
349 with open(instackenv_json, 'w') as fh:
350 json.dump(inventory, fh)
352 # Create and configure undercloud
354 root_pw = constants.DEBUG_OVERCLOUD_PW
358 if not args.upstream:
359 logging.warning("Using upstream is now required for Apex. "
360 "Forcing upstream to true")
361 if os_version == 'master':
364 branch = "stable/{}".format(os_version)
366 logging.info("Deploying with upstream artifacts for OpenStack "
367 "{}".format(os_version))
368 args.image_dir = os.path.join(args.image_dir, os_version)
369 upstream_url = constants.UPSTREAM_RDO.replace(
370 constants.DEFAULT_OS_VERSION, os_version)
371 upstream_targets = ['overcloud-full.tar', 'undercloud.qcow2']
372 utils.fetch_upstream_and_unpack(args.image_dir, upstream_url,
374 fetch=not args.no_fetch)
375 sdn_image = os.path.join(args.image_dir, 'overcloud-full.qcow2')
376 # copy undercloud so we don't taint upstream fetch
377 uc_image = os.path.join(args.image_dir, 'undercloud_mod.qcow2')
378 uc_fetch_img = os.path.join(args.image_dir, 'undercloud.qcow2')
379 shutil.copyfile(uc_fetch_img, uc_image)
380 # prep undercloud with required packages
381 uc_builder.add_upstream_packages(uc_image)
382 # add patches from upstream to undercloud and overcloud
383 logging.info('Adding patches to undercloud')
384 patches = deployment.determine_patches()
385 c_builder.add_upstream_patches(patches['undercloud'], uc_image,
386 APEX_TEMP_DIR, branch)
388 # Create/Start Undercloud VM
389 undercloud = uc_lib.Undercloud(args.image_dir,
392 external_network=uc_external,
393 image_name=os.path.basename(uc_image),
394 os_version=os_version)
396 undercloud_admin_ip = net_settings['networks'][
397 constants.ADMIN_NETWORK]['installer_vm']['ip']
399 if ds_opts['containers']:
400 tag = constants.DOCKER_TAG
404 # Generate nic templates
405 for role in 'compute', 'controller':
406 oc_cfg.create_nic_template(net_settings, deploy_settings, role,
407 args.deploy_dir, APEX_TEMP_DIR)
409 undercloud.configure(net_settings, deploy_settings,
410 os.path.join(args.lib_dir, constants.ANSIBLE_PATH,
411 'configure_undercloud.yml'),
412 APEX_TEMP_DIR, virtual_oc=args.virtual)
414 # Prepare overcloud-full.qcow2
415 logging.info("Preparing Overcloud for deployment...")
416 if os_version != 'ocata':
417 net_data_file = os.path.join(APEX_TEMP_DIR, 'network_data.yaml')
418 net_data = network_data.create_network_data(net_settings,
423 shutil.copyfile(os.path.join(args.deploy_dir, 'build_ovs_nsh.sh'),
424 os.path.join(APEX_TEMP_DIR, 'build_ovs_nsh.sh'))
426 # TODO(trozet): Either fix opnfv env or default to use upstream env
427 if args.env_file == 'opnfv-environment.yaml':
428 # Override the env_file if it is defaulted to opnfv
429 # opnfv env file will not work with upstream
430 args.env_file = 'upstream-environment.yaml'
431 opnfv_env = os.path.join(args.deploy_dir, args.env_file)
432 oc_deploy.prep_env(deploy_settings, net_settings, inventory,
433 opnfv_env, net_env_target, APEX_TEMP_DIR)
435 oc_deploy.LOOP_DEVICE_SIZE = "50G"
436 patched_containers = oc_deploy.prep_image(
437 deploy_settings, net_settings, sdn_image, APEX_TEMP_DIR,
438 root_pw=root_pw, docker_tag=tag, patches=patches['overcloud'])
440 oc_deploy.create_deploy_cmd(deploy_settings, net_settings, inventory,
441 APEX_TEMP_DIR, args.virtual,
442 os.path.basename(opnfv_env),
444 # Prepare undercloud with containers
445 docker_playbook = os.path.join(args.lib_dir, constants.ANSIBLE_PATH,
446 'prepare_overcloud_containers.yml')
447 if ds_opts['containers']:
448 logging.info("Preparing Undercloud with Docker containers")
449 sdn_env = oc_deploy.get_docker_sdn_files(ds_opts)
450 sdn_env_files = str()
451 for sdn_file in sdn_env:
452 sdn_env_files += " -e {}".format(sdn_file)
453 if patched_containers:
454 oc_builder.archive_docker_patches(APEX_TEMP_DIR)
455 container_vars = dict()
456 container_vars['apex_temp_dir'] = APEX_TEMP_DIR
457 container_vars['patched_docker_services'] = list(
459 container_vars['container_tag'] = constants.DOCKER_TAG
460 container_vars['stackrc'] = 'source /home/stack/stackrc'
461 container_vars['sdn'] = ds_opts['sdn_controller']
462 container_vars['undercloud_ip'] = undercloud_admin_ip
463 container_vars['os_version'] = os_version
464 container_vars['aarch64'] = platform.machine() == 'aarch64'
465 container_vars['sdn_env_file'] = sdn_env_files
467 utils.run_ansible(container_vars, docker_playbook,
468 host=undercloud.ip, user='stack',
469 tmp_dir=APEX_TEMP_DIR)
470 logging.info("Container preparation complete")
472 logging.error("Unable to complete container prep on "
474 os.remove(os.path.join(APEX_TEMP_DIR, 'overcloud-full.qcow2'))
477 deploy_playbook = os.path.join(args.lib_dir, constants.ANSIBLE_PATH,
478 'deploy_overcloud.yml')
479 virt_env = 'virtual-environment.yaml'
480 bm_env = 'baremetal-environment.yaml'
481 k8s_env = 'kubernetes-environment.yaml'
482 for p_env in virt_env, bm_env, k8s_env:
483 shutil.copyfile(os.path.join(args.deploy_dir, p_env),
484 os.path.join(APEX_TEMP_DIR, p_env))
486 # Start Overcloud Deployment
487 logging.info("Executing Overcloud Deployment...")
489 deploy_vars['virtual'] = args.virtual
490 deploy_vars['debug'] = args.debug
491 deploy_vars['aarch64'] = platform.machine() == 'aarch64'
492 deploy_vars['introspect'] = not (args.virtual or
493 deploy_vars['aarch64'] or
495 deploy_vars['dns_server_args'] = ''
496 deploy_vars['apex_temp_dir'] = APEX_TEMP_DIR
497 deploy_vars['apex_env_file'] = os.path.basename(opnfv_env)
498 deploy_vars['stackrc'] = 'source /home/stack/stackrc'
499 deploy_vars['overcloudrc'] = 'source /home/stack/overcloudrc'
500 deploy_vars['undercloud_ip'] = undercloud_admin_ip
501 deploy_vars['ha_enabled'] = ha_enabled
502 deploy_vars['os_version'] = os_version
503 deploy_vars['http_proxy'] = net_settings.get('http_proxy', '')
504 deploy_vars['https_proxy'] = net_settings.get('https_proxy', '')
505 deploy_vars['vim'] = ds_opts['vim']
506 for dns_server in net_settings['dns_servers']:
507 deploy_vars['dns_server_args'] += " --dns-nameserver {}".format(
510 utils.run_ansible(deploy_vars, deploy_playbook, host=undercloud.ip,
511 user='stack', tmp_dir=APEX_TEMP_DIR)
512 logging.info("Overcloud deployment complete")
514 logging.error("Deployment Failed. Please check deploy log as "
515 "well as mistral logs in "
516 "{}".format(os.path.join(APEX_TEMP_DIR,
517 'mistral_logs.tar.gz')))
520 os.remove(os.path.join(APEX_TEMP_DIR, 'overcloud-full.qcow2'))
523 logging.info("Executing post deploy configuration")
524 jumphost.configure_bridges(net_settings)
525 nova_output = os.path.join(APEX_TEMP_DIR, 'nova_output')
526 deploy_vars['overcloud_nodes'] = parsers.parse_nova_output(
528 deploy_vars['SSH_OPTIONS'] = '-o StrictHostKeyChecking=no -o ' \
529 'GlobalKnownHostsFile=/dev/null -o ' \
530 'UserKnownHostsFile=/dev/null -o ' \
532 deploy_vars['external_network_cmds'] = \
533 oc_deploy.external_network_cmds(net_settings, deploy_settings)
534 # TODO(trozet): just parse all ds_opts as deploy vars one time
535 deploy_vars['gluon'] = ds_opts['gluon']
536 deploy_vars['sdn'] = ds_opts['sdn_controller']
537 for dep_option in 'yardstick', 'dovetail', 'vsperf':
538 if dep_option in ds_opts:
539 deploy_vars[dep_option] = ds_opts[dep_option]
541 deploy_vars[dep_option] = False
542 deploy_vars['dataplane'] = ds_opts['dataplane']
543 overcloudrc = os.path.join(APEX_TEMP_DIR, 'overcloudrc')
544 if ds_opts['congress']:
545 deploy_vars['congress_datasources'] = \
546 oc_deploy.create_congress_cmds(overcloudrc)
547 deploy_vars['congress'] = True
549 deploy_vars['congress'] = False
550 deploy_vars['calipso'] = ds_opts.get('calipso', False)
551 deploy_vars['calipso_ip'] = undercloud_admin_ip
552 # overcloudrc.v3 removed and set as default in queens and later
553 if os_version == 'pike':
554 deploy_vars['overcloudrc_files'] = ['overcloudrc',
557 deploy_vars['overcloudrc_files'] = ['overcloudrc']
559 post_undercloud = os.path.join(args.lib_dir,
560 constants.ANSIBLE_PATH,
561 'post_deploy_undercloud.yml')
562 logging.info("Executing post deploy configuration undercloud "
565 utils.run_ansible(deploy_vars, post_undercloud,
566 host=undercloud.ip, user='stack',
567 tmp_dir=APEX_TEMP_DIR)
568 logging.info("Post Deploy Undercloud Configuration Complete")
570 logging.error("Post Deploy Undercloud Configuration failed. "
574 # Deploy kubernetes if enabled
575 # (TODO)zshi move handling of kubernetes deployment
576 # to its own deployment class
577 if deploy_vars['vim'] == 'k8s':
578 # clone kubespray repo
579 git.Repo.clone_from(constants.KUBESPRAY_URL,
580 os.path.join(APEX_TEMP_DIR, 'kubespray'))
582 os.path.join(APEX_TEMP_DIR, 'kubespray', 'inventory',
584 os.path.join(APEX_TEMP_DIR, 'kubespray', 'inventory',
586 k8s_node_inventory = {
606 for node, ip in deploy_vars['overcloud_nodes'].items():
607 k8s_node_inventory['all']['hosts'][node] = {
608 'ansible_become': True,
609 'ansible_ssh_host': ip,
610 'ansible_become_user': 'root',
613 if 'controller' in node:
614 k8s_node_inventory['all']['children']['k8s-cluster'][
615 'children']['kube-master']['hosts'][node] = None
616 k8s_node_inventory['all']['children']['etcd'][
617 'hosts'][node] = None
618 elif 'compute' in node:
619 k8s_node_inventory['all']['children']['k8s-cluster'][
620 'children']['kube-node']['hosts'][node] = None
622 kubespray_dir = os.path.join(APEX_TEMP_DIR, 'kubespray')
623 with open(os.path.join(kubespray_dir, 'inventory', 'apex',
624 'apex.yaml'), 'w') as invfile:
625 yaml.dump(k8s_node_inventory, invfile,
626 default_flow_style=False)
628 # Add kubespray ansible control variables in k8s_deploy_vars,
629 # example: 'kube_network_plugin': 'flannel'
630 k8s_deploy = os.path.join(kubespray_dir, 'cluster.yml')
631 k8s_deploy_inv_file = os.path.join(kubespray_dir, 'inventory',
634 k8s_remove_pkgs = os.path.join(args.lib_dir,
635 constants.ANSIBLE_PATH,
636 'k8s_remove_pkgs.yml')
638 logging.debug("Removing any existing overcloud docker "
640 utils.run_ansible(k8s_deploy_vars, k8s_remove_pkgs,
641 host=k8s_deploy_inv_file,
642 user='heat-admin', tmp_dir=APEX_TEMP_DIR)
643 logging.info("k8s Deploy Remove Existing Docker Related "
646 logging.error("k8s Deploy Remove Existing Docker Related "
647 "Packages failed. Please check log")
651 utils.run_ansible(k8s_deploy_vars, k8s_deploy,
652 host=k8s_deploy_inv_file,
653 user='heat-admin', tmp_dir=APEX_TEMP_DIR)
654 logging.info("k8s Deploy Overcloud Configuration Complete")
656 logging.error("k8s Deploy Overcloud Configuration failed."
660 # Post deploy overcloud node configuration
661 # TODO(trozet): just parse all ds_opts as deploy vars one time
662 deploy_vars['sfc'] = ds_opts['sfc']
663 deploy_vars['vpn'] = ds_opts['vpn']
664 deploy_vars['l2gw'] = ds_opts.get('l2gw')
665 deploy_vars['sriov'] = ds_opts.get('sriov')
666 deploy_vars['tacker'] = ds_opts.get('tacker')
667 # TODO(trozet): pull all logs and store in tmp dir in overcloud
669 post_overcloud = os.path.join(args.lib_dir, constants.ANSIBLE_PATH,
670 'post_deploy_overcloud.yml')
671 # Run per overcloud node
672 for node, ip in deploy_vars['overcloud_nodes'].items():
673 logging.info("Executing Post deploy overcloud playbook on "
674 "node {}".format(node))
676 utils.run_ansible(deploy_vars, post_overcloud, host=ip,
677 user='heat-admin', tmp_dir=APEX_TEMP_DIR)
678 logging.info("Post Deploy Overcloud Configuration Complete "
679 "for node {}".format(node))
681 logging.error("Post Deploy Overcloud Configuration failed "
682 "for node {}. Please check log".format(node))
684 logging.info("Apex deployment complete")
685 logging.info("Undercloud IP: {}, please connect by doing "
686 "'opnfv-util undercloud'".format(undercloud.ip))
687 # TODO(trozet): add logging here showing controller VIP and horizon url
690 if __name__ == '__main__':