1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
: Copyright (c) 2017 Mirantis Inc., Enea AB and others.
:
: All rights reserved. This program and the accompanying materials
: are made available under the terms of the Apache License, Version 2.0
: which accompanies this distribution, and is available at
: http://www.apache.org/licenses/LICENSE-2.0
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
From: Alexandru Avadanii <Alexandru.Avadanii@enea.com>
Date: Wed, 3 Jan 2018 00:50:50 +0100
Subject: [PATCH] controller: Use keystoneclient to check project ID
Port fix from [1] for using the internal network when connecting
to keystone during project ID validation in nova, instead of
going through public endpoint (and using SSL).
[1] https://bugs.launchpad.net/nova/+bug/1716344
Signed-off-by: Alexandru Avadanii <Alexandru.Avadanii@enea.com>
---
nova/controller.sls | 10 ++
...keystoneclient-to-check-project-ID-exists.patch | 116 +++++++++++++++++++++
2 files changed, 126 insertions(+)
create mode 100644 nova/files/0001-Use-keystoneclient-to-check-project-ID-exists.patch
diff --git a/nova/controller.sls b/nova/controller.sls
index a55d037..59af945 100644
--- a/nova/controller.sls
+++ b/nova/controller.sls
@@ -71,6 +71,16 @@ contrail_nova_packages:
{%- endif %}
+nova-api-openstack-identity-patch:
+ file.patch:
+ - name: /usr/lib/python2.7/dist-packages
+ - source: salt://nova/files/0001-Use-keystoneclient-to-check-project-ID-exists.patch
+ - hash: False
+ - options: '-p1'
+ - unless: 'test -f /var/cache/salt/minion/files/base/nova/files/0001-Use-keystoneclient-to-check-project-ID-exists.patch && cd /usr/lib/python2.7/dist-packages && patch -p1 -R --dry-run /var/cache/salt/minion/files/base/nova/files/0001-Use-keystoneclient-to-check-project-ID-exists.patch'
+ - require:
+ - pkg: nova_controller_packages
+
/etc/nova/nova.conf:
file.managed:
- source: salt://nova/files/{{ controller.version }}/nova-controller.conf.{{ grains.os_family }}
diff --git a/nova/files/0001-Use-keystoneclient-to-check-project-ID-exists.patch b/nova/files/0001-Use-keystoneclient-to-check-project-ID-exists.patch
new file mode 100644
index 0000000..58d027e
--- /dev/null
+++ b/nova/files/0001-Use-keystoneclient-to-check-project-ID-exists.patch
@@ -0,0 +1,116 @@
+From: Christoph Fiehe <fiehe@gmx.de>
+Date: Wed, 3 Jan 2018 00:11:20 +0100
+Subject: [PATCH] Use keystoneclient to check project ID exists
+
+Based on Christoph's implementation proposed in [1].
+
+[1] https://bugs.launchpad.net/nova/+bug/1716344
+
+Signed-off-by: Alexandru Avadanii <Alexandru.Avadanii@enea.com>
+---
+ nova/api/openstack/identity.py | 81 ++++++++++++++++--------------------------
+ 1 file changed, 30 insertions(+), 51 deletions(-)
+
+diff --git a/nova/api/openstack/identity.py b/nova/api/openstack/identity.py
+index 833d3b5..3269cec 100644
+--- a/nova/api/openstack/identity.py
++++ b/nova/api/openstack/identity.py
+@@ -12,16 +12,15 @@
+ # License for the specific language governing permissions and limitations
+ # under the License.
+
+-from keystoneauth1 import exceptions as kse
+-from keystoneauth1 import loading as ks_loading
++from keystoneauth1 import session
++from keystoneclient import exceptions as kse
++from keystoneclient.v3 import client
+ from oslo_log import log as logging
+ import webob
+
+-import nova.conf
+ from nova.i18n import _
+
+
+-CONF = nova.conf.CONF
+ LOG = logging.getLogger(__name__)
+
+
+@@ -32,51 +31,31 @@ def verify_project_id(context, project_id):
+ an HTTPBadRequest is emitted.
+
+ """
+- sess = ks_loading.load_session_from_conf_options(
+- CONF, 'keystone', auth=context.get_auth_plugin())
+-
+- failure = webob.exc.HTTPBadRequest(
+- explanation=_("Project ID %s is not a valid project.") %
+- project_id)
++ auth = context.get_auth_plugin()
++ sess = session.Session(auth=auth)
++ keystone = client.Client(session=sess)
+ try:
+- resp = sess.get('/projects/%s' % project_id,
+- endpoint_filter={
+- 'service_type': 'identity',
+- 'version': (3, 0)
+- },
+- raise_exc=False)
+- except kse.EndpointNotFound:
+- LOG.error(
+- "Keystone identity service version 3.0 was not found. This might "
+- "be because your endpoint points to the v2.0 versioned endpoint "
+- "which is not supported. Please fix this.")
+- raise failure
+- except kse.ClientException:
+- # something is wrong, like there isn't a keystone v3 endpoint,
+- # we'll take the pass and default to everything being ok.
+- LOG.exception("Unable to contact keystone to verify project_id")
+- return True
+-
+- if resp:
+- # All is good with this 20x status
+- return True
+- elif resp.status_code == 404:
+- # we got access, and we know this project is not there
+- raise failure
+- elif resp.status_code == 403:
+- # we don't have enough permission to verify this, so default
+- # to "it's ok".
+- LOG.info(
+- "Insufficient permissions for user %(user)s to verify "
+- "existence of project_id %(pid)s",
+- {"user": context.user_id, "pid": project_id})
+- return True
+- else:
+- LOG.warning(
+- "Unexpected response from keystone trying to "
+- "verify project_id %(pid)s - resp: %(code)s %(content)s",
+- {"pid": project_id,
+- "code": resp.status_code,
+- "content": resp.content})
+- # realize we did something wrong, but move on with a warning
+- return True
++ project = keystone.projects.get(project_id)
++ except kse.ClientException as e:
++ if e.http_status == 404:
++ # we got access, and we know this project is not there
++ raise webob.exc.HTTPBadRequest(
++ explanation=_("Project ID %s is not a valid project.") %
++ project_id)
++ elif e.http_status == 403:
++ # we don't have enough permission to verify this, so default
++ # to "it's ok".
++ LOG.info(
++ "Insufficient permissions for user %(user)s to verify "
++ "existence of project_id %(pid)s",
++ {"user": context.user_id, "pid": project_id})
++ return True
++ else:
++ LOG.warning(
++ "Unexpected response from keystone trying to "
++ "verify project_id %(pid)s - resp: %(code)s %(content)s",
++ {"pid": project_id,
++ "code": resp.status_code,
++ "content": resp.content})
++ # realize we did something wrong, but move on with a warning
++ return True
|