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_good_create_config_from_post(tmpdir): """ Test that it creates the config """ # Create a temp config workspace = tmpdir.strpath temp_config_path = workspace + '/config.yaml' temp_ip_detect_path = workspace + '/ip-detect' f = open(temp_ip_detect_path, "w") f.write("#/bin/bash foo") good_post_data = { "agent_list": ["10.0.0.2"], "master_list": ["10.0.0.1"], "cluster_name": "Good Test", "resolvers": ["4.4.4.4"], "ip_detect_filename": temp_ip_detect_path } expected_good_messages = {} err, msg = backend.create_config_from_post( post_data=good_post_data, config_path=temp_config_path) assert err is False assert msg == expected_good_messages
def test_good_create_config_from_post(tmpdir): """ Test that it creates the config """ # Create a temp config workspace = tmpdir.strpath temp_config_path = workspace + '/config.yaml' make_default_config_if_needed(temp_config_path) temp_ip_detect_path = workspace + '/ip-detect' f = open(temp_ip_detect_path, "w") f.write("#/bin/bash foo") good_post_data = { "agent_list": ["10.0.0.2"], "master_list": ["10.0.0.1"], "cluster_name": "Good Test", "resolvers": ["4.4.4.4"], "ip_detect_filename": temp_ip_detect_path } expected_good_messages = {} create_fake_build_artifacts(tmpdir) with tmpdir.as_cwd(): messages = backend.create_config_from_post( post_data=good_post_data, config_path=temp_config_path) assert messages == expected_good_messages
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_accept_overrides_for_undefined_config_params(tmpdir): temp_config_path = tmpdir.strpath + '/config.yaml' param = ('fake_test_param_name', 'fake_test_param_value') make_default_config_if_needed(temp_config_path) messages = backend.create_config_from_post( post_data=dict([param]), config_path=temp_config_path) assert not messages, "unexpected validation error: {}".format(messages) assert Config(config_path=temp_config_path)[param[0]] == param[1]
def dispatch(args): """ Dispatches the selected mode based on command line args. """ if args.action == 'set-superuser-password': password_hash = do_hash_password(args.password) messages = backend.create_config_from_post( {'superuser_password_hash': password_hash}, dcos_installer.constants.CONFIG_PATH) if messages: log.error("Unable to save password: {}".format(messages)) sys.exit(1) sys.exit(0) if args.action == 'hash-password': # TODO(cmaloney): Import a function from the auth stuff to do the hashing and guarantee it # always matches byte_str = do_hash_password(args.password).encode('ascii') sys.stdout.buffer.write(byte_str + b'\n') sys.exit(0) if args.action == 'generate-node-upgrade-script': status = backend.generate_node_upgrade_script(args.installed_cluster_version) sys.exit(status) if args.action in dispatch_dict_simple: action = dispatch_dict_simple[args.action] if action[1] is not None: print_header(action[1]) sys.exit(action[0](args)) # Dispatches CLI options which are installer actions ran through AIO event loop if args.action in dispatch_dict_aio: action = dispatch_dict_aio[args.action] if do_validate_config(args) != 0: sys.exit(1) if action[1] is not None: print_header(action[1]) errors = run_loop(action[0], args) if not args.cli_telemetry_disabled: installer_analytics.send( action=args.action, install_method="cli", num_errors=errors, ) sys.exit(1 if errors > 0 else 0) print("Internal Error: No known way to dispatch {}".format(args.action)) sys.exit(1)
def configure(request): """Return /api/v1/configure :param request: a web requeest object. :type request: request | None """ if request.method == 'POST': new_config = yield from request.json() # Save ssh_key, ip_detect as needed # TODO(cmaloney): make ssh_key derive from ssh_key_path so we can just set ssh_key and skip all this. new_config = extract_external(new_config, 'ssh_key', 'ssh_key_path', SSH_KEY_PATH, 0o600) # TODO(cmaloney): change this to ip_detect_contents removing the need for the remapping. new_config = extract_external(new_config, 'ip_detect_script', 'ip_detect_path', IP_DETECT_PATH, 0o644) log.info('POST to configure: {}'.format(new_config)) messages = backend.create_config_from_post(new_config, CONFIG_PATH) # Map back to DC/OS UI configuration parameters. # TODO(cmaloney): Remove need to remap validation keys. The remapping is making things show up # under the key of the user config chunk that caused them rather than their particular key so # num_masters validation for instance shows up under master_list where the user would expect it. if "ssh_key_path" in messages: messages["ssh_key"] = messages["ssh_key_path"] if "ip_detect_contents" in messages: messages['ip_detect_path'] = messages['ip_detect_contents'] if 'num_masters' in messages: messages['master_list'] = messages['num_masters'] resp = web.json_response({}, status=200) if messages: resp = web.json_response(messages, status=400) return resp elif request.method == 'GET': config = Config(CONFIG_PATH).config # TODO(cmaloney): should exclude the value entirely if the file doesn't exist. config['ssh_key'] = try_read_file(SSH_KEY_PATH) config['ip_detect_script'] = try_read_file(IP_DETECT_PATH) resp = web.json_response(config) resp.headers['Content-Type'] = 'application/json' return resp
def test_bad_create_config_from_post(tmpdir): # Create a temp config workspace = tmpdir.strpath temp_config_path = workspace + '/config.yaml' bad_post_data = { "agent_list": "foo", "master_list": ["foo"], } expected_bad_messages = { "agent_list": 'agent_list must be a list', "master_list": 'Only IPv4 values are allowed. The following are invalid IPv4 addresses: foo', } err, msg = backend.create_config_from_post( post_data=bad_post_data, config_path=temp_config_path) assert err is True assert msg == expected_bad_messages
def dispatch(args): """ Dispatches the selected mode based on command line args. """ if args.action == 'set-superuser-password': password_hash = do_hash_password(args.password) messages = backend.create_config_from_post( {'superuser_password_hash': password_hash}, dcos_installer.constants.CONFIG_PATH) if messages: log.error("Unable to save password: {}".format(messages)) sys.exit(1) sys.exit(0) if args.action == 'hash-password': # TODO(cmaloney): Import a function from the auth stuff to do the hashing and guarantee it # always matches byte_str = do_hash_password(args.password).encode('ascii') sys.stdout.buffer.write(byte_str + b'\n') sys.exit(0) if args.action in dispatch_dict_simple: action = dispatch_dict_simple[args.action] if action[1] is not None: print_header(action[1]) sys.exit(action[0](args)) # Dispatches CLI options which are installer actions ran through AIO event loop if args.action in dispatch_dict_aio: action = dispatch_dict_aio[args.action] if do_validate_config(args) != 0: sys.exit(1) if action[1] is not None: print_header(action[1]) errors = run_loop(action[0], args) if not args.cli_telemetry_disabled: installer_analytics.send( action=args.action, install_method="cli", num_errors=errors, ) sys.exit(1 if errors > 0 else 0) print("Internal Error: No known way to dispatch {}".format(args.action)) sys.exit(1)
def test_bad_create_config_from_post(tmpdir): # Create a temp config workspace = tmpdir.strpath temp_config_path = workspace + '/config.yaml' bad_post_data = { "agent_list": "foo", "master_list": ["foo"], } expected_bad_messages = { "agent_list": 'agent_list must be a list', "master_list": 'Only IPv4 values are allowed. The following are invalid IPv4 addresses: foo', } err, msg = backend.create_config_from_post(post_data=bad_post_data, config_path=temp_config_path) assert err is True assert msg == expected_bad_messages
def test_bad_create_config_from_post(tmpdir): # Create a temp config workspace = tmpdir.strpath temp_config_path = workspace + '/config.yaml' make_default_config_if_needed(temp_config_path) bad_post_data = { "agent_list": "foo", "master_list": ["foo"], } expected_bad_messages = { "agent_list": "Must be a JSON formatted list, but couldn't be parsed the given value `foo` as " "one because of: Expecting value: line 1 column 1 (char 0)", "master_list": 'Invalid IPv4 addresses in list: foo', } messages = backend.create_config_from_post( post_data=bad_post_data, config_path=temp_config_path) assert messages == expected_bad_messages
def dispatch(args): """ Dispatches the selected mode based on command line args. """ if getattr(args, 'set_superuser_password'): assert len(args.set_superuser_password) == 1 password_hash = do_hash_password(args.set_superuser_password[0]) err, messages = backend.create_config_from_post({'superuser_password_hash': password_hash}) if err: log.error("Unable to save password: {}".format(messages)) sys.exit(1) sys.exit(0) if getattr(args, 'hash_password'): assert len(args.hash_password) == 1 # TODO(cmaloney): Import a function from the auth stuff to do the hashing and guarantee it # always matches byte_str = do_hash_password(args.hash_password[0]).encode('ascii') sys.stdout.buffer.write(byte_str + b'\n') sys.exit(0) if args.action in dispatch_dict_simple: action = dispatch_dict_simple[args.action] if action[1] is not None: print_header(action[1]) sys.exit(action[0](args)) # Dispatches CLI options which are installer actions ran through AIO event loop if args.action in dispatch_dict_aio: action = dispatch_dict_aio[args.action] if do_validate_config(args) != 0: sys.exit(1) if action[1] is not None: print_header(action[1]) errors = run_loop(action[0], args) if not args.cli_telemetry_disabled: installer_analytics.send( action=args.action, install_method="cli", num_errors=errors, ) sys.exit(1 if errors > 0 else 0) print("Internal Error: No known way to dispatch {}".format(args.action)) sys.exit(1)
def configure(request): """Return /api/v1/configure :param request: a web requeest object. :type request: request | None """ if request.method == 'POST': new_config = yield from request.json() log.info('POST to configure: {}'.format(new_config)) validation_err, messages = backend.create_config_from_post(new_config) resp = web.json_response({}, status=200) if validation_err: resp = web.json_response(messages, status=400) return resp elif request.method == 'GET': config = backend.get_ui_config() resp = web.json_response(config) resp.headers['Content-Type'] = 'application/json' return resp