def test_set_superuser_password(tmpdir): """Test that --set-superuser-hash works""" with tmpdir.as_cwd(): tmpdir.join('genconf').ensure(dir=True) # check config.yaml doesn't have the password assert 'superuser_password_hash' not in backend.get_config('genconf/config.yaml') # Set the password subprocess.check_call(['dcos_installer', '--set-superuser-password', 'foo'], cwd=str(tmpdir)) # Check that config.yaml has the password set config = backend.get_config('genconf/config.yaml') assert passlib.hash.sha512_crypt.verify('foo', config['superuser_password_hash'])
def run_loop(action, options): assert callable(action) loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) print_header('START {}'.format(action.__name__)) try: config = backend.get_config() cli_delegate = CliDelegate() result = loop.run_until_complete(action(config, block=True, async_delegate=cli_delegate, options=options)) pp = PrettyPrint(result) pp.stage_name = action.__name__ pp.beautify('print_data') finally: loop.close() exitcode = 0 for host_result in result: for command_result in host_result: for host, process_result in command_result.items(): if process_result['returncode'] != 0: exitcode += 1 print_header('ACTION {} COMPLETE'.format(action.__name__)) pp.print_summary() return exitcode
def send(self, action, install_method, num_errors): """Sends analytics track data to segmentIO. variant: string | open or enterprise action: string | preflight, deploy, or postflight install_method: string | gui, cli or advanced """ analytics.write_key = "51ybGTeFEFU1xo6u10XMDrr6kATFyRyh" # We set customer key from config to avoid loading the config during class init customer_key = backend.get_config().get("customer_key", None) analytics.track(user_id=customer_key, anonymous_id=self.uuid, event=action, properties={ "provider": "onprem", "source": "installer", "variant": os.environ["BOOTSTRAP_VARIANT"], "install_id": self.uuid, "bootstrap_id": os.environ["BOOTSTRAP_ID"], "install_method": install_method, "stage": action, "errors": num_errors, "customerKey": customer_key, }) analytics.flush()
def run_loop(action, options): assert callable(action) loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) print_header('START {}'.format(action.__name__)) try: config = backend.get_config() cli_delegate = CliDelegate() result = loop.run_until_complete( action(config, block=True, async_delegate=cli_delegate, options=options)) pp = PrettyPrint(result) pp.stage_name = action.__name__ pp.beautify('print_data') finally: loop.close() exitcode = 0 for host_result in result: for command_result in host_result: for host, process_result in command_result.items(): if process_result['returncode'] != 0: exitcode += 1 print_header('ACTION {} COMPLETE'.format(action.__name__)) pp.print_summary() return exitcode
def test_accept_overrides_for_undefined_config_params(tmpdir): temp_config_path = tmpdir.strpath + '/config.yaml' param = ('fake_test_param_name', 'fake_test_param_value') backend.create_config_from_post( post_data=dict([param]), config_path=temp_config_path) assert backend.get_config(config_path=temp_config_path)[param[0]] == param[1]
def test_accept_overrides_for_undefined_config_params(tmpdir): temp_config_path = tmpdir.strpath + '/config.yaml' param = ('fake_test_param_name', 'fake_test_param_value') backend.create_config_from_post(post_data=dict([param]), config_path=temp_config_path) assert backend.get_config( config_path=temp_config_path)[param[0]] == param[1]
def test_accept_overrides_for_undefined_config_params(tmpdir): temp_config_path = tmpdir.strpath + '/config.yaml' param = ('fake_test_param_name', 'fake_test_param_value') validation_err, data = backend.create_config_from_post( post_data=dict([param]), config_path=temp_config_path) assert not validation_err, "unexpected validation error: {}".format(data) assert backend.get_config(config_path=temp_config_path)[param[0]] == param[1]
def test_set_superuser_password(tmpdir): """Test that --set-superuser-hash works""" with tmpdir.as_cwd(): tmpdir.join('genconf').ensure(dir=True) # check config.yaml doesn't have the password assert 'superuser_password_hash' not in backend.get_config( 'genconf/config.yaml') # Set the password subprocess.check_call( ['dcos_installer', '--set-superuser-password', 'foo'], cwd=str(tmpdir)) # Check that config.yaml has the password set config = backend.get_config('genconf/config.yaml') assert passlib.hash.sha512_crypt.verify( 'foo', config['superuser_password_hash'])
def test_accept_overrides_for_undefined_config_params(tmpdir): temp_config_path = tmpdir.strpath + '/config.yaml' param = ('fake_test_param_name', 'fake_test_param_value') validation_err, data = backend.create_config_from_post( post_data=dict([param]), config_path=temp_config_path) assert not validation_err, "unexpected validation error: {}".format(data) assert backend.get_config( config_path=temp_config_path)[param[0]] == param[1]
def test_get_config(tmpdir): # Create a temp config workspace = tmpdir.strpath temp_config_path = workspace + '/config.yaml' expected_file = """ { "cluster_name": "DC/OS", "master_discovery": "static", "exhibitor_storage_backend": "static", "resolvers": ["8.8.8.8","8.8.4.4"], "ssh_port": 22, "process_timeout": 10000, "bootstrap_url": "file:///opt/dcos_install_tmp" } """ config = backend.get_config(config_path=temp_config_path) expected_config = json.loads(expected_file) assert expected_config == config
def test_get_config(tmpdir): # Create a temp config workspace = tmpdir.strpath temp_config_path = workspace + '/config.yaml' expected_file = """ { "cluster_name": "DCOS", "master_discovery": "static", "exhibitor_storage_backend": "static", "resolvers": ["8.8.8.8","8.8.4.4"], "ssh_port": 22, "process_timeout": 10000, "bootstrap_url": "file:///opt/dcos_install_tmp" } """ config = backend.get_config(config_path=temp_config_path) expected_config = json.loads(expected_file) assert expected_config == config
def action_action_name(request): """Return /action/<action_name> :param request: a web requeest object. :type request: request | None """ action_name = request.match_info['action_name'] # Update the global action json_state = read_json_state(action_name) app['current_action'] = action_name if request.method == 'GET': log.info('GET {}'.format(action_name)) if json_state: return web.json_response(json_state) return web.json_response({}) elif request.method == 'POST': log.info('POST {}'.format(action_name)) action = action_map.get(action_name) # If the action name is preflight, attempt to run configuration # generation. If genconf fails, present the UI with a usable error # for the end-user if action_name == 'preflight': try: print_header("GENERATING CONFIGURATION") backend.do_configure() except: genconf_failure = { "errors": "Configuration generation failed, please see command line for details" } return web.json_response(genconf_failure, status=400) params = yield from request.post() if json_state: if action_name == 'deploy' and 'retry' in params: if 'hosts' in json_state: failed_hosts = [] for deploy_host, deploy_params in json_state['hosts'].items(): if deploy_params['host_status'] != 'success': failed_hosts.append(Node(deploy_host, tags=deploy_params['tags'])) log.debug('failed hosts: {}'.format(failed_hosts)) if failed_hosts: yield from asyncio.async( action( backend.get_config(), state_json_dir=STATE_DIR, hosts=failed_hosts, try_remove_stale_dcos=True, **params)) return web.json_response({ 'status': 'retried', 'details': sorted(['{}:{}'.format(node.ip, node.port) for node in failed_hosts]) }) if action_name not in remove_on_done: return web.json_response({'status': '{} was already executed, skipping'.format(action_name)}) running = False for host, attributes in json_state['hosts'].items(): if attributes['host_status'].lower() == 'running': running = True log.debug('is action running: {}'.format(running)) if running: return web.json_response({'status': '{} is running, skipping'.format(action_name)}) else: unlink_state_file(action_name) yield from asyncio.async(action(backend.get_config(), state_json_dir=STATE_DIR, options=options, **params)) return web.json_response({'status': '{} started'.format(action_name)})
def get_new_analytics(config_path=CONFIG_PATH): return InstallerAnalytics(backend.get_config(config_path))
def action_action_name(request): """Return /action/<action_name> :param request: a web requeest object. :type request: request | None """ global current_action action_name = request.match_info['action_name'] # Update the global action json_state = read_json_state(action_name) current_action = action_name if request.method == 'GET': log.info('GET {}'.format(action_name)) if json_state: return web.json_response(json_state) return web.json_response({}) elif request.method == 'POST': log.info('POST {}'.format(action_name)) action = action_map.get(action_name) # If the action name is preflight, attempt to run configuration # generation. If genconf fails, present the UI with a usable error # for the end-user if action_name == 'preflight': try: log.warning("GENERATING CONFIGURATION") backend.do_configure() except: genconf_failure = { "errors": "Configuration generation failed, please see command line for details" } return web.json_response(genconf_failure, status=400) params = yield from request.post() if json_state: if action_name == 'deploy' and 'retry' in params: if 'hosts' in json_state: failed_hosts = [] for deploy_host, deploy_params in json_state['hosts'].items(): if deploy_params['host_status'] != 'success': failed_hosts.append(Node(deploy_host, tags=deploy_params['tags'])) log.debug('failed hosts: {}'.format(failed_hosts)) if failed_hosts: yield from asyncio.async( action( backend.get_config(), state_json_dir=STATE_DIR, hosts=failed_hosts, try_remove_stale_dcos=True, **params)) return web.json_response({ 'status': 'retried', 'details': sorted(['{}:{}'.format(node.ip, node.port) for node in failed_hosts]) }) if action_name not in remove_on_done: return web.json_response({'status': '{} was already executed, skipping'.format(action_name)}) running = False for host, attributes in json_state['hosts'].items(): if attributes['host_status'].lower() == 'running': running = True log.debug('is action running: {}'.format(running)) if running: return web.json_response({'status': '{} is running, skipping'.format(action_name)}) else: unlink_state_file(action_name) yield from asyncio.async(action(backend.get_config(), state_json_dir=STATE_DIR, options=options, **params)) return web.json_response({'status': '{} started'.format(action_name)})