def test_configure(client): route = '/api/v1/configure' featured_methods = { 'GET': [200, 'application/json'], # Should return a 400 if validation has errors, # which this POST will return since the ssh_port is not an integer. 'POST': [400, 'application/json', '{"ssh_port": "asdf"}'], 'PUT': [405, 'text/plain'], 'DELETE': [405, 'text/plain'], 'HEAD': [405, 'text/plain'], 'TRACE': [405, 'text/plain'], 'CONNECT': [405, 'text/plain'], } for method, expected in featured_methods.items(): if method == 'POST': res = client.request(route, method=method, body=bytes(expected[2].encode('utf-8')), expect_errors=True) else: res = client.request(route, method=method, expect_errors=True) assert res.status_code == expected[0], '{}: {}'.format( method, expected) assert res.content_type == expected[1], '{}: {}'.format( method, expected) if expected[0] == 200: expected_config = Config('genconf/config.yaml').config # Add ui config parameters which are always set. # TODO(cmaloney): Make this unnecessary expected_config.update({'ssh_key': None, 'ip_detect_script': None}) assert res.json == expected_config
def test_configure(client): route = '/api/v1/configure' featured_methods = { 'GET': [200, 'application/json'], # Should return a 400 if validation has errors, # which this POST will return since the ssh_port is not an integer. 'POST': [400, 'application/json', '{"ssh_port": "asdf"}'], 'PUT': [405, 'text/plain'], 'DELETE': [405, 'text/plain'], 'HEAD': [405, 'text/plain'], 'TRACE': [405, 'text/plain'], 'CONNECT': [405, 'text/plain'], } for method, expected in featured_methods.items(): if method == 'POST': res = client.request(route, method=method, body=bytes(expected[2].encode('utf-8')), expect_errors=True) else: res = client.request(route, method=method, expect_errors=True) assert res.status_code == expected[0], '{}: {}'.format( method, expected) assert res.content_type == expected[1], '{}: {}'.format( method, expected) if expected[0] == 200: expected_config = Config('genconf/config.yaml').config # Add ui config parameters which are always set. # TODO(cmaloney): Make this unnecessary expected_config.update({'ssh_key': None, 'ip_detect_script': None}) assert res.json == expected_config
def create_config_from_post(post_data, config_path): """Returns error code and validation messages for only keys POSTed to the UI. :param config_path: path to config.yaml :type config_path: string | CONFIG_PATH (genconf/config.yaml) :param post_data: data from POST to UI :type post_data: dict | {} """ log.info("Updating config with POST data.") # Make sure this isn't passed ssh_key how the web installer used to, the web installer should # take care of it's wrapping / unwrapping. assert 'ssh_key' not in post_data assert 'ip_detect_script' not in post_data # Create a new configuration object, pass it the config.yaml path and POSTed dictionary. # Add in "hidden config" we don't present in the config.yaml, and then create a meta # validation dictionary from gen and ssh validation libs. # We do not use the already built methods for this since those are used to read the # coniguration off disk, here we need to validate the configuration overridees, and # return the key and message for the POSTed parameter. config = Config(config_path) config.update(post_data) validation_messages = config.do_validate(include_ssh=True) # TODO(cmaloney): Return all errors to the UI so it can display / decide how # it wants to log (new parameter might cause an error with an old set key) # Return only the keys the UI POSTed, do not write config to disk if # validation fails. post_validation_errors = { key: validation_messages[key] for key in validation_messages if key in post_data } # If validation is successful, write the data to disk, otherwise, if # they keys POSTed failed, do not write to disk. if post_validation_errors: log.error("POSTed configuration has errors, not writing to disk.") for key, value in post_validation_errors.items(): log.error('{}: {}'.format(key, value)) else: log.debug("Success! POSTed configuration looks good, writing to disk.") config.update(post_data) config.write_config() return post_validation_errors
def create_config_from_post(post_data, config_path): """Returns error code and validation messages for only keys POSTed to the UI. :param config_path: path to config.yaml :type config_path: string | CONFIG_PATH (genconf/config.yaml) :param post_data: data from POST to UI :type post_data: dict | {} """ log.info("Updating config with POST data.") # Make sure this isn't passed ssh_key how the web installer used to, the web installer should # take care of it's wrapping / unwrapping. assert 'ssh_key' not in post_data assert 'ip_detect_script' not in post_data # Create a new configuration object, pass it the config.yaml path and POSTed dictionary. # Add in "hidden config" we don't present in the config.yaml, and then create a meta # validation dictionary from gen and ssh validation libs. # We do not use the already built methods for this since those are used to read the # coniguration off disk, here we need to validate the configuration overridees, and # return the key and message for the POSTed parameter. config = Config(config_path) config.update(post_data) validation_messages = config.do_validate(include_ssh=True) # TODO(cmaloney): Return all errors to the UI so it can display / decide how # it wants to log (new parameter might cause an error with an old set key) # Return only the keys the UI POSTed, do not write config to disk if # validation fails. post_validation_errors = {key: validation_messages[key] for key in validation_messages if key in post_data} # If validation is successful, write the data to disk, otherwise, if # they keys POSTed failed, do not write to disk. if post_validation_errors: log.error("POSTed configuration has errors, not writing to disk.") for key, value in post_validation_errors.items(): log.error('{}: {}'.format(key, value)) else: log.debug("Success! POSTed configuration looks good, writing to disk.") config.update(post_data) config.write_config() return post_validation_errors