diff --git a/fuelclient/cli/actions/environment.py b/fuelclient/cli/actions/environment.py index 6054074b..549b591f 100644 --- a/fuelclient/cli/actions/environment.py +++ b/fuelclient/cli/actions/environment.py @@ -223,6 +223,6 @@ class EnvironmentAction(Action): "downloaded into {1}.yaml.".format(cluster.id, full_path)) elif params.upload: attributes = self.serializer.read_from_file(full_path) - cluster.update_attributes(attributes) + cluster.update_attributes(attributes, params.force) print("Attributes of cluster {0} " "uploaded from {1}.yaml".format(cluster.id, full_path)) diff --git a/fuelclient/cli/actions/settings.py b/fuelclient/cli/actions/settings.py index 142cc71a..bce06ee9 100644 --- a/fuelclient/cli/actions/settings.py +++ b/fuelclient/cli/actions/settings.py @@ -33,7 +33,8 @@ class SettingsAction(Action): Args.get_upload_arg("Save current changes in configuration."), required=True ), - Args.get_dir_arg("Directory with configuration data.") + Args.get_dir_arg("Directory with configuration data."), + Args.get_force_arg("Force settings upload.") ) self.flag_func_map = ( ("upload", self.upload), @@ -50,7 +51,7 @@ class SettingsAction(Action): directory=params.dir, serializer=self.serializer ) - env.set_settings_data(settings_data) + env.set_settings_data(settings_data, params.force) print("Settings configuration uploaded.") def default(self, params): diff --git a/fuelclient/client.py b/fuelclient/client.py index e3786c75..84f9e650 100644 --- a/fuelclient/client.py +++ b/fuelclient/client.py @@ -160,15 +160,18 @@ class Client(object): return resp.json() - def put_request(self, api, data): - """Make PUT request to specific API with some data.""" + def put_request(self, api, data, **params): + """Make PUT request to specific API with some data. + :param api: API endpoint (path) + :param data: Data send in request, will be serialized to JSON + :param params: Params of query string + """ url = self.api_root + api - data_json = json.dumps(data) - self.print_debug('PUT {0} data={1}'.format(url, data_json)) + resp = self.session.put(url, data=data_json, params=params) - resp = self.session.put(url, data=data_json) + self.print_debug('PUT {0} data={1}'.format(resp.url, data_json)) self._raise_for_status_with_info(resp) return resp.json() diff --git a/fuelclient/objects/environment.py b/fuelclient/objects/environment.py index 1fbf737b..9202e8b7 100644 --- a/fuelclient/objects/environment.py +++ b/fuelclient/objects/environment.py @@ -217,7 +217,7 @@ class Environment(BaseObject): @property def settings_url(self): - return "clusters/{0}/attributes".format(self.id) + return self.attributes_path.format(self.id) @property def default_settings_url(self): @@ -267,9 +267,14 @@ class Environment(BaseObject): return self.connection.put_request( self.network_url, data) - def set_settings_data(self, data): - return self.connection.put_request( - self.settings_url, data) + def set_settings_data(self, data, force=False): + if force: + result = self.connection.put_request( + self.settings_url, data, force=1) + else: + result = self.connection.put_request( + self.settings_url, data) + return result def set_vmware_settings_data(self, data): return self.connection.put_request( @@ -494,12 +499,16 @@ class Environment(BaseObject): return self.connection.put_request(url, data) def get_attributes(self): - url = self.attributes_path.format(self.id) - return self.connection.get_request(url) + return self.connection.get_request(self.settings_url) - def update_attributes(self, data): - url = self.attributes_path.format(self.id) - return self.connection.put_request(url, data) + def update_attributes(self, data, force=False): + if force: + result = self.connection.put_request( + self.settings_url, data, force=1) + else: + result = self.connection.put_request( + self.settings_url, data) + return result def get_deployment_tasks_graph(self, tasks, parents_for=None, remove=None): url = self.deployment_tasks_graph_path.format(self.id) diff --git a/fuelclient/tests/functional/v1/test_client.py b/fuelclient/tests/functional/v1/test_client.py index 8d150026..0f44b3d3 100644 --- a/fuelclient/tests/functional/v1/test_client.py +++ b/fuelclient/tests/functional/v1/test_client.py @@ -518,3 +518,39 @@ class TestDirectoryDoesntExistErrorMessages(base.BaseTestCase): "Directory '/foo/bar/baz' doesn't exist.\n", check_errors=False ) + + +class TestUploadSettings(base.BaseTestCase): + + create_env = "env create --name=test --release={0}" + add_node = "--env-id=1 node set --node 1 --role=controller" + deploy_changes = "deploy-changes --env 1" + cmd = "settings --env 1" + cmd_force = "settings --env 1 --force" + + def setUp(self): + super(TestUploadSettings, self).setUp() + self.load_data_to_nailgun_server() + release_id = self.get_first_deployable_release_id() + self.create_env = self.create_env.format(release_id) + self.run_cli_commands(( + self.create_env, + self.add_node, + self.download_command(self.cmd) + )) + + def test_upload_settings_before_deployment(self): + msg_success = "Settings configuration uploaded.\n" + self.check_for_stdout(self.upload_command(self.cmd), + msg_success) + + def test_upload_settings_after_deployment(self): + msg_success = "Settings configuration uploaded.\n" + msg_error = "couldn't be changed after or during deployment.)\n" + + self.run_cli_command(self.deploy_changes) + self.check_for_stderr(self.upload_command(self.cmd), + msg_error, + check_errors=False) + self.check_for_stdout(self.upload_command(self.cmd_force), + msg_success) diff --git a/fuelclient/tests/unit/common/test_settings.py b/fuelclient/tests/unit/common/test_settings.py index e123b811..64113206 100644 --- a/fuelclient/tests/unit/common/test_settings.py +++ b/fuelclient/tests/unit/common/test_settings.py @@ -78,6 +78,12 @@ class TestSettings(BaseSettings): 'fuel', 'settings', '--env', '1', '--upload'], test_url='/api/v1/clusters/1/attributes') + def test_upload_force_action(self): + self.check_upload_action( + test_command=[ + 'fuel', 'settings', '--env', '1', '--upload', '--force'], + test_url='/api/v1/clusters/1/attributes?force=1') + def test_default_action(self): self.check_default_action( test_command=[