github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/acceptancetests/assess_block.py (about) 1 #!/usr/bin/env python 2 """Assess juju blocks prevent users from making changes and models""" 3 4 from __future__ import print_function 5 6 import argparse 7 import logging 8 import sys 9 10 from assess_min_version import ( 11 JujuAssertionError 12 ) 13 from deploy_stack import ( 14 BootstrapManager, 15 deploy_dummy_stack, 16 ) 17 from utility import ( 18 add_basic_testing_arguments, 19 configure_logging, 20 ) 21 22 23 __metaclass__ = type 24 25 26 log = logging.getLogger("assess_block") 27 28 29 def make_block_list(client, disabled_commands): 30 """Return a manually made list of blocks and their status 31 32 :param client: The client whose rules will be used. 33 :param disabled_commands: list of client.command_set_* elements to 34 include in simulated output. 35 """ 36 if not disabled_commands: 37 return [] 38 39 return [{'command-set': ','.join(disabled_commands)}] 40 41 42 def test_disabled(client, command, args, include_e=True): 43 """Test if a command is disabled as expected""" 44 try: 45 if command == 'deploy': 46 client.deploy(args) 47 elif command == 'remove-service': 48 client.remove_service(args) 49 else: 50 client.juju(command, args, include_e=include_e) 51 raise JujuAssertionError() 52 except Exception: 53 pass 54 55 56 def assess_block_destroy_model(client, charm_series): 57 """Test disabling the destroy-model command. 58 59 When "disable-command destroy-model" is set, 60 the model cannot be destroyed, but objects 61 can be added, related, and removed. 62 """ 63 client.disable_command(client.destroy_model_command) 64 block_list = client.list_disabled_commands() 65 if block_list != make_block_list( 66 client, [client.command_set_destroy_model]): 67 raise JujuAssertionError(block_list) 68 test_disabled( 69 client, client.destroy_model_command, 70 ('-y', client.env.environment), include_e=False) 71 # Adding, relating, and removing are not blocked. 72 deploy_dummy_stack(client, charm_series) 73 74 75 def assess_block_remove_object(client, charm_series): 76 """Test block remove-object 77 78 When "disable-command remove-object" is set, 79 objects can be added and related, but they 80 cannot be removed or the model/environment deleted. 81 """ 82 client.disable_command(client.command_set_remove_object) 83 block_list = client.list_disabled_commands() 84 if block_list != make_block_list( 85 client, [client.command_set_remove_object]): 86 raise JujuAssertionError(block_list) 87 test_disabled( 88 client, client.destroy_model_command, 89 ('-y', client.env.environment), include_e=False) 90 # Adding and relating are not blocked. 91 deploy_dummy_stack(client, charm_series) 92 test_disabled(client, 'remove-service', 'dummy-source') 93 test_disabled(client, 'remove-unit', ('dummy-source/1',)) 94 test_disabled(client, 'remove-relation', ('dummy-source', 'dummy-sink')) 95 96 97 def assess_block_all_changes(client, charm_series): 98 """Test Block Functionality: block all-changes""" 99 client.juju('remove-relation', ('dummy-source', 'dummy-sink')) 100 client.disable_command(client.command_set_all) 101 block_list = client.list_disabled_commands() 102 if block_list != make_block_list(client, [client.command_set_all]): 103 raise JujuAssertionError(block_list) 104 test_disabled(client, 'add-relation', ('dummy-source', 'dummy-sink')) 105 test_disabled(client, 'unexpose', ('dummy-sink',)) 106 test_disabled(client, 'remove-service', 'dummy-sink') 107 client.enable_command(client.command_set_all) 108 client.juju('unexpose', ('dummy-sink',)) 109 client.disable_command(client.command_set_all) 110 test_disabled(client, 'expose', ('dummy-sink',)) 111 client.enable_command(client.command_set_all) 112 client.remove_service('dummy-sink') 113 client.wait_for_started() 114 client.disable_command(client.command_set_all) 115 test_disabled(client, 'deploy', ('dummy-sink',)) 116 test_disabled( 117 client, client.destroy_model_command, 118 ('-y', client.env.environment), include_e=False) 119 120 121 def assess_unblock(client, type): 122 """Test Block Functionality 123 unblock destroy-model/remove-object/all-changes.""" 124 client.enable_command(type) 125 block_list = client.list_disabled_commands() 126 if block_list != make_block_list(client, []): 127 raise JujuAssertionError(block_list) 128 if type == client.destroy_model_command: 129 client.remove_service('dummy-source') 130 client.wait_for_started() 131 client.remove_service('dummy-sink') 132 client.wait_for_started() 133 134 135 def assess_block(client, charm_series): 136 """Test Block Functionality: 137 block/unblock destroy-model/remove-object/all-changes. 138 """ 139 log.info('Test started') 140 block_list = client.list_disabled_commands() 141 client.wait_for_started() 142 expected_none_blocked = make_block_list(client, []) 143 if block_list != expected_none_blocked: 144 log.error('Controller is not in the expected starting state') 145 raise JujuAssertionError( 146 'Expected {}\nFound {}'.format(expected_none_blocked, block_list)) 147 assess_block_destroy_model(client, charm_series) 148 assess_unblock(client, client.destroy_model_command) 149 assess_block_remove_object(client, charm_series) 150 assess_unblock(client, client.command_set_remove_object) 151 assess_block_all_changes(client, charm_series) 152 assess_unblock(client, client.command_set_all) 153 log.info('Test PASS') 154 155 156 def parse_args(argv): 157 """Parse all arguments.""" 158 parser = argparse.ArgumentParser(description="Test Block Functionality") 159 add_basic_testing_arguments(parser) 160 parser.set_defaults(series='trusty') 161 return parser.parse_args(argv) 162 163 164 def main(argv=None): 165 args = parse_args(argv) 166 configure_logging(args.verbose) 167 bs_manager = BootstrapManager.from_args(args) 168 with bs_manager.booted_context(args.upload_tools): 169 assess_block(bs_manager.client, bs_manager.series) 170 return 0 171 172 173 if __name__ == '__main__': 174 sys.exit(main())