Reuse existing disable_rollback in stack-update
This patch makes `stack-update` command to change the `disable_rollback` bit of the stack IF AND ONLY IF explicitly requested on CLI. In order to facilitate this, `--rollback` CLI argument to `stack-update` is added (accepting values from 1, on, true, t, 0, off, false, f and similar) to explicitly set disable_rollback property of the stack on stack update. If this argument is omitted, the value of disable_rollback of the stack to be updated will be implicitly used by heat engine. The boolean switch '--enable-rollback' is deprecated with appropriate message (although the default behavior is effectively changed). Change-Id: I235198ec04bfb192fcbfa4e2e3e618b64c99d3df Closes-Bug: #1324366
This commit is contained in:
parent
95841b5633
commit
847a8fd566
|
@ -11,6 +11,7 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import six
|
||||
|
@ -1085,6 +1086,7 @@ class ShellTestUserPass(ShellBase):
|
|||
'stack-update teststack2/2 '
|
||||
'--template-file=%s '
|
||||
'--timeout 123 '
|
||||
'--rollback off '
|
||||
'--parameters="InstanceType=m1.large;DBUsername=wp;'
|
||||
'DBPassword=verybadpassword;KeyName=heat_key;'
|
||||
'LinuxDistribution=F17"' % template_file)
|
||||
|
@ -1228,8 +1230,17 @@ class ShellTestUserPass(ShellBase):
|
|||
self.shell_error('stack-adopt teststack ', failed_msg)
|
||||
|
||||
@httpretty.activate
|
||||
def test_stack_update(self):
|
||||
def test_stack_update_enable_rollback(self):
|
||||
self.register_keystone_auth_fixture()
|
||||
template_file = os.path.join(TEST_VAR_DIR, 'minimal.template')
|
||||
with open(template_file) as f:
|
||||
template_data = json.load(f)
|
||||
expected_data = {'files': {},
|
||||
'environment': {},
|
||||
'template': template_data,
|
||||
'disable_rollback': False,
|
||||
'parameters': mox.IgnoreArg()
|
||||
}
|
||||
resp = fakes.FakeHTTPResponse(
|
||||
202,
|
||||
'Accepted',
|
||||
|
@ -1237,18 +1248,16 @@ class ShellTestUserPass(ShellBase):
|
|||
'The request is accepted for processing.')
|
||||
http.HTTPClient.json_request(
|
||||
'PUT', '/stacks/teststack2/2',
|
||||
data=mox.IgnoreArg(),
|
||||
data=expected_data,
|
||||
headers={'X-Auth-Key': 'password', 'X-Auth-User': 'username'}
|
||||
).AndReturn((resp, None))
|
||||
fakes.script_heat_list()
|
||||
|
||||
self.m.ReplayAll()
|
||||
|
||||
template_file = os.path.join(TEST_VAR_DIR, 'minimal.template')
|
||||
update_text = self.shell(
|
||||
'stack-update teststack2/2 '
|
||||
'--rollback on '
|
||||
'--template-file=%s '
|
||||
'--enable-rollback '
|
||||
'--parameters="InstanceType=m1.large;DBUsername=wp;'
|
||||
'DBPassword=verybadpassword;KeyName=heat_key;'
|
||||
'LinuxDistribution=F17"' % template_file)
|
||||
|
@ -1262,6 +1271,99 @@ class ShellTestUserPass(ShellBase):
|
|||
for r in required:
|
||||
self.assertRegexpMatches(update_text, r)
|
||||
|
||||
@httpretty.activate
|
||||
def test_stack_update_disable_rollback(self):
|
||||
self.register_keystone_auth_fixture()
|
||||
template_file = os.path.join(TEST_VAR_DIR, 'minimal.template')
|
||||
with open(template_file) as f:
|
||||
template_data = json.load(f)
|
||||
expected_data = {'files': {},
|
||||
'environment': {},
|
||||
'template': template_data,
|
||||
'disable_rollback': True,
|
||||
'parameters': mox.IgnoreArg()
|
||||
}
|
||||
resp = fakes.FakeHTTPResponse(
|
||||
202,
|
||||
'Accepted',
|
||||
{},
|
||||
'The request is accepted for processing.')
|
||||
http.HTTPClient.json_request(
|
||||
'PUT', '/stacks/teststack2',
|
||||
data=expected_data,
|
||||
headers={'X-Auth-Key': 'password', 'X-Auth-User': 'username'}
|
||||
).AndReturn((resp, None))
|
||||
fakes.script_heat_list()
|
||||
self.m.ReplayAll()
|
||||
|
||||
update_text = self.shell(
|
||||
'stack-update teststack2 '
|
||||
'--template-file=%s '
|
||||
'--rollback off '
|
||||
'--parameters="InstanceType=m1.large;DBUsername=wp;'
|
||||
'DBPassword=verybadpassword;KeyName=heat_key;'
|
||||
'LinuxDistribution=F17"' % template_file)
|
||||
|
||||
required = [
|
||||
'stack_name',
|
||||
'id',
|
||||
'teststack2',
|
||||
'1'
|
||||
]
|
||||
for r in required:
|
||||
self.assertRegexpMatches(update_text, r)
|
||||
|
||||
@httpretty.activate
|
||||
def test_stack_update_fault_rollback_value(self):
|
||||
self.register_keystone_auth_fixture()
|
||||
self.m.ReplayAll()
|
||||
template_file = os.path.join(TEST_VAR_DIR, 'minimal.template')
|
||||
self.shell_error('stack-update teststack2/2 '
|
||||
'--rollback Foo '
|
||||
'--template-file=%s' % template_file,
|
||||
"Unrecognized value 'Foo', acceptable values are:"
|
||||
)
|
||||
|
||||
@httpretty.activate
|
||||
def test_stack_update_rollback_default(self):
|
||||
self.register_keystone_auth_fixture()
|
||||
template_file = os.path.join(TEST_VAR_DIR, 'minimal.template')
|
||||
with open(template_file) as f:
|
||||
template_data = json.load(f)
|
||||
expected_data = {'files': {},
|
||||
'environment': {},
|
||||
'template': template_data,
|
||||
'parameters': mox.IgnoreArg()
|
||||
}
|
||||
resp_update = fakes.FakeHTTPResponse(
|
||||
202,
|
||||
'Accepted',
|
||||
{},
|
||||
'The request is accepted for processing.')
|
||||
http.HTTPClient.json_request(
|
||||
'PUT', '/stacks/teststack2',
|
||||
data=expected_data,
|
||||
headers={'X-Auth-Key': 'password', 'X-Auth-User': 'username'}
|
||||
).AndReturn((resp_update, None))
|
||||
fakes.script_heat_list()
|
||||
self.m.ReplayAll()
|
||||
|
||||
update_text = self.shell(
|
||||
'stack-update teststack2 '
|
||||
'--template-file=%s '
|
||||
'--parameters="InstanceType=m1.large;DBUsername=wp;'
|
||||
'DBPassword=verybadpassword;KeyName=heat_key;'
|
||||
'LinuxDistribution=F17"' % template_file)
|
||||
|
||||
required = [
|
||||
'stack_name',
|
||||
'id',
|
||||
'teststack2',
|
||||
'2'
|
||||
]
|
||||
for r in required:
|
||||
self.assertRegexpMatches(update_text, r)
|
||||
|
||||
@httpretty.activate
|
||||
def test_stack_delete(self):
|
||||
self.register_keystone_auth_fixture()
|
||||
|
|
|
@ -21,6 +21,7 @@ import yaml
|
|||
from heatclient.common import template_utils
|
||||
from heatclient.common import utils
|
||||
from heatclient.openstack.common import jsonutils
|
||||
from heatclient.openstack.common import strutils
|
||||
|
||||
import heatclient.exc as exc
|
||||
|
||||
|
@ -347,7 +348,16 @@ def do_stack_show(hc, args):
|
|||
type=int,
|
||||
help='Stack update timeout in minutes.')
|
||||
@utils.arg('-r', '--enable-rollback', default=False, action="store_true",
|
||||
help='Enable rollback on create/update failure.')
|
||||
help='DEPRECATED! Use --rollback argument instead. '
|
||||
'Enable rollback on stack update failure. '
|
||||
'NOTE: default behavior is now to use the rollback value '
|
||||
'of existing stack.')
|
||||
@utils.arg('--rollback', default=None, metavar='<VALUE>',
|
||||
help='Set rollback on update failure. '
|
||||
'Values %(true)s set rollback to enabled. '
|
||||
'Values %(false)s set rollback to disabled. '
|
||||
'Default is to use the value of existing stack to be updated.'
|
||||
% {'true': strutils.TRUE_STRINGS, 'false': strutils.FALSE_STRINGS})
|
||||
@utils.arg('-P', '--parameters', metavar='<KEY1=VALUE1;KEY2=VALUE2...>',
|
||||
help='Parameter values used to create the stack. '
|
||||
'This can be specified multiple times, or once with parameters '
|
||||
|
@ -374,7 +384,16 @@ def do_update(hc, args):
|
|||
type=int,
|
||||
help='Stack update timeout in minutes.')
|
||||
@utils.arg('-r', '--enable-rollback', default=False, action="store_true",
|
||||
help='Enable rollback on create/update failure.')
|
||||
help='DEPRECATED! Use --rollback argument instead. '
|
||||
'Enable rollback on stack update failure. '
|
||||
'NOTE: default behavior is now to use the rollback value '
|
||||
'of existing stack.')
|
||||
@utils.arg('--rollback', default=None, metavar='<VALUE>',
|
||||
help='Set rollback on update failure. '
|
||||
'Values %(true)s set rollback to enabled. '
|
||||
'Values %(false)s set rollback to disabled. '
|
||||
'Default is to use the value of existing stack to be updated.'
|
||||
% {'true': strutils.TRUE_STRINGS, 'false': strutils.FALSE_STRINGS})
|
||||
@utils.arg('-P', '--parameters', metavar='<KEY1=VALUE1;KEY2=VALUE2...>',
|
||||
help='Parameter values used to create the stack. '
|
||||
'This can be specified multiple times, or once with parameters '
|
||||
|
@ -396,7 +415,6 @@ def do_stack_update(hc, args):
|
|||
|
||||
fields = {
|
||||
'stack_id': args.id,
|
||||
'disable_rollback': not(args.enable_rollback),
|
||||
'parameters': utils.format_parameters(args.parameters),
|
||||
'template': template,
|
||||
'files': dict(list(tpl_files.items()) + list(env_files.items())),
|
||||
|
@ -406,6 +424,19 @@ def do_stack_update(hc, args):
|
|||
if args.timeout:
|
||||
fields['timeout_mins'] = args.timeout
|
||||
|
||||
if args.rollback is not None:
|
||||
try:
|
||||
rollback = strutils.bool_from_string(args.rollback, strict=True)
|
||||
except ValueError as ex:
|
||||
raise exc.CommandError(six.text_type(ex))
|
||||
else:
|
||||
fields['disable_rollback'] = not(rollback)
|
||||
# TODO(pshchelo): remove the following 'else' clause after deprecation
|
||||
# period of --enable-rollback switch and assign -r shortcut to --rollback
|
||||
else:
|
||||
if args.enable_rollback:
|
||||
fields['disable_rollback'] = False
|
||||
|
||||
hc.stacks.update(**fields)
|
||||
do_stack_list(hc)
|
||||
|
||||
|
|
Loading…
Reference in New Issue