Require --force argument when removing an environment

Since removal of an environment is a dangerous operation
it is nececcary to ask user to enter an extra proof of the
intended action.

This patch adds the required --force argument to the env-delete
command.

Closes-bug: #1455025
Change-Id: I0aacf547c6c48755a8d3b9a139dc4f30d9d46a4a
This commit is contained in:
Roman Prykhodchenko
2015-05-14 13:48:33 +02:00
parent e4ebbc720c
commit 38765563e1
4 changed files with 66 additions and 2 deletions

View File

@@ -51,6 +51,9 @@ class EnvironmentAction(Action):
Args.get_release_arg(
"Release id"
),
Args.get_force_arg(
"Do it anyway."
),
Args.get_name_arg(
"environment name"
),
@@ -148,9 +151,18 @@ class EnvironmentAction(Action):
@check_all("env")
def delete(self, params):
"""To delete the environment:
fuel --env 1 env delete
fuel --env 1 env --force delete
"""
env = Environment(params.env, params=params)
if env.status == "operational" and not params.force:
self.serializer.print_to_output(env.data,
"Deleting an operational"
"environment is a dangerous "
"operation. Please use --force to "
"bypass this message.")
return
data = env.delete()
self.serializer.print_to_output(
data,

View File

@@ -103,6 +103,27 @@ class EnvCreate(EnvMixIn, base.BaseShowCommand):
class EnvDelete(EnvMixIn, base.BaseDeleteCommand):
"""Delete environment with given id."""
def get_parser(self, prog_name):
parser = super(EnvDelete, self).get_parser(prog_name)
parser.add_argument('-f',
'--force',
action='store_true',
help='Force-delete the environment.')
return parser
def take_action(self, parsed_args):
env = self.client.get_by_id(parsed_args.id)
if env.status == 'operational' and not parsed_args.force:
self.app.stdout.write("Deleting an operational environment is a "
"dangerous operation. Please use --force to "
"bypass this message.")
return
return super(EnvDelete, self).take_action(parsed_args)
class EnvUpdate(EnvMixIn, base.BaseShowCommand):
"""Change given attributes for an environment."""

View File

@@ -14,12 +14,30 @@
# License for the specific language governing permissions and limitations
# under the License.
import cStringIO
import mock
from fuelclient.objects.environment import Environment
from fuelclient.tests import base
class TestEnvironment(base.UnitTestCase):
@mock.patch('requests.Response', new_callable=mock.MagicMock)
@mock.patch('requests.delete')
@mock.patch('requests.get')
def test_delete_operational_wo_force(self, m_get, m_del, m_resp):
m_resp.json.return_value = {'id': 1, 'status': 'operational'}
m_get.return_value = m_resp
with mock.patch('sys.stdout', new=cStringIO.StringIO()) as m_stdout:
self.execute('fuel --env 1 env delete'.split())
self.assertIn('--force', m_stdout.getvalue())
self.assertEqual(0, m_del.call_count)
class TestEnvironmentOstf(base.UnitTestCase):
def setUp(self):

View File

@@ -14,6 +14,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import cStringIO
import mock
from fuelclient.tests.v2.unit.cli import test_engine
@@ -50,12 +52,23 @@ class TestEnvCommand(test_engine.BaseCLITest):
net_segment_type='gre')
def test_env_delete(self):
args = 'env delete 42'
args = 'env delete --force 42'
self.exec_command(args)
self.m_get_client.assert_called_once_with('environment', mock.ANY)
self.m_client.delete_by_id.assert_called_once_with(42)
def test_env_delete_wo_force(self):
args = 'env delete 42'
fake_env = mock.Mock()
fake_env.status = 'operational'
self.m_client.get_by_id.return_value = fake_env
with mock.patch('sys.stdout', new=cStringIO.StringIO()) as m_stdout:
self.exec_command(args)
self.assertIn('--force', m_stdout.getvalue())
def test_env_deploy(self):
args = 'env deploy 42'
self.exec_command(args)