summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2018-05-18 16:03:12 +0000
committerGerrit Code Review <review@openstack.org>2018-05-18 16:03:13 +0000
commit4a9fd8fa9aed62efaa7a3f327a99c177df606321 (patch)
tree2ba56c4cbe5f78c95d3414a97ba20aa3ab1a6ddf
parent40bca5e574d05bb8ab00bac6bd941abd667651e7 (diff)
parent73361b4069ea3fe9d96698e3ea6458756206f616 (diff)
downloadheat-4a9fd8fa9aed62efaa7a3f327a99c177df606321.tar.gz
Merge "Generate user passwords with special characters" into stable/ocata
-rw-r--r--heat/common/password_gen.py8
-rw-r--r--heat/engine/clients/os/keystone/heat_keystoneclient.py5
-rw-r--r--heat/engine/resources/openstack/heat/wait_condition_handle.py5
-rw-r--r--heat/engine/resources/server_base.py3
-rw-r--r--heat/engine/resources/signal_responder.py7
-rw-r--r--heat/tests/clients/test_heat_client.py21
6 files changed, 29 insertions, 20 deletions
diff --git a/heat/common/password_gen.py b/heat/common/password_gen.py
index 93b03c6b9..52d5a3a24 100644
--- a/heat/common/password_gen.py
+++ b/heat/common/password_gen.py
@@ -107,3 +107,11 @@ def generate_password(length, char_classes):
selected_chars = char_buffer.getvalue()
char_buffer.close()
return ''.join(random.sample(selected_chars, length))
+
+
+def generate_openstack_password():
+ """Generate a random password suitable for a Keystone User."""
+ return generate_password(32, [named_char_class(LOWERCASE, 1),
+ named_char_class(UPPERCASE, 1),
+ named_char_class(DIGITS, 1),
+ special_char_class('!@#%^&*', 1)])
diff --git a/heat/engine/clients/os/keystone/heat_keystoneclient.py b/heat/engine/clients/os/keystone/heat_keystoneclient.py
index 4f40c0252..a03aeb2c9 100644
--- a/heat/engine/clients/os/keystone/heat_keystoneclient.py
+++ b/heat/engine/clients/os/keystone/heat_keystoneclient.py
@@ -31,6 +31,7 @@ from heat.common import exception
from heat.common.i18n import _
from heat.common.i18n import _LE
from heat.common.i18n import _LW
+from heat.common import password_gen
LOG = logging.getLogger('heat.engine.clients.keystoneclient')
@@ -479,7 +480,7 @@ class KsClientWrapper(object):
user_id = user_id or self.context.get_access(self.session).user_id
project_id = self.context.tenant_id
data_blob = {'access': uuid.uuid4().hex,
- 'secret': uuid.uuid4().hex}
+ 'secret': password_gen.generate_openstack_password()}
ec2_creds = self.client.credentials.create(
user=user_id, type='ec2', blob=jsonutils.dumps(data_blob),
project=project_id)
@@ -498,7 +499,7 @@ class KsClientWrapper(object):
# files which lack domain configuration
return self.create_ec2_keypair(user_id)
data_blob = {'access': uuid.uuid4().hex,
- 'secret': uuid.uuid4().hex}
+ 'secret': password_gen.generate_openstack_password()}
creds = self.domain_admin_client.credentials.create(
user=user_id, type='ec2', blob=jsonutils.dumps(data_blob),
project=project_id)
diff --git a/heat/engine/resources/openstack/heat/wait_condition_handle.py b/heat/engine/resources/openstack/heat/wait_condition_handle.py
index c22a4f7bc..481acdee0 100644
--- a/heat/engine/resources/openstack/heat/wait_condition_handle.py
+++ b/heat/engine/resources/openstack/heat/wait_condition_handle.py
@@ -11,11 +11,10 @@
# License for the specific language governing permissions and limitations
# under the License.
-import uuid
-
from oslo_serialization import jsonutils
from heat.common.i18n import _
+from heat.common import password_gen
from heat.engine import attributes
from heat.engine import constraints
from heat.engine import properties
@@ -135,7 +134,7 @@ class HeatWaitConditionHandle(wc_base.BaseWaitConditionHandle):
self.SIGNAL_TRANSPORT) == self.TOKEN_SIGNAL
def handle_create(self):
- self.password = uuid.uuid4().hex
+ self.password = password_gen.generate_openstack_password()
super(HeatWaitConditionHandle, self).handle_create()
if self._signal_transport_token():
# FIXME(shardy): The assumption here is that token expiry > timeout
diff --git a/heat/engine/resources/server_base.py b/heat/engine/resources/server_base.py
index cd0097ec8..3e1bb2d7a 100644
--- a/heat/engine/resources/server_base.py
+++ b/heat/engine/resources/server_base.py
@@ -19,6 +19,7 @@ from oslo_serialization import jsonutils
from heat.common import exception
from heat.common.i18n import _LE
+from heat.common import password_gen
from heat.engine.clients import progress
from heat.engine.resources import stack_user
@@ -138,7 +139,7 @@ class BaseServer(stack_user.StackUser):
elif (self.transport_poll_server_heat(props) or
self.transport_zaqar_message(props)):
if self.password is None:
- self.password = uuid.uuid4().hex
+ self.password = password_gen.generate_openstack_password()
self._create_user()
self._register_access_key()
diff --git a/heat/engine/resources/signal_responder.py b/heat/engine/resources/signal_responder.py
index 28a8ab9b9..6fa58c545 100644
--- a/heat/engine/resources/signal_responder.py
+++ b/heat/engine/resources/signal_responder.py
@@ -11,8 +11,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import uuid
-
from keystoneclient.contrib.ec2 import utils as ec2_utils
from oslo_config import cfg
from oslo_log import log as logging
@@ -22,6 +20,7 @@ from six.moves.urllib import parse as urlparse
from heat.common import exception
from heat.common.i18n import _
from heat.common.i18n import _LW
+from heat.common import password_gen
from heat.engine.clients.os import swift
from heat.engine.resources import stack_user
@@ -103,7 +102,7 @@ class SignalResponder(stack_user.StackUser):
"""
if self._get_user_id() is None:
if self.password is None:
- self.password = uuid.uuid4().hex
+ self.password = password_gen.generate_openstack_password()
self._create_user()
return {'auth_url': self.keystone().v3_endpoint,
'username': self.physical_resource_name(),
@@ -286,7 +285,7 @@ class SignalResponder(stack_user.StackUser):
if self._get_user_id() is None:
if self.password is None:
- self.password = uuid.uuid4().hex
+ self.password = password_gen.generate_openstack_password()
self._create_user()
queue_id = self.physical_resource_name()
diff --git a/heat/tests/clients/test_heat_client.py b/heat/tests/clients/test_heat_client.py
index ff0a8b849..6b3f7f1c2 100644
--- a/heat/tests/clients/test_heat_client.py
+++ b/heat/tests/clients/test_heat_client.py
@@ -12,6 +12,7 @@
# under the License.
import json
+import mock
import uuid
from keystoneauth1 import access as ks_access
@@ -29,6 +30,7 @@ import six
from heat.common import config
from heat.common import exception
+from heat.common import password_gen
from heat.engine.clients.os.keystone import heat_keystoneclient
from heat.tests import common
from heat.tests import utils
@@ -995,14 +997,13 @@ class KeystoneClientTest(common.HeatTestCase):
user_id='duser123', project_id='aproject',
credential_id='acredentialid')
- def _stub_uuid(self, values=None):
+ def _stub_gen_creds(self, access, secret):
# stub UUID.hex to return the values specified
- values = values or []
- self.m.StubOutWithMock(uuid, 'uuid4')
- for v in values:
- mock_uuid = self.m.CreateMockAnything()
- mock_uuid.hex = v
- uuid.uuid4().AndReturn(mock_uuid)
+ mock_access_uuid = mock.Mock()
+ mock_access_uuid.hex = access
+ self.patchobject(uuid, 'uuid4', return_value=mock_access_uuid)
+ self.patchobject(password_gen, 'generate_openstack_password',
+ return_value=secret)
def test_create_ec2_keypair(self):
@@ -1018,7 +1019,7 @@ class KeystoneClientTest(common.HeatTestCase):
ex_data_json = json.dumps(ex_data)
# stub UUID.hex to match ex_data
- self._stub_uuid(['dummy_access', 'dummy_secret'])
+ self._stub_gen_creds('dummy_access', 'dummy_secret')
# mock keystone client credentials functions
self.mock_ks_v3_client.credentials = self.m.CreateMockAnything()
@@ -1054,7 +1055,7 @@ class KeystoneClientTest(common.HeatTestCase):
ex_data_json = json.dumps(ex_data)
# stub UUID.hex to match ex_data
- self._stub_uuid(['dummy_access2', 'dummy_secret2'])
+ self._stub_gen_creds('dummy_access2', 'dummy_secret2')
# mock keystone client credentials functions
self.mock_admin_client.credentials = self.m.CreateMockAnything()
@@ -1091,7 +1092,7 @@ class KeystoneClientTest(common.HeatTestCase):
ex_data_json = json.dumps(ex_data)
# stub UUID.hex to match ex_data
- self._stub_uuid(['dummy_access2', 'dummy_secret2'])
+ self._stub_gen_creds('dummy_access2', 'dummy_secret2')
# mock keystone client credentials functions
self.mock_ks_v3_client.credentials = self.m.CreateMockAnything()