Merge "Enable H302 rule everywhere"
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 44340c3..7c70aec 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -56,6 +56,7 @@
cls.images = []
cls.multi_user = cls.get_multi_user()
cls.security_groups = []
+ cls.server_groups = []
if cls._api_version == 2:
cls.servers_client = cls.os.servers_client
@@ -191,11 +192,24 @@
LOG.exception(exc)
@classmethod
+ def clear_server_groups(cls):
+ for server_group_id in cls.server_groups:
+ try:
+ cls.client.delete_server_group(server_group_id)
+ except exceptions.NotFound:
+ # The server-group may have already been deleted which is OK.
+ pass
+ except Exception:
+ LOG.exception('Exception raised deleting server-group %s',
+ server_group_id)
+
+ @classmethod
def tearDownClass(cls):
cls.clear_images()
cls.clear_servers()
cls.clear_security_groups()
cls.clear_isolated_creds()
+ cls.clear_server_groups()
super(BaseComputeTest, cls).tearDownClass()
@classmethod
@@ -249,6 +263,16 @@
return resp, body
+ @classmethod
+ def create_test_server_group(cls, name="", policy=[]):
+ if not name:
+ name = data_utils.rand_name(cls.__name__ + "-Server-Group")
+ if not policy:
+ policy = ['affinity']
+ resp, body = cls.servers_client.create_server_group(name, policy)
+ cls.server_groups.append(body)
+ return resp, body
+
def wait_for(self, condition):
"""Repeatedly calls condition() until a timeout."""
start_time = int(time.time())
diff --git a/tempest/api/compute/servers/test_server_group.py b/tempest/api/compute/servers/test_server_group.py
new file mode 100644
index 0000000..0cd23fd
--- /dev/null
+++ b/tempest/api/compute/servers/test_server_group.py
@@ -0,0 +1,112 @@
+# Copyright 2014 NEC Technologies India Ltd.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.api.compute import base
+from tempest.common.utils import data_utils
+from tempest import test
+
+
+class ServerGroupTestJSON(base.BaseV2ComputeTest):
+ """
+ These tests check for the server-group APIs
+ They create/delete server-groups with different policies.
+ policies = affinity/anti-affinity
+ It also adds the tests for list and get details of server-groups
+ """
+ @classmethod
+ @test.safe_setup
+ def setUpClass(cls):
+ super(ServerGroupTestJSON, cls).setUpClass()
+ if not test.is_extension_enabled('os-server-groups', 'compute'):
+ msg = "os-server-groups extension is not enabled."
+ raise cls.skipException(msg)
+ cls.client = cls.servers_client
+ server_group_name = data_utils.rand_name('server-group')
+ cls.policy = ['affinity']
+
+ _, cls.created_server_group = cls.create_test_server_group(
+ server_group_name,
+ cls.policy)
+
+ def _create_server_group(self, name, policy):
+ # create the test server-group with given policy
+ server_group = {'name': name, 'policies': policy}
+ resp, body = self.create_test_server_group(name, policy)
+ self.assertEqual(200, resp.status)
+ for key in ['name', 'policies']:
+ self.assertEqual(server_group[key], body[key])
+ return body
+
+ def _delete_server_group(self, server_group):
+ # delete the test server-group
+ resp, _ = self.client.delete_server_group(server_group['id'])
+ self.assertEqual(204, resp.status)
+ # validation of server-group deletion
+ resp, server_group_list = self.client.list_server_groups()
+ self.assertEqual(200, resp.status)
+ self.assertNotIn(server_group, server_group_list)
+
+ def _create_delete_server_group(self, policy):
+ # Create and Delete the server-group with given policy
+ name = data_utils.rand_name('server-group')
+ server_group = self._create_server_group(name, policy)
+ self._delete_server_group(server_group)
+
+ @test.attr(type='gate')
+ def test_create_delete_server_group_with_affinity_policy(self):
+ # Create and Delete the server-group with affinity policy
+ self._create_delete_server_group(self.policy)
+
+ @test.attr(type='gate')
+ def test_create_delete_server_group_with_anti_affinity_policy(self):
+ # Create and Delete the server-group with anti-affinity policy
+ policy = ['anti-affinity']
+ self._create_delete_server_group(policy)
+
+ @test.attr(type='gate')
+ def test_create_delete_server_group_with_multiple_policies(self):
+ # Create and Delete the server-group with multiple policies
+ policies = ['affinity', 'affinity']
+ self._create_delete_server_group(policies)
+
+ @test.attr(type='gate')
+ def test_create_delete_multiple_server_groups_with_same_name_policy(self):
+ # Create and Delete the server-groups with same name and same policy
+ server_groups = []
+ server_group_name = data_utils.rand_name('server-group')
+ for i in range(0, 2):
+ server_groups.append(self._create_server_group(server_group_name,
+ self.policy))
+ for key in ['name', 'policies']:
+ self.assertEqual(server_groups[0][key], server_groups[1][key])
+ self.assertNotEqual(server_groups[0]['id'], server_groups[1]['id'])
+
+ for i in range(0, 2):
+ self._delete_server_group(server_groups[i])
+
+ @test.attr(type='gate')
+ def test_get_server_group(self):
+ # Get the server-group
+ resp, body = self.client.get_server_group(
+ self.created_server_group['id'])
+ self.assertEqual(200, resp.status)
+ self.assertEqual(self.created_server_group, body)
+
+ @test.attr(type='gate')
+ def test_list_server_groups(self):
+ # List the server-group
+ resp, body = self.client.list_server_groups()
+ self.assertEqual(200, resp.status)
+ self.assertIn(self.created_server_group, body)
diff --git a/tempest/api/data_processing/base.py b/tempest/api/data_processing/base.py
index 74444d7..8d5e223 100644
--- a/tempest/api/data_processing/base.py
+++ b/tempest/api/data_processing/base.py
@@ -1,17 +1,16 @@
-# Copyright (c) 2013 Mirantis Inc.
+# Copyright (c) 2014 Mirantis Inc.
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
from tempest import config
from tempest import exceptions
diff --git a/tempest/api/data_processing/test_node_group_templates.py b/tempest/api/data_processing/test_node_group_templates.py
index 393618c..f3af4e8 100644
--- a/tempest/api/data_processing/test_node_group_templates.py
+++ b/tempest/api/data_processing/test_node_group_templates.py
@@ -1,17 +1,16 @@
-# Copyright (c) 2013 Mirantis Inc.
+# Copyright (c) 2014 Mirantis Inc.
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
from tempest.api.data_processing import base as dp_base
from tempest.common.utils import data_utils
diff --git a/tempest/api/data_processing/test_plugins.py b/tempest/api/data_processing/test_plugins.py
index f4ac24e..c6832a2 100644
--- a/tempest/api/data_processing/test_plugins.py
+++ b/tempest/api/data_processing/test_plugins.py
@@ -1,17 +1,16 @@
-# Copyright (c) 2013 Mirantis Inc.
+# Copyright (c) 2014 Mirantis Inc.
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
from tempest.api.data_processing import base as dp_base
from tempest import test
diff --git a/tempest/api/identity/admin/test_users.py b/tempest/api/identity/admin/test_users.py
index a4e6c17..e2c1066 100644
--- a/tempest/api/identity/admin/test_users.py
+++ b/tempest/api/identity/admin/test_users.py
@@ -206,6 +206,25 @@
"Failed to find user %s in fetched list" %
', '.join(m_user for m_user in missing_users))
+ @test.attr(type='smoke')
+ def test_update_user_password(self):
+ # Test case to check if updating of user password is successful.
+ self.data.setup_test_user()
+ # Updating the user with new password
+ new_pass = data_utils.rand_name('pass-')
+ resp, update_user = self.client.update_user_password(
+ self.data.user['id'], new_pass)
+ # Assert response body of update user.
+ self.assertEqual(200, resp.status)
+ self.assertEqual(update_user['id'], self.data.user['id'])
+
+ # Validate the updated password
+ # Get a token
+ resp, body = self.token_client.auth(self.data.test_user, new_pass,
+ self.data.test_tenant)
+ self.assertEqual('200', resp['status'])
+ self.assertTrue('id' in body['token'])
+
class UsersTestXML(UsersTestJSON):
_interface = 'xml'
diff --git a/tempest/api/identity/admin/v3/test_certificates.py b/tempest/api/identity/admin/v3/test_certificates.py
new file mode 100644
index 0000000..a53ee0a
--- /dev/null
+++ b/tempest/api/identity/admin/v3/test_certificates.py
@@ -0,0 +1,43 @@
+# Copyright 2014 OpenStack Foundation
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.api.identity import base
+from tempest import test
+
+
+class CertificatesV3TestJSON(base.BaseIdentityV3AdminTest):
+ _interface = 'json'
+
+ def _verify_response(self, expected, actual):
+ missing_tags = [t for t in expected if t not in actual]
+ self.assertEqual(0, len(missing_tags),
+ "Failed to fetch expected tag"
+ "in the certificate: %s" % ','.join(missing_tags))
+
+ @test.attr(type='smoke')
+ def test_get_ca_certificate(self):
+ # Verify ca certificate chain
+ expected_tags = ['BEGIN CERTIFICATE', 'END CERTIFICATE']
+ resp, certificate = self.client.get_ca_certificate()
+ self.assertEqual(200, resp.status)
+ self._verify_response(expected_tags, certificate)
+
+ @test.attr(type='smoke')
+ def test_get_certificates(self):
+ # Verify signing certificates
+ expected_tags = ['Certificate', 'BEGIN CERTIFICATE', 'END CERTIFICATE']
+ resp, certificates = self.client.get_certificates()
+ self.assertEqual(200, resp.status)
+ self._verify_response(expected_tags, certificates)
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index 3e26f46..97b3c4b 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+import six
+
from tempest.api.network import base_security_groups as base
from tempest.common.utils import data_utils
from tempest import test
@@ -88,18 +90,24 @@
rule_create_body['security_group_rule']['id']
)
- # Show details of the created security rule
- resp, show_rule_body = self.client.show_security_group_rule(
- rule_create_body['security_group_rule']['id']
- )
- self.assertEqual('200', resp['status'])
+ # Show details of the created security rule
+ resp, show_rule_body = self.client.show_security_group_rule(
+ rule_create_body['security_group_rule']['id']
+ )
+ self.assertEqual('200', resp['status'])
+ create_dict = rule_create_body['security_group_rule']
+ for key, value in six.iteritems(create_dict):
+ self.assertEqual(value,
+ show_rule_body['security_group_rule'][key],
+ "%s does not match." % key)
- # List rules and verify created rule is in response
- resp, rule_list_body = self.client.list_security_group_rules()
- self.assertEqual('200', resp['status'])
- rule_list = [rule['id']
- for rule in rule_list_body['security_group_rules']]
- self.assertIn(rule_create_body['security_group_rule']['id'], rule_list)
+ # List rules and verify created rule is in response
+ resp, rule_list_body = self.client.list_security_group_rules()
+ self.assertEqual('200', resp['status'])
+ rule_list = [rule['id']
+ for rule in rule_list_body['security_group_rules']]
+ self.assertIn(rule_create_body['security_group_rule']['id'],
+ rule_list)
@test.attr(type='smoke')
def test_create_security_group_rule_with_additional_args(self):
diff --git a/tempest/api/orchestration/base.py b/tempest/api/orchestration/base.py
index 4e40de9..df3efdb 100644
--- a/tempest/api/orchestration/base.py
+++ b/tempest/api/orchestration/base.py
@@ -60,11 +60,13 @@
return admin_client
@classmethod
- def create_stack(cls, stack_name, template_data, parameters={}):
+ def create_stack(cls, stack_name, template_data, parameters={},
+ environment=None):
resp, body = cls.client.create_stack(
stack_name,
template=template_data,
- parameters=parameters)
+ parameters=parameters,
+ environment=environment)
stack_id = resp['location'].split('/')[-1]
stack_identifier = '%s/%s' % (stack_name, stack_id)
cls.stacks.append(stack_identifier)
diff --git a/tempest/api/orchestration/stacks/templates/random_string.yaml b/tempest/api/orchestration/stacks/templates/random_string.yaml
new file mode 100644
index 0000000..dfd2342
--- /dev/null
+++ b/tempest/api/orchestration/stacks/templates/random_string.yaml
@@ -0,0 +1,18 @@
+heat_template_version: 2013-05-23
+
+parameters:
+ random_length:
+ type: number
+ default: 10
+
+resources:
+ random:
+ type: OS::Heat::RandomString
+ properties:
+ length: {get_param: random_length}
+
+outputs:
+ random_length:
+ value: {get_param: random_length}
+ random_value:
+ value: {get_attr: [random, value]}
diff --git a/tempest/api/orchestration/stacks/test_environment.py b/tempest/api/orchestration/stacks/test_environment.py
new file mode 100644
index 0000000..7ed65e8
--- /dev/null
+++ b/tempest/api/orchestration/stacks/test_environment.py
@@ -0,0 +1,42 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import logging
+
+from tempest.api.orchestration import base
+from tempest.common.utils import data_utils
+from tempest import config
+from tempest import test
+
+
+CONF = config.CONF
+LOG = logging.getLogger(__name__)
+
+
+class StackEnvironmentTest(base.BaseOrchestrationTest):
+
+ @test.attr(type='gate')
+ def test_environment_parameter(self):
+ """Test passing a stack parameter via the environment."""
+ stack_name = data_utils.rand_name('heat')
+ template = self.load_template('random_string')
+ environment = {'parameters': {'random_length': 20}}
+
+ stack_identifier = self.create_stack(stack_name, template,
+ environment=environment)
+ self.client.wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')
+
+ random_len = self.get_stack_output(stack_identifier, 'random_length')
+ self.assertEqual(20, random_len)
+
+ random_value = self.get_stack_output(stack_identifier, 'random_value')
+ self.assertEqual(20, len(random_value))
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 0ef34c6..e057c74 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -114,8 +114,10 @@
resource.delete()
except Exception as e:
# If the resource is already missing, mission accomplished.
- # add status code as workaround for bug 1247568
- if (e.__class__.__name__ == 'NotFound' or
+ # - Status code tolerated as a workaround for bug 1247568
+ # - HTTPNotFound tolerated as this is currently raised when
+ # attempting to delete an already-deleted heat stack.
+ if (e.__class__.__name__ in ('NotFound', 'HTTPNotFound') or
(hasattr(e, 'status_code') and e.status_code == 404)):
return
raise
diff --git a/tempest/scenario/test_load_balancer_basic.py b/tempest/scenario/test_load_balancer_basic.py
index d771aed..9152220 100644
--- a/tempest/scenario/test_load_balancer_basic.py
+++ b/tempest/scenario/test_load_balancer_basic.py
@@ -68,6 +68,7 @@
def setUp(self):
super(TestLoadBalancerBasic, self).setUp()
self.server_ips = {}
+ self.server_fixed_ips = {}
self._create_security_group()
def cleanup_wrapper(self, resource):
@@ -119,6 +120,7 @@
self.server_ips[server.id] = floating_ip.floating_ip_address
else:
self.server_ips[server.id] = server.networks[net['name']][0]
+ self.server_fixed_ips[server.id] = server.networks[net['name']][0]
self.assertTrue(self.servers_keypairs)
return server
@@ -231,8 +233,8 @@
but with different ports to listen on.
"""
- for server_id, ip in self.server_ips.iteritems():
- if len(self.server_ips) == 1:
+ for server_id, ip in self.server_fixed_ips.iteritems():
+ if len(self.server_fixed_ips) == 1:
member1 = self._create_member(address=ip,
protocol_port=self.port1,
pool_id=self.pool.id)
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 92cfc8e..5204cd0 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -478,3 +478,36 @@
return self.action(server_id, "os-getVNCConsole",
"console", common_schema.get_vnc_console,
type=console_type)
+
+ def create_server_group(self, name, policies):
+ """
+ Create the server group
+ name : Name of the server-group
+ policies : List of the policies - affinity/anti-affinity)
+ """
+ post_body = {
+ 'name': name,
+ 'policies': policies,
+ }
+
+ post_body = json.dumps({'server_group': post_body})
+ resp, body = self.post('os-server-groups', post_body)
+
+ body = json.loads(body)
+ return resp, body['server_group']
+
+ def delete_server_group(self, server_group_id):
+ """Delete the given server-group."""
+ return self.delete("os-server-groups/%s" % str(server_group_id))
+
+ def list_server_groups(self):
+ """List the server-groups."""
+ resp, body = self.get("os-server-groups")
+ body = json.loads(body)
+ return resp, body['server_groups']
+
+ def get_server_group(self, server_group_id):
+ """Get the details of given server_group."""
+ resp, body = self.get("os-server-groups/%s" % str(server_group_id))
+ body = json.loads(body)
+ return resp, body['server_group']
diff --git a/tempest/services/data_processing/v1_1/client.py b/tempest/services/data_processing/v1_1/client.py
index 194e300..b07e663 100644
--- a/tempest/services/data_processing/v1_1/client.py
+++ b/tempest/services/data_processing/v1_1/client.py
@@ -1,17 +1,16 @@
# Copyright (c) 2013 Mirantis Inc.
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
import json
diff --git a/tempest/services/identity/json/identity_client.py b/tempest/services/identity/json/identity_client.py
index 55239f7..479a289 100644
--- a/tempest/services/identity/json/identity_client.py
+++ b/tempest/services/identity/json/identity_client.py
@@ -227,6 +227,16 @@
url = '/OS-KSADM/services/%s' % service_id
return self.delete(url)
+ def update_user_password(self, user_id, new_pass):
+ """Update User Password."""
+ put_body = {
+ 'password': new_pass,
+ 'id': user_id
+ }
+ put_body = json.dumps({'user': put_body})
+ resp, body = self.put('users/%s/OS-KSADM/password' % user_id, put_body)
+ return resp, self._parse_resp(body)
+
class TokenClientJSON(IdentityClientJSON):
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index 6829333..73e52a0 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -450,6 +450,16 @@
% (trust_id, role_id))
return resp, body
+ def get_ca_certificate(self):
+ """GET ca certificate chain."""
+ resp, body = self.get("OS-SIMPLE-CERT/ca")
+ return resp, body
+
+ def get_certificates(self):
+ """GET signing certificates used to sign tokens."""
+ resp, body = self.get("OS-SIMPLE-CERT/certificates")
+ return resp, body
+
class V3TokenClientJSON(rest_client.RestClient):
diff --git a/tempest/services/identity/xml/identity_client.py b/tempest/services/identity/xml/identity_client.py
index c48bc90..b213c1a 100644
--- a/tempest/services/identity/xml/identity_client.py
+++ b/tempest/services/identity/xml/identity_client.py
@@ -118,6 +118,15 @@
str(xml.Document(create_service)))
return resp, self._parse_resp(body)
+ def update_user_password(self, user_id, new_pass):
+ """Update User Password."""
+ put_body = xml.Element("user",
+ id=user_id,
+ password=new_pass)
+ resp, body = self.put('users/%s/OS-KSADM/password' % user_id,
+ str(xml.Document(put_body)))
+ return resp, self._parse_resp(body)
+
class TokenClientXML(identity_client.TokenClientJSON):
TYPE = "xml"
diff --git a/tempest/services/orchestration/json/orchestration_client.py b/tempest/services/orchestration/json/orchestration_client.py
index 2311bdd..1bbdb07 100644
--- a/tempest/services/orchestration/json/orchestration_client.py
+++ b/tempest/services/orchestration/json/orchestration_client.py
@@ -45,28 +45,31 @@
return resp, body['stacks']
def create_stack(self, name, disable_rollback=True, parameters={},
- timeout_mins=60, template=None, template_url=None):
+ timeout_mins=60, template=None, template_url=None,
+ environment=None):
headers, body = self._prepare_update_create(
name,
disable_rollback,
parameters,
timeout_mins,
template,
- template_url)
+ template_url,
+ environment)
uri = 'stacks'
resp, body = self.post(uri, headers=headers, body=body)
return resp, body
def update_stack(self, stack_identifier, name, disable_rollback=True,
parameters={}, timeout_mins=60, template=None,
- template_url=None):
+ template_url=None, environment=None):
headers, body = self._prepare_update_create(
name,
disable_rollback,
parameters,
timeout_mins,
template,
- template_url)
+ template_url,
+ environment)
uri = "stacks/%s" % stack_identifier
resp, body = self.put(uri, headers=headers, body=body)
@@ -74,13 +77,15 @@
def _prepare_update_create(self, name, disable_rollback=True,
parameters={}, timeout_mins=60,
- template=None, template_url=None):
+ template=None, template_url=None,
+ environment=None):
post_body = {
"stack_name": name,
"disable_rollback": disable_rollback,
"parameters": parameters,
"timeout_mins": timeout_mins,
- "template": "HeatTemplateFormatVersion: '2012-12-12'\n"
+ "template": "HeatTemplateFormatVersion: '2012-12-12'\n",
+ "environment": environment
}
if template:
post_body['template'] = template