Browse Source

Fix CVE-2016-7404

This commit addresses multiple potential vulnerabilities in
Magnum. It makes the following changes:

* Permissions for /etc/sysconfig/heat-params inside Magnum
  created instances are tightened to 0600 (used to be 0755).
* Certificate retrieval is modified to work without the need
  for a Keystone trust.
* The cluster's Keystone trust id is only passed into
  instances for clusters where that is actually needed. This
  prevents the trustee user from consuming the trust in cases
  where it is not needed.
* The configuration setting trust/cluster_user_trust (False by
  default) is introduced. It needs to be explicitely enabled
  by the cloud operator to allow clusters that need the
  trust_id to be passed into instances to work. Without this
  setting, attempts to create such clusters will fail.

Please note, that none of these changes apply to existing
clusters. They will have to be deleted and rebuilt to benefit
from these changes.

(cherry picked from commit e93d82e8b3)

Change-Id: I643d408cde0d6e30812cf6429fb7118184793400
Johannes Grassler 2 years ago
parent
commit
0c7625ff4b
27 changed files with 171 additions and 75 deletions
  1. 1
    0
      devstack/lib/magnum
  2. 28
    26
      etc/magnum/policy.json
  3. 1
    0
      magnum/common/keystone.py
  4. 12
    0
      magnum/common/policy.py
  5. 10
    3
      magnum/conductor/handlers/common/trust_manager.py
  6. 11
    0
      magnum/conf/trust.py
  7. 16
    1
      magnum/db/sqlalchemy/api.py
  8. 0
    5
      magnum/drivers/common/templates/kubernetes/fragments/make-cert-client.sh
  9. 0
    5
      magnum/drivers/common/templates/kubernetes/fragments/make-cert.sh
  10. 1
    1
      magnum/drivers/common/templates/kubernetes/fragments/write-heat-params-master.yaml
  11. 1
    1
      magnum/drivers/common/templates/kubernetes/fragments/write-heat-params.yaml
  12. 0
    6
      magnum/drivers/common/templates/swarm/fragments/make-cert.py
  13. 1
    1
      magnum/drivers/common/templates/swarm/fragments/write-heat-params-master.yaml
  14. 1
    1
      magnum/drivers/common/templates/swarm/fragments/write-heat-params-node.yaml
  15. 15
    1
      magnum/drivers/heat/template_def.py
  16. 0
    5
      magnum/drivers/k8s_coreos_v1/templates/fragments/make-cert-client.yaml
  17. 0
    5
      magnum/drivers/k8s_coreos_v1/templates/fragments/make-cert.yaml
  18. 1
    1
      magnum/drivers/k8s_coreos_v1/templates/fragments/write-heat-params-master.yaml
  19. 1
    1
      magnum/drivers/k8s_coreos_v1/templates/fragments/write-heat-params.yaml
  20. 1
    1
      magnum/drivers/mesos_ubuntu_v1/templates/fragments/write-heat-params.yaml
  21. 27
    0
      magnum/tests/base.py
  22. 15
    0
      magnum/tests/unit/common/test_keystone.py
  23. 2
    1
      magnum/tests/unit/conductor/handlers/common/test_trust_manager.py
  24. 5
    0
      magnum/tests/unit/conductor/handlers/test_cluster_conductor.py
  25. 9
    5
      magnum/tests/unit/conductor/handlers/test_k8s_cluster_conductor.py
  26. 5
    4
      magnum/tests/unit/conductor/handlers/test_mesos_cluster_conductor.py
  27. 7
    1
      magnum/tests/unit/conductor/handlers/test_swarm_cluster_conductor.py

+ 1
- 0
devstack/lib/magnum View File

