~nskaggs/juju-ci-tools/add-essential-operations

« back to all changes in this revision

Viewing changes to assess_controller_permissions.py

Merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
"""TODO: add rough description of what is assessed in this module."""
 
3
 
 
4
from __future__ import print_function
 
5
 
 
6
import argparse
 
7
import logging
 
8
import random
 
9
import string
 
10
import subprocess
 
11
import sys
 
12
 
 
13
from assess_user_grant_revoke import (
 
14
    assert_change_password,
 
15
    assert_logout_login,
 
16
    list_users,
 
17
    User,
 
18
)
 
19
from deploy_stack import (
 
20
    BootstrapManager,
 
21
)
 
22
from utility import (
 
23
    add_basic_testing_arguments,
 
24
    configure_logging,
 
25
    temp_dir,
 
26
)
 
27
 
 
28
 
 
29
__metaclass__ = type
 
30
 
 
31
 
 
32
log = logging.getLogger("assess_controller_permissions")
 
33
 
 
34
 
 
35
# This needs refactored out to utility
 
36
class JujuAssertionError(AssertionError):
 
37
    """Exception for juju assertion failures."""
 
38
 
 
39
 
 
40
def assert_add_model(user_client, permission):
 
41
    """Test user's ability of adding models."""
 
42
    try:
 
43
        user_client.add_model(user_client.env)
 
44
    except subprocess.CalledProcessError:
 
45
        raise JujuAssertionError(
 
46
            "Controller can't add model with {} permission".format(permission))
 
47
 
 
48
 
 
49
def assert_destroy_model(user_client, permission):
 
50
    """Test user's ability of destroying models."""
 
51
    try:
 
52
        user_client.destroy_model()
 
53
    except subprocess.CalledProcessError:
 
54
        raise JujuAssertionError(
 
55
            "Controller can't destroy model with {} permission".format(
 
56
                permission))
 
57
 
 
58
 
 
59
def assert_add_remove_user(user_client, permission):
 
60
    """Test user's ability of adding/removing users."""
 
61
    for controller_permission in ['login', 'addmodel', 'superuser']:
 
62
        code = ''.join(random.choice(
 
63
            string.ascii_letters + string.digits) for _ in xrange(4))
 
64
        try:
 
65
            user_client.add_user(permission + code,
 
66
                                 permissions=controller_permission)
 
67
        except subprocess.CalledProcessError:
 
68
            raise JujuAssertionError(
 
69
                'Controller could not add '
 
70
                '{} controller with {} permission'.format(
 
71
                    controller_permission, permission))
 
72
        try:
 
73
            user_client.remove_user(permission + code,
 
74
                                    permissions=controller_permission)
 
75
        except subprocess.CalledProcessError:
 
76
            raise JujuAssertionError(
 
77
                'Controller could not remove '
 
78
                '{} controller with {} permission'.format(
 
79
                    controller_permission, permission))
 
80
 
 
81
 
 
82
def assert_lists(user_client):
 
83
    """Test user's ability of retrieving lists."""
 
84
    list_users(user_client)
 
85
    user_client.list_models()
 
86
    user_client.list_clouds()
 
87
    user_client.show_controller()
 
88
 
 
89
 
 
90
def assert_login_permission(controller_client, user_client,
 
91
                            user, fake_home, has_permission):
 
92
    """Test user's ability with login permission."""
 
93
    if has_permission:
 
94
        try:
 
95
            assert_logout_login(controller_client, user_client,
 
96
                                user, fake_home)
 
97
            assert_change_password(user_client, user)
 
98
            assert_lists(user_client)
 
99
        except subprocess.CalledProcessError:
 
100
            raise JujuAssertionError(
 
101
                'FAIL {} could not login/read with {} permission'.format(
 
102
                    user.name, user.permissions))
 
103
    else:
 
104
        try:
 
105
            assert_logout_login(controller_client, user_client,
 
106
                                user, fake_home)
 
107
            assert_change_password(user_client, user)
 
108
            assert_lists(user_client)
 
109
        except subprocess.CalledProcessError:
 
110
            log.info('Correctly rejected {} use of login/read'.format(
 
111
                user.name))
 
112
        else:
 
113
            raise JujuAssertionError(
 
114
                'FAIL User login/read without login permission')
 
115
 
 
116
 
 
117
def assert_addmodel_permission(user_client, user, has_permission):
 
118
    """Test user's ability with addmodel permission."""
 
119
    if has_permission:
 
