Adds ability to force update environment attributes

In order to upgrade deployed cluster that is in operational state
without re-provisioning it, we need a possibility to forcefully
update cluster attributes (aka cluster/environment settings).

Optional flag '--force' is added to the commands below:
fuel settings --env <env_id> --upload --force
fuel env --env <env_id> --attributes --upload --force

This flag is handled by API here:
clusters/<id>/attributes/?force=1

Partial-Bug: 1540434
Change-Id: I870445a158d1497a823eda7fdd920e32478f9f79
Depends-On: Ic6541f8e227251ae992a3005d543a8e1e42665f3
This commit is contained in:
Vitalii Myhal 2016-02-03 11:26:36 -06:00
parent 1ef7442734
commit 828a664114
6 changed files with 72 additions and 17 deletions

View File

@ -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))

View File

@ -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):

View File

@ -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()

View File

@ -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)

View File

@ -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)

View File

@ -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=[