@@ -204,6 +204,7 @@ function create_magnum_conf {
204 204
               --os-identity-api-version 3 role add \
205 205
               --user $trustee_domain_admin_id --domain $trustee_domain_id \
206 206
               admin
207
+    iniset $MAGNUM_CONF trust cluster_user_trust True
207 208
     iniset $MAGNUM_CONF trust trustee_domain_name magnum
208 209
     iniset $MAGNUM_CONF trust trustee_domain_admin_name trustee_domain_admin
209 210
     iniset $MAGNUM_CONF trust trustee_domain_admin_password $MAGNUM_TRUSTEE_DOMAIN_ADMIN_PASSWORD

+ 28
- 26
etc/magnum/policy.json View File

@@ -4,35 +4,37 @@
4 4
     "default": "rule:admin_or_owner",
5 5
     "admin_api": "rule:context_is_admin",
6 6
     "admin_or_user": "is_admin:True or user_id:%(user_id)s",
7
+    "cluster_user": "user_id:%(trustee_user_id)s",
8
+    "deny_cluster_user": "not domain_id:%(trustee_domain_id)s",
7 9
 
8
-    "bay:create": "rule:default",
9
-    "bay:delete": "rule:default",
10
-    "bay:detail": "rule:default",
11
-    "bay:get": "rule:default",
12
-    "bay:get_all": "rule:default",
13
-    "bay:update": "rule:default",
10
+    "bay:create": "rule:deny_cluster_user",
11
+    "bay:delete": "rule:deny_cluster_user",
12
+    "bay:detail": "rule:deny_cluster_user",
13
+    "bay:get": "rule:deny_cluster_user",
14
+    "bay:get_all": "rule:deny_cluster_user",
15
+    "bay:update": "rule:deny_cluster_user",
14 16
 
15
-    "baymodel:create": "rule:default",
16
-    "baymodel:delete": "rule:default",
17
-    "baymodel:detail": "rule:default",
18
-    "baymodel:get": "rule:default",
19
-    "baymodel:get_all": "rule:default",
20
-    "baymodel:update": "rule:default",
17
+    "baymodel:create": "rule:deny_cluster_user",
18
+    "baymodel:delete": "rule:deny_cluster_user",
19
+    "baymodel:detail": "rule:deny_cluster_user",
20
+    "baymodel:get": "rule:deny_cluster_user",
21
+    "baymodel:get_all": "rule:deny_cluster_user",
22
+    "baymodel:update": "rule:deny_cluster_user",
21 23
     "baymodel:publish": "rule:admin_or_owner",
22 24
 
23
-    "cluster:create": "rule:default",
24
-    "cluster:delete": "rule:default",
25
-    "cluster:detail": "rule:default",
26
-    "cluster:get": "rule:default",
27
-    "cluster:get_all": "rule:default",
28
-    "cluster:update": "rule:default",
25
+    "cluster:create": "rule:deny_cluster_user",
26
+    "cluster:delete": "rule:deny_cluster_user",
27
+    "cluster:detail": "rule:deny_cluster_user",
28
+    "cluster:get": "rule:deny_cluster_user",
29
+    "cluster:get_all": "rule:deny_cluster_user",
30
+    "cluster:update": "rule:deny_cluster_user",
29 31
 
30
-    "clustertemplate:create": "rule:default",
31
-    "clustertemplate:delete": "rule:default",
32
-    "clustertemplate:detail": "rule:default",
33
-    "clustertemplate:get": "rule:default",
34
-    "clustertemplate:get_all": "rule:default",
35
-    "clustertemplate:update": "rule:default",
32
+    "clustertemplate:create": "rule:deny_cluster_user",
33
+    "clustertemplate:delete": "rule:deny_cluster_user",
34
+    "clustertemplate:detail": "rule:deny_cluster_user",
35
+    "clustertemplate:get": "rule:deny_cluster_user",
36
+    "clustertemplate:get_all": "rule:deny_cluster_user",
37
+    "clustertemplate:update": "rule:deny_cluster_user",
36 38
     "clustertemplate:publish": "rule:admin_or_owner",
37 39
 
38 40
     "quotas:get": "rule:default",
@@ -41,9 +43,9 @@
41 43
     "quotas:update": "rule:admin_api",
42 44
     "quotas:delete": "rule:admin_api",
43 45
 
44
-    "certificate:create": "rule:admin_or_user",
45
-    "certificate:get": "rule:admin_or_user",
46 46
     "certificate:rotate_ca": "rule:admin_or_owner",
47
+    "certificate:create": "rule:admin_or_user or rule:cluster_user",
48
+    "certificate:get": "rule:admin_or_user or rule:cluster_user",
47 49
 
48 50
     "magnum-service:get_all": "rule:admin_api",
49 51
     "stats:get_all": "rule:admin_or_owner"

+ 1
- 0
magnum/common/keystone.py View File

@@ -204,6 +204,7 @@ class KeystoneClientV3(object):
204 204
                 project=trustor_project_id,
205 205
                 trustee_user=trustee_user,
206 206
                 impersonation=True,
207
+                delegation_depth=0,
207 208
                 role_names=roles)
208 209
         except Exception:
209 210
             LOG.exception(_LE('Failed to create trust'))

+ 12
- 0
magnum/common/policy.py View File

@@ -20,6 +20,8 @@ from oslo_config import cfg
20 20
 from oslo_policy import policy
21 21
 import pecan
22 22
 
23
+from magnum.common import clients
24
+from magnum.common import context
23 25
 from magnum.common import exception
24 26
 
25 27
 
