2
"""Assess juju blocks prevent users from making changes and models"""
4
from __future__ import print_function
10
from assess_min_version import (
13
from deploy_stack import (
18
add_basic_testing_arguments,
20
wait_for_removed_services,
27
log = logging.getLogger("assess_block")
30
class DisableCommandTypes:
31
destroy_mode = 'destroy-model'
32
remove_object = 'remove-object'
36
def make_block_list(disabled_commands):
37
"""Return a manually made list of blocks and their status
39
:param disabled_commands: list of DisableCommandTypes elements to include
43
if not disabled_commands:
46
return [{'command-set': ','.join(disabled_commands)}]
49
def test_disabled(client, command, args, include_e=True):
50
"""Test if a command is disabled as expected"""
52
if command == 'deploy':
54
elif command == 'remove-service':
55
client.remove_service(args)
57
client.juju(command, args, include_e=include_e)
58
raise JujuAssertionError()
63
def assess_block_destroy_model(client, charm_series):
64
"""Test disabling the destroy-model command.
66
When "disable-command destroy-model" is set,
67
the model cannot be destroyed, but objects
68
can be added, related, and removed.
70
client.disable_command(client.destroy_model_command)
71
block_list = client.list_disabled_commands()
72
if block_list != make_block_list([DisableCommandTypes.destroy_mode]):
73
raise JujuAssertionError(block_list)
75
client, client.destroy_model_command,
76
('-y', client.env.environment), include_e=False)
77
# Adding, relating, and removing are not blocked.
78
deploy_dummy_stack(client, charm_series)
81
def assess_block_remove_object(client, charm_series):
82
"""Test block remove-object
84
When "disable-command remove-object" is set,
85
objects can be added and related, but they
86
cannot be removed or the model/environment deleted.
88
client.disable_command(DisableCommandTypes.remove_object)
89
block_list = client.list_disabled_commands()
90
if block_list != make_block_list([DisableCommandTypes.remove_object]):
91
raise JujuAssertionError(block_list)
93
client, client.destroy_model_command,
94
('-y', client.env.environment), include_e=False)
95
# Adding and relating are not blocked.
96
deploy_dummy_stack(client, charm_series)
97
test_disabled(client, 'remove-service', 'dummy-source')
98
test_disabled(client, 'remove-unit', ('dummy-source/1',))
99
test_disabled(client, 'remove-relation', ('dummy-source', 'dummy-sink'))
102
def assess_block_all_changes(client, charm_series):
103
"""Test Block Functionality: block all-changes"""
104
client.juju('remove-relation', ('dummy-source', 'dummy-sink'))
105
client.disable_command(DisableCommandTypes.all)
106
block_list = client.list_disabled_commands()
107
if block_list != make_block_list([DisableCommandTypes.all]):
108
raise JujuAssertionError(block_list)
109
test_disabled(client, 'add-relation', ('dummy-source', 'dummy-sink'))
110
test_disabled(client, 'unexpose', ('dummy-sink',))
111
test_disabled(client, 'remove-service', 'dummy-sink')
112
client.enable_command(DisableCommandTypes.all)
113
client.juju('unexpose', ('dummy-sink',))
114
client.disable_command(DisableCommandTypes.all)
115
test_disabled(client, 'expose', ('dummy-sink',))
116
client.enable_command(DisableCommandTypes.all)
117
client.remove_service('dummy-sink')
118
wait_for_removed_services(client, 'dummy-sink')
119
client.disable_command(DisableCommandTypes.all)
120
test_disabled(client, 'deploy', ('dummy-sink',))
122
client, client.destroy_model_command,
123
('-y', client.env.environment), include_e=False)
126
def assess_unblock(client, type):
127
"""Test Block Functionality
128
unblock destroy-model/remove-object/all-changes."""
129
client.enable_command(type)
130
block_list = client.list_disabled_commands()
131
if block_list != make_block_list([]):
132
raise JujuAssertionError(block_list)
133
if type == client.destroy_model_command:
134
client.remove_service('dummy-source')
135
wait_for_removed_services(client, 'dummy-source')
136
client.remove_service('dummy-sink')
137
wait_for_removed_services(client, 'dummy-sink')
140
def assess_block(client, charm_series):
141
"""Test Block Functionality:
142
block/unblock destroy-model/remove-object/all-changes.
144
block_list = client.list_disabled_commands()
145
client.wait_for_started()
146
expected_none_blocked = make_block_list([])
147
if block_list != expected_none_blocked:
148
raise JujuAssertionError(block_list)
149
assess_block_destroy_model(client, charm_series)
150
assess_unblock(client, client.destroy_model_command)
151
assess_block_remove_object(client, charm_series)
152
assess_unblock(client, DisableCommandTypes.remove_object)
153
assess_block_all_changes(client, charm_series)
154
assess_unblock(client, DisableCommandTypes.all)
157
def parse_args(argv):
158
"""Parse all arguments."""
159
parser = argparse.ArgumentParser(description="Test Block Functionality")
160
add_basic_testing_arguments(parser)
161
parser.set_defaults(series='trusty')
162
return parser.parse_args(argv)
166
args = parse_args(argv)
167
configure_logging(args.verbose)
168
bs_manager = BootstrapManager.from_args(args)
169
with bs_manager.booted_context(args.upload_tools):
170
assess_block(bs_manager.client, bs_manager.series)
174
if __name__ == '__main__':