120
        try:
 
121
            assert_add_model(user_client, user.permissions)
 
122
            assert_destroy_model(user_client, user.permissions)
 
123
        except subprocess.CalledProcessError:
 
124
            raise JujuAssertionError(
 
125
                'FAIL {} could not add/remove'
 
126
                ' models with {} permission'.format(
 
127
                    user.name, user.permissions))
 
128
    else:
 
129
        try:
 
130
            assert_add_model(user_client, user.permissions)
 
131
            assert_destroy_model(user_client, user.permissions)
 
132
        except subprocess.CalledProcessError:
 
133
            log.info('Correctly rejected {} use of add/remove model'.format(
 
134
                user.name))
 
135
        else:
 
136
            raise JujuAssertionError(
 
137
                'FAIL User added/removed models without addmodel permission')
 
138
 
 
139
 
 
140
def assert_superuser_permission(user_client, user, has_permission):
 
141
    """Test user's ability with superuser permission."""
 
142
    if has_permission:
 
143
        try:
 
144
            assert_add_remove_user(user_client, user.permissions)
 
145
        except subprocess.CalledProcessError:
 
146
            raise JujuAssertionError(
 
147
                'FAIL {} could not add/remove users with {} permission'.format(
 
148
                    user.name, user.permissions))
 
149
    else:
 
150
        try:
 
151
            assert_add_remove_user(user_client, user.permissions)
 
152
        except subprocess.CalledProcessError:
 
153
            log.info('Correctly rejected {} use of add/remove users'.format(
 
154
                user.name))
 
155
        else:
 
156
            raise JujuAssertionError(
 
157
                'FAIL User added/removed users without superuser permission')
 
158
 
 
159
 
 
160
def assert_login_controller(controller_client, user):
 
161
    """Test user with login controller permission."""
 
162
    with temp_dir() as fake_home:
 
163
        user_client = controller_client.register_user(
 
164
            user, fake_home)
 
165
        assert_login_permission(controller_client, user_client,
 
166
                                user, fake_home, True)
 
167
        assert_addmodel_permission(user_client, user, False)
 
168
        assert_superuser_permission(user_client, user, False)
 
169
 
 
170
 
 
171
def assert_addmodel_controller(controller_client, user):
 
172
    """Test user with addmodel controller permission."""
 
173
    with temp_dir() as fake_home:
 
174
        user_client = controller_client.register_user(
 
175
            user, fake_home)
 
176
        assert_login_permission(controller_client, user_client,
 
177
                                user, fake_home, True)
 
178
        assert_addmodel_permission(user_client, user, True)
 
179
        assert_superuser_permission(user_client, user, False)
 
180
 
 
181
 
 
182
def assert_superuser_controller(controller_client, user):
 
183
    """Test user with superuser controller permission."""
 
184
    with temp_dir() as fake_home:
 
185
        user_client = controller_client.register_user(
 
186
            user, fake_home)
 
187
        assert_login_permission(controller_client, user_client,
 
188
                                user, fake_home, True)
 
189
        assert_addmodel_permission(user_client, user, True)
 
190
        assert_superuser_permission(user_client, user, True)
 
191
 
 
192
 
 
193
def assess_controller_permissions(controller_client):
 
194
    """Test controller permissions."""
 
195
    login_controller = User('login_controller', 'login', [])
 
196
    addmodel_controller = User('addmodel_controller', 'addmodel', [])
 
197
    superuser_controller = User('superuser_controller', 'superuser', [])
 
198
    assert_login_controller(controller_client, login_controller)
 
199
    assert_addmodel_controller(controller_client, addmodel_controller)
 
200
    assert_superuser_controller(controller_client, superuser_controller)
 
201
 
 
202
 
 
203
def parse_args(argv):
 
204
    """Parse all arguments."""
 
205
    parser = argparse.ArgumentParser(
 
206
        description="Test controller permissions.")
 
207
    add_basic_testing_arguments(parser)
 
208
    return parser.parse_args(argv)
 
209
 
 
210
 
 
211
def main(argv=None):
 
212
    args = parse_args(argv)
 
213
    configure_logging(args.verbose)
 
214
    bs_manager = BootstrapManager.from_args(args)
 
215
    with bs_manager.booted_context(args.upload_tools):
 
216
        assess_controller_permissions(bs_manager.client)
 
217
    return 0
 
218
 
 
219
 
 
220
if __name__ == '__main__':
 
221
    sys.exit(main())