@@ -92,10 +94,20 @@ def enforce(context, rule=None, target=None,
92 94
     if target is None:
93 95
         target = {'project_id': context.project_id,
94 96
                   'user_id': context.user_id}
97
+    add_policy_attributes(target)
95 98
     return enforcer.enforce(rule, target, credentials,
96 99
                             do_raise=do_raise, exc=exc, *args, **kwargs)
97 100
 
98 101
 
102
+def add_policy_attributes(target):
103
+    """Adds extra information for policy enforcement to raw target object"""
104
+    admin_context = context.make_admin_context()
105
+    admin_osc = clients.OpenStackClients(admin_context)
106
+    trustee_domain_id = admin_osc.keystone().trustee_domain_id
107
+    target['trustee_domain_id'] = trustee_domain_id
108
+    return target
109
+
110
+
99 111
 def enforce_wsgi(api_name, act=None):
100 112
     """This is a decorator to simplify wsgi action policy rule check.
101 113
 

+ 10
- 3
magnum/conductor/handlers/common/trust_manager.py View File

@@ -22,15 +22,20 @@ LOG = logging.getLogger(__name__)
22 22
 def create_trustee_and_trust(osc, cluster):
23 23
     try:
24 24
         password = utils.generate_password(length=18)
25
+
25 26
         trustee = osc.keystone().create_trustee(
26
-            cluster.uuid,
27
+            "%s_%s" % (cluster.uuid, cluster.project_id),
27 28
             password,
28 29
         )
30
+
29 31
         cluster.trustee_username = trustee.name
30 32
         cluster.trustee_user_id = trustee.id
31 33
         cluster.trustee_password = password
32
-        trust = osc.keystone().create_trust(trustee.id)
34
+
35
+        trust = osc.keystone().create_trust(
36
+            cluster.trustee_user_id)
33 37
         cluster.trust_id = trust.id
38
+
34 39
     except Exception:
35 40
         LOG.exception(
36 41
             _LE('Failed to create trustee and trust for Cluster: %s'),
@@ -41,9 +46,11 @@ def create_trustee_and_trust(osc, cluster):
41 46
 
42 47
 def delete_trustee_and_trust(osc, context, cluster):
43 48
     try:
49
+        kst = osc.keystone()
50
+
44 51
         # The cluster which is upgraded from Liberty doesn't have trust_id
45 52
         if cluster.trust_id:
46
-            osc.keystone().delete_trust(context, cluster)
53
+            kst.delete_trust(context, cluster)
47 54
     except Exception:
48 55
         # Exceptions are already logged by keystone().delete_trust
49 56
         pass

+ 11
- 0
magnum/conf/trust.py View File

@@ -18,6 +18,17 @@ trust_group = cfg.OptGroup(name='trust',
18 18
                            title='Trustee options for the magnum services')
19 19
 
20 20
 trust_opts = [
21
+    cfg.BoolOpt('cluster_user_trust',
22
+                default=False,
23
+                help=_('This setting controls whether to assign a trust to'
24
+                       ' the cluster user or not. You will need to set it to'
25
+                       ' True for clusters with volume_driver=cinder or'
26
+                       ' registry_enabled=true in the underlying cluster'
27
+                       ' template to work. This is a potential security risk'
28
+                       ' since the trust gives instances OpenStack API access'
29
+                       " to the cluster's project. Note that this setting"
30
+                       ' does not affect per-cluster trusts assigned to the'
31
+                       'Magnum service user.')),
21 32
     cfg.StrOpt('trustee_domain_id',
22 33
                help=_('Id of the domain to create trustee for clusters')),
23 34
     cfg.StrOpt('trustee_domain_name',

+ 16
- 1
magnum/db/sqlalchemy/api.py View File

@@ -26,6 +26,8 @@ from sqlalchemy.orm.exc import MultipleResultsFound
26 26
 from sqlalchemy.orm.exc import NoResultFound
27 27
 from sqlalchemy.sql import func
28 28
 
29
+from magnum.common import clients
30
+from magnum.common import context as request_context
29 31
 from magnum.common import exception
30 32
 import magnum.conf
31 33
 from magnum.db import api
@@ -122,8 +124,21 @@ class Connection(api.Connection):
122 124
         if context.is_admin and context.all_tenants:
123 125
             return query
124 126
 
125
-        if context.project_id:
127
+        admin_context = request_context.make_admin_context(all_tenants=True)
128
+        osc = clients.OpenStackClients(admin_context)
129
+        kst = osc.keystone()
130
+
131
+        # User in a regular project (not in the trustee domain)
132
+        if context.project_id and context.domain_id != kst.trustee_domain_id:
126 133
             query = query.filter_by(project_id=context.project_id)
134
+        # Match project ID component in trustee user's user name against
135
+        # cluster's project_id to associate per-cluster trustee users who have
136
+        # no project information with the project their clusters/cluster models
137
+        # reside in. This is equivalent to the project filtering above.
138
+        elif context.domain_id == kst.trustee_domain_id:
139
+            user_name = kst.client.users.get(context.user_id).name
140
+            user_project = user_name.split('_', 2)[1]
141
+            query = query.filter_by(project_id=user_project)
127 142
         else:
128 143
             query = query.filter_by(user_id=context.user_id)
129 144
 

+ 0
- 5
magnum/drivers/common/templates/kubernetes/fragments/make-cert-client.sh View File

@@ -49,11 +49,6 @@ auth_json=$(cat << EOF
49 49
                     "password": "$TRUSTEE_PASSWORD"
50 50
                 }
51 51
             }
52
-        },
53
-        "scope": {
54
-            "OS-TRUST:trust": {
55
-                "id": "$TRUST_ID"
56
-            }
57 52
         }
58 53
     }
59 54
 }

+ 0
- 5
magnum/drivers/common/templates/kubernetes/fragments/make-cert.sh View File

@@ -71,11 +71,6 @@ auth_json=$(cat << EOF
71 71
                     "password": "$TRUSTEE_PASSWORD"
72 72
                 }
73 73
             }
74
-        },
75
-        "scope": {
76
-            "OS-TRUST:trust": {
77
-                "id": "$TRUST_ID"
78
-            }
79 74
         }
80 75
     }
81 76
 }

+ 1
- 1
magnum/drivers/common/templates/kubernetes/fragments/write-heat-params-master.yaml View File

@@ -3,7 +3,7 @@ merge_how: dict(recurse_array)+list(append)
3 3
 write_files:
4 4
   - path: /etc/sysconfig/heat-params
5 5
     owner: "root:root"
6
-    permissions: "0644"
6
+    permissions: "0600"
7 7
     content: |
8 8
       KUBE_API_PUBLIC_ADDRESS="$KUBE_API_PUBLIC_ADDRESS"
9 9
       KUBE_API_PRIVATE_ADDRESS="$KUBE_API_PRIVATE_ADDRESS"

+ 1
- 1
magnum/drivers/common/templates/kubernetes/fragments/write-heat-params.yaml View File

@@ -3,7 +3,7 @@ merge_how: dict(recurse_array)+list(append)
3 3
 write_files:
4 4
   - path: /etc/sysconfig/heat-params
5 5
     owner: "root:root"
6
-    permissions: "0644"
6
+    permissions: "0600"
7 7
     content: |
8 8
       KUBE_ALLOW_PRIV="$KUBE_ALLOW_PRIV"
9 9
       KUBE_MASTER_IP="$KUBE_MASTER_IP"

+ 0
- 6
magnum/drivers/common/templates/swarm/fragments/make-cert.py View File

@@ -150,11 +150,6 @@ def get_user_token(config):
150 150
                     "password": "%(trustee_password)s"
151 151
                 }
152 152
             }
153
-        },
154
-        "scope": {
155
-            "OS-TRUST:trust": {
156
-                "id": "%(trust_id)s"
157
-            }
158 153
         }
159 154
     }
160 155
 }
@@ -162,7 +157,6 @@ def get_user_token(config):
162 157
     params = {
163 158
         'trustee_user_id': config['TRUSTEE_USER_ID'],
164 159
         'trustee_password': config['TRUSTEE_PASSWORD'],
165
-        'trust_id': config['TRUST_ID']
166 160
     }
167 161
     creds = creds_str % params
168 162
     headers = {'Content-Type': 'application/json'}

+ 1
- 1
magnum/drivers/common/templates/swarm/fragments/write-heat-params-master.yaml View File

@@ -3,7 +3,7 @@ merge_how: dict(recurse_array)+list(append)
3 3
 write_files:
4 4
   - path: /etc/sysconfig/heat-params
5 5
     owner: "root:root"
6
-    permissions: "0644"
6
+    permissions: "0600"
7 7
     content: |
8 8
       WAIT_HANDLE_ENDPOINT="$WAIT_HANDLE_ENDPOINT"
9 9
       WAIT_HANDLE_TOKEN="$WAIT_HANDLE_TOKEN"

+ 1
- 1
magnum/drivers/common/templates/swarm/fragments/write-heat-params-node.yaml View File

@@ -3,7 +3,7 @@ merge_how: dict(recurse_array)+list(append)
3 3
 write_files:
4 4
   - path: /etc/sysconfig/heat-params
5 5
     owner: "root:root"
6
-    permissions: "0644"
6
+    permissions: "0600"
7 7
     content: |
8 8
       WAIT_HANDLE_ENDPOINT="$WAIT_HANDLE_ENDPOINT"
9 9
       WAIT_HANDLE_TOKEN="$WAIT_HANDLE_TOKEN"

+ 15
- 1
magnum/drivers/heat/template_def.py View File

@@ -21,6 +21,7 @@ import six
21 21
 from magnum.common import clients
22 22
 from magnum.common import exception
23 23
 import magnum.conf
24
+from magnum.i18n import _LE
24 25
 from magnum.i18n import _LW
25 26
 
26 27
 from requests import exceptions as req_exceptions
@@ -245,7 +246,20 @@ class BaseTemplateDefinition(TemplateDefinition):
245 246
         extra_params['trustee_user_id'] = cluster.trustee_user_id
246 247
         extra_params['trustee_username'] = cluster.trustee_username
247 248
         extra_params['trustee_password'] = cluster.trustee_password
248
-        extra_params['trust_id'] = cluster.trust_id
249
+
250
+        # Only pass trust ID into the template when it is needed.
251
+        if (cluster_template.volume_driver == 'rexray' or
252
+                cluster_template.registry_enabled):
253
+            if CONF.trust.cluster_user_trust:
254
+                extra_params['trust_id'] = cluster.trust_id
255
+            else:
256
+                missing_setting = ('trust/cluster_user_trust = True')
257
+                msg = _LE('This cluster can only be created with %s in '
258
+                          'magnum.conf')
259
+                raise exception.ConfigInvalid(msg % missing_setting)
260
+        else:
261
+            extra_params['trust_id'] = ""
262
+
249 263
         extra_params['auth_url'] = context.auth_url
250 264
 
251 265
         return super(BaseTemplateDefinition,

+ 0
- 5
magnum/drivers/k8s_coreos_v1/templates/fragments/make-cert-client.yaml View File

@@ -63,11 +63,6 @@ write_files:
63 63
                           "password": "$TRUSTEE_PASSWORD"
64 64
                       }
65 65
                   }
66
-              },
67
-              "scope": {
68
-                  "OS-TRUST:trust": {
69
-                      "id": "$TRUST_ID"
70
-                  }
71 66
               }
72 67
           }
73 68
       }

+ 0
- 5
magnum/drivers/k8s_coreos_v1/templates/fragments/make-cert.yaml View File

@@ -86,11 +86,6 @@ write_files:
86 86
                           "password": "$TRUSTEE_PASSWORD"
87 87
                       }
88 88
                   }
89
-              },
90
-              "scope": {
91
-                  "OS-TRUST:trust": {
92
-                      "id": "$TRUST_ID"
93
-                  }
94 89
               }
95 90
           }
96 91
       }

+ 1
- 1
magnum/drivers/k8s_coreos_v1/templates/fragments/write-heat-params-master.yaml View File

@@ -3,7 +3,7 @@ merge_how: dict(recurse_array)+list(append)
3 3
 write_files:
4 4
   - path: /etc/sysconfig/heat-params
5 5
     owner: "root:root"
6
-    permissions: "0644"
6
+    permissions: "0600"
7 7
     content: |
8 8
       KUBE_API_PUBLIC_ADDRESS="$KUBE_API_PUBLIC_ADDRESS"
9 9
       KUBE_API_PRIVATE_ADDRESS="$KUBE_API_PRIVATE_ADDRESS"

+ 1
- 1
magnum/drivers/k8s_coreos_v1/templates/fragments/write-heat-params.yaml View File

@@ -3,7 +3,7 @@ merge_how: dict(recurse_array)+list(append)
3 3
 write_files:
4 4
   - path: /etc/sysconfig/heat-params
5 5
     owner: "root:root"
6
-    permissions: "0644"
6
+    permissions: "0600"
7 7
     content: |
8 8
       KUBE_ALLOW_PRIV="$KUBE_ALLOW_PRIV"
9 9
       KUBE_MASTER_IP="$KUBE_MASTER_IP"

+ 1
- 1
magnum/drivers/mesos_ubuntu_v1/templates/fragments/write-heat-params.yaml View File

@@ -3,7 +3,7 @@ merge_how: dict(recurse_array)+list(append)
3 3
 write_files:
4 4
   - path: /etc/sysconfig/heat-params
5 5
     owner: "root:root"
6
-    permissions: "0644"
6
+    permissions: "0600"
7 7
     content: |
8 8
       MESOS_MASTERS_IPS="$MESOS_MASTERS_IPS"
9 9
       EXECUTOR_REGISTRATION_TIMEOUT="$EXECUTOR_REGISTRATION_TIMEOUT"

+ 27
- 0
magnum/tests/base.py View File

@@ -26,6 +26,7 @@ import pecan
26 26
 import testscenarios
27 27
 
28 28
 from magnum.common import context as magnum_context
29
+from magnum.common import keystone as magnum_keystone
29 30
 from magnum.objects import base as objects_base
30 31
 from magnum.tests import conf_fixture
31 32
 from magnum.tests import fake_notifier
@@ -63,11 +64,18 @@ class TestCase(base.BaseTestCase):
63 64
                 }
64 65
             }
65 66
         }
67
+
68
+        trustee_domain_id = '12345678-9012-3456-7890-123456789abc'
69
+
66 70
         self.context = magnum_context.RequestContext(
67 71
             auth_token_info=token_info,
68 72
             project_id='fake_project',
69 73
             user_id='fake_user')
70 74
 
75
+        self.global_mocks = {}
76
+
77
+        self.keystone_client = magnum_keystone.KeystoneClientV3(self.context)
78
+
71 79
         self.policy = self.useFixture(policy_fixture.PolicyFixture())
72 80
 
73 81
         self.useFixture(fixtures.MockPatchObject(
@@ -89,9 +97,22 @@ class TestCase(base.BaseTestCase):
89 97
 
90 98
         p = mock.patch.object(magnum_context, 'make_context',
91 99
                               side_effect=make_context)
100
+
101
+        self.global_mocks['magnum.common.context.make_context'] = p
102
+
103
+        q = mock.patch.object(magnum_keystone.KeystoneClientV3,
104
+                              'trustee_domain_id',
105
+                              return_value=trustee_domain_id)
106
+
107
+        self.global_mocks[
108
+            'magnum.common.keystone.KeystoneClientV3.trustee_domain_id'] = q
109
+
92 110
         self.mock_make_context = p.start()
93 111
         self.addCleanup(p.stop)
94 112
 
113
+        self.mock_make_trustee_domain_id = q.start()
114
+        self.addCleanup(q.stop)
115
+
95 116
         self.useFixture(conf_fixture.ConfFixture())
96 117
         self.useFixture(fixtures.NestedTempfile())
97 118
 
@@ -104,6 +125,12 @@ class TestCase(base.BaseTestCase):
104 125
 
105 126
         self.addCleanup(reset_pecan)
106 127
 
128
+    def start_global(self, name):
129
+        self.global_mocks[name].start()
130
+
131
+    def stop_global(self, name):
132
+        self.global_mocks[name].stop()
133
+
107 134
     def _restore_obj_registry(self):
108 135
         objects_base.MagnumObjectRegistry._registry._obj_classes \
109 136
             = self._base_test_obj_backup

+ 15
- 0
magnum/tests/unit/common/test_keystone.py View File

@@ -55,6 +55,19 @@ class KeystoneClientTest(base.TestCase):
55 55
                     admin_tenant_name='service',
56 56
                     group=ksconf.CFG_LEGACY_GROUP)
57 57
 
58
+        # Disable global mocking for trustee_domain_id
59
+        self.stop_global(
60
+            'magnum.common.keystone.KeystoneClientV3.trustee_domain_id')
61
+
62
+    def tearDown(self):
63
+        # Re-enable global mocking for trustee_domain_id. We need this because
64
+        # mock blows up when trying to stop an already stopped patch (which it
65
+        # will do due to the addCleanup() in base.TestCase).
66
+        self.start_global(
67
+            'magnum.common.keystone.KeystoneClientV3.trustee_domain_id')
68
+
69
+        super(KeystoneClientTest, self).tearDown()
70
+
58 71
     def test_client_with_password(self, mock_ks):
59 72
         self.ctx.is_admin = True
60 73
         ks_client = keystone.KeystoneClientV3(self.ctx)
@@ -136,6 +149,7 @@ class KeystoneClientTest(base.TestCase):
136 149
         ks_client.create_trust(trustee_user='888888')
137 150
 
138 151
         mock_ks.return_value.trusts.create.assert_called_once_with(
152
+            delegation_depth=0,
139 153
             trustor_user='123456', project='654321',
140 154
             trustee_user='888888', role_names=['role1', 'role2'],
141 155
             impersonation=True)
@@ -152,6 +166,7 @@ class KeystoneClientTest(base.TestCase):
152 166
         ks_client.create_trust(trustee_user='888888')
153 167
 
154 168
         mock_ks.return_value.trusts.create.assert_called_once_with(
169
+            delegation_depth=0,
155 170
             trustor_user='123456', project='654321',
156 171
             trustee_user='888888', role_names=['role3'],
157 172
             impersonation=True)

+ 2
- 1
magnum/tests/unit/conductor/handlers/common/test_trust_manager.py View File

@@ -37,6 +37,7 @@ class TrustManagerTestCase(base.BaseTestCase):
37 37
         mock_generate_password.return_value = mock_password
38 38
         mock_cluster = mock.MagicMock()
39 39
         mock_cluster.uuid = 'mock_cluster_uuid'
40
+        mock_cluster.project_id = 'mock_cluster_project_id'
40 41
         mock_keystone = mock.MagicMock()
41 42
         mock_trustee = mock.MagicMock()
42 43
         mock_trustee.id = 'mock_trustee_id'
@@ -52,7 +53,7 @@ class TrustManagerTestCase(base.BaseTestCase):
52 53
         trust_manager.create_trustee_and_trust(self.osc, mock_cluster)
53 54
 
54 55
         mock_keystone.create_trustee.assert_called_once_with(
55
-            mock_cluster.uuid,
56
+            '%s_%s' % (mock_cluster.uuid, mock_cluster.project_id),
56 57
             mock_password,
57 58
         )
58 59
         mock_keystone.create_trust.assert_called_once_with(

+ 5
- 0
magnum/tests/unit/conductor/handlers/test_cluster_conductor.py View File

@@ -181,6 +181,11 @@ class TestHandler(db_base.DbTestCase):
181 181
         mock_poller.poll_and_check.return_value = loopingcall.LoopingCallDone()
182 182
         mock_heat_poller_class.return_value = mock_poller
183 183
         osc = mock.sentinel.osc
184
+
185
+        def return_keystone():
186
+            return self.keystone_client
187
+
188
+        osc.keystone = return_keystone
184 189
         mock_openstack_client_class.return_value = osc
185 190
         mock_dr = mock.MagicMock()
186 191
         mock_driver.return_value = mock_dr

+ 9
- 5
magnum/tests/unit/conductor/handlers/test_k8s_cluster_conductor.py View File

@@ -194,7 +194,7 @@ class TestClusterConductorWithK8s(base.TestCase):
194 194
             'trustee_username': 'fake_trustee',
195 195
             'trustee_password': 'fake_trustee_password',
196 196
             'trustee_user_id': '7b489f04-b458-4541-8179-6a48a553e656',
197
-            'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de',
197
+            'trust_id': '',
198 198
             'auth_url': 'http://192.168.10.10:5000/v3',
199 199
             'insecure_registry_url': '10.0.0.1:5000',
200 200
             'kube_version': 'fake-version',
@@ -236,6 +236,10 @@ class TestClusterConductorWithK8s(base.TestCase):
236 236
                           'RegionOne',
237 237
                           group='docker_registry')
238 238
 
239
+        CONF.set_override('cluster_user_trust',
240
+                          True,
241
+                          group='trust')
242
+
239 243
         (template_path,
240 244
          definition,
241 245
          env_files) = mock_driver()._extract_template_definition(self.context,
@@ -350,7 +354,7 @@ class TestClusterConductorWithK8s(base.TestCase):
350 354
             'ssh_key_name': 'keypair_id',
351 355
             'tenant_name': 'fake_tenant',
352 356
             'tls_disabled': False,
353
-            'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de',
357
+            'trust_id': '',
354 358
             'trustee_domain_id': 'trustee_domain_id',
355 359
             'trustee_password': 'fake_trustee_password',
356 360
             'trustee_user_id': '7b489f04-b458-4541-8179-6a48a553e656',
@@ -421,7 +425,7 @@ class TestClusterConductorWithK8s(base.TestCase):
421 425
             'trustee_username': 'fake_trustee',
422 426
             'trustee_password': 'fake_trustee_password',
423 427
             'trustee_user_id': '7b489f04-b458-4541-8179-6a48a553e656',
424
-            'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de',
428
+            'trust_id': '',
425 429
             'auth_url': 'http://192.168.10.10:5000/v3',
426 430
             'cluster_uuid': self.cluster_dict['uuid'],
427 431
             'magnum_url': self.mock_osc.magnum_url.return_value,
@@ -488,7 +492,7 @@ class TestClusterConductorWithK8s(base.TestCase):
488 492
             'trustee_username': 'fake_trustee',
489 493
             'trustee_password': 'fake_trustee_password',
490 494
             'trustee_user_id': '7b489f04-b458-4541-8179-6a48a553e656',
491
-            'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de',
495
+            'trust_id': '',
492 496
             'auth_url': 'http://192.168.10.10:5000/v3',
493 497
             'cluster_uuid': self.cluster_dict['uuid'],
494 498
             'magnum_url': self.mock_osc.magnum_url.return_value,
@@ -686,7 +690,7 @@ class TestClusterConductorWithK8s(base.TestCase):
686 690
             'trustee_username': 'fake_trustee',
687 691
             'trustee_password': 'fake_trustee_password',
688 692
             'trustee_user_id': '7b489f04-b458-4541-8179-6a48a553e656',
689
-            'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de',
693
+            'trust_id': '',
690 694
             'auth_url': 'http://192.168.10.10:5000/v3',
691 695
             'insecure_registry_url': '10.0.0.1:5000',
692 696
             'kube_version': 'fake-version',

+ 5
- 4
magnum/tests/unit/conductor/handlers/test_mesos_cluster_conductor.py View File

@@ -37,6 +37,7 @@ class TestClusterConductorWithMesos(base.TestCase):
37 37
             'http_proxy': 'http_proxy',
38 38
             'https_proxy': 'https_proxy',
39 39
             'no_proxy': 'no_proxy',
40
+            'registry_enabled': False,
40 41
             'server_type': 'vm',
41 42
             'volume_driver': 'volume_driver',
42 43
             'labels': {'rexray_preempt': 'False',
@@ -117,7 +118,7 @@ class TestClusterConductorWithMesos(base.TestCase):
117 118
             'trustee_username': 'fake_trustee',
118 119
             'trustee_password': 'fake_trustee_password',
119 120
             'trustee_user_id': '7b489f04-b458-4541-8179-6a48a553e656',
120
-            'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de',
121
+            'trust_id': '',
121 122
             'volume_driver': 'volume_driver',
122 123
             'auth_url': 'http://192.168.10.10:5000/v3',
123 124
             'region_name': self.mock_osc.cinder_region_name.return_value,
@@ -171,7 +172,7 @@ class TestClusterConductorWithMesos(base.TestCase):
171 172
             'trustee_username': 'fake_trustee',
172 173
             'trustee_password': 'fake_trustee_password',
173 174
             'trustee_user_id': '7b489f04-b458-4541-8179-6a48a553e656',
174
-            'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de',
175
+            'trust_id': '',
175 176
             'auth_url': 'http://192.168.10.10:5000/v3',
176 177
             'region_name': self.mock_osc.cinder_region_name.return_value,
177 178
             'username': 'mesos_user',
@@ -227,7 +228,7 @@ class TestClusterConductorWithMesos(base.TestCase):
227 228
             'trustee_username': 'fake_trustee',
228 229
             'trustee_password': 'fake_trustee_password',
229 230
             'trustee_user_id': '7b489f04-b458-4541-8179-6a48a553e656',
230
-            'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de',
231
+            'trust_id': '',
231 232
             'volume_driver': 'volume_driver',
232 233
             'auth_url': 'http://192.168.10.10:5000/v3',
233 234
             'region_name': self.mock_osc.cinder_region_name.return_value,
@@ -285,7 +286,7 @@ class TestClusterConductorWithMesos(base.TestCase):
285 286
             'trustee_username': 'fake_trustee',
286 287
             'trustee_password': 'fake_trustee_password',
287 288
             'trustee_user_id': '7b489f04-b458-4541-8179-6a48a553e656',
288
-            'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de',
289
+            'trust_id': '',
289 290
             'volume_driver': 'volume_driver',
290 291
             'auth_url': 'http://192.168.10.10:5000/v3',
291 292
             'region_name': self.mock_osc.cinder_region_name.return_value,

+ 7
- 1
magnum/tests/unit/conductor/handlers/test_swarm_cluster_conductor.py View File

@@ -74,6 +74,12 @@ class TestClusterConductorWithSwarm(base.TestCase):
74 74
             'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de',
75 75
             'coe_version': 'fake-version'
76 76
         }
77
+
78
+        # We need this due to volume_driver=rexray
79
+        CONF.set_override('cluster_user_trust',
80
+                          True,
81
+                          group='trust')
82
+
77 83
         osc_patcher = mock.patch('magnum.common.clients.OpenStackClients')
78 84
         self.mock_osc_class = osc_patcher.start()
79 85
         self.addCleanup(osc_patcher.stop)
@@ -280,7 +286,7 @@ class TestClusterConductorWithSwarm(base.TestCase):
280 286
             'trustee_username': 'fake_trustee',
281 287
             'trustee_password': 'fake_trustee_password',
282 288
             'trustee_user_id': '7b489f04-b458-4541-8179-6a48a553e656',
283
-            'trust_id': 'bd11efc5-d4e2-4dac-bbce-25e348ddf7de',
289
+            'trust_id': '',
284 290
             'auth_url': 'http://192.168.10.10:5000/v3',
285 291
             'swarm_version': 'fake-version',
286 292
             'swarm_strategy': u'spread',

Loading…
Cancel
Save