Allow to PUT an empty object model

It was impossible to delete the last component from the env via
CLI, because it was prohibited to make put request with empty body.

APIImpact
Change-Id: I462072ad7c90eec1790b74cae958809aa316c25c
Closes-bug: #1511645
This commit is contained in:
Valerii Kovalchuk 2016-09-22 14:04:38 +03:00
parent afc17fb207
commit 945cc04806
7 changed files with 175 additions and 6 deletions

View File

@ -716,6 +716,93 @@ Created application returned
| 400 | Required header or body are not provided |
+----------------+-----------------------------------------------------------+
Update applications
-------------------
Applications list for environment can be updated.
*Request*
**Content-Type**
application/json
+----------------+-----------------------------------------------------------+------------------------------------+
| Method | URI | Header |
+================+===========================================================+====================================+
| PUT | /environments/<env_id>/services | X-Configuration-Session |
+----------------+-----------------------------------------------------------+------------------------------------+
::
[{
"instance": {
"availabilityZone": "nova",
"name": "apache-instance",
"assignFloatingIp": true,
"keyname": "",
"flavor": "m1.small",
"image": "146d5523-7b2d-4abc-b0d0-2041f920ce26",
"?": {
"type": "io.murano.resources.LinuxMuranoInstance",
"id": "25185cb6f29b415fa2e438309827a797"
}
},
"name": "ApacheHttpServer",
"enablePHP": true,
"?": {
"type": "com.example.apache.ApacheHttpServer",
"id": "6e66106d7dcb4748a5c570150a3df80f"
}
}]
*Response*
Updated applications list returned
**Content-Type**
application/json
::
[{
"instance": {
"availabilityZone": "nova",
"name": "apache-instance",
"assignFloatingIp": true,
"keyname": "",
"flavor": "m1.small",
"image": "146d5523-7b2d-4abc-b0d0-2041f920ce26",
"?": {
"type": "io.murano.resources.LinuxMuranoInstance",
"id": "25185cb6f29b415fa2e438309827a797"
}
},
"name": "ApacheHttpServer",
"enablePHP": true,
"?": {
"type": "com.example.apache.ApacheHttpServer",
"id": "6e66106d7dcb4748a5c570150a3df80f"
}
}]
+----------------+-----------------------------------------------------------+
| Code | Description |
+================+===========================================================+
| 200 | Services are updated successfully |
+----------------+-----------------------------------------------------------+
| 400 | Required header is not provided |
+----------------+-----------------------------------------------------------+
| 401 | User is not authorized |
+----------------+-----------------------------------------------------------+
| 403 | Session is in deploying state and could not be updated |
| | or user is not allowed to update services |
+----------------+-----------------------------------------------------------+
| 404 | Not found. Specified environment and/or session do not |
| | exist |
+----------------+-----------------------------------------------------------+
Delete application from environment
-----------------------------------

View File

@ -92,10 +92,7 @@ class Controller(object):
@normalize_path
def put(self, request, environment_id, path, body=None):
if not body:
msg = _('Request body is empty: please, provide '
'application object model')
LOG.error(msg)
raise exc.HTTPBadRequest(msg)
body = []
LOG.debug('Services:Put <EnvId: {0}, Path: {2}, '
'Body: {1}>'.format(environment_id, body, path))

View File

@ -110,8 +110,10 @@ class TestServicesApi(tb.ControllerTest, tb.MuranoApiTestCase):
request.headers['X-Configuration-Session'] = str(session_id)
request.context.session = session_id
self.assertRaises(exc.HTTPBadRequest, self.services_controller.put,
request, environment_id, path)
# Check that empty body can be put
response = self.services_controller.put(request, environment_id,
path, [])
self.assertEqual([], response)
response = self.services_controller.put(request, environment_id,
path, "test service")

View File

@ -196,6 +196,19 @@ class ApplicationCatalogClient(rest_client.RestClient):
self.expected_success(200, resp.status)
return self._parse_resp(body)
def update_services(self, environment_id, session_id, put_body=None):
headers = self.get_headers()
headers.update(
{'X-Configuration-Session': session_id}
)
uri = 'v1/environments/{0}/services'.format(environment_id)
resp, body = self.put(uri, json.dumps(put_body), headers)
self.expected_success(200, resp.status)
# TODO(freerunner): Need to replace json.loads() to _parse_resp
# method, when fix for https://bugs.launchpad.net/tempest/+bug/1539927
# will resolved and new version of tempest-lib released.
return json.loads(body)
def delete_service(self, environment_id, session_id, service_id):
headers = self.get_headers()
headers.update(

View File

@ -65,6 +65,44 @@ class TestServices(base.BaseApplicationCatalogTest):
get_services_list(self.environment['id'], session['id'])
self.assertEqual(len(services_list), len(services_list_))
@testtools.testcase.attr('smoke')
def test_update_services_via_put(self):
session = self.application_catalog_client.\
create_session(self.environment['id'])
self.addCleanup(self.application_catalog_client.delete_session,
self.environment['id'], session['id'])
put_body = [self._get_demo_app()]
self.application_catalog_client.\
update_services(self.environment['id'], session['id'], put_body)
services_list = self.application_catalog_client.\
get_services_list(self.environment['id'], session['id'])
self.assertEqual(1, len(services_list))
@testtools.testcase.attr('smoke')
def test_clear_services_via_put(self):
session = self.application_catalog_client.\
create_session(self.environment['id'])
self.addCleanup(self.application_catalog_client.delete_session,
self.environment['id'], session['id'])
services_list = self.application_catalog_client.\
get_services_list(self.environment['id'], session['id'])
post_body = self._get_demo_app()
self.application_catalog_client.\
create_service(self.environment['id'], session['id'], post_body)
services_list_ = self.application_catalog_client.\
get_services_list(self.environment['id'], session['id'])
self.assertEqual(len(services_list) + 1, len(services_list_))
self.application_catalog_client.\
update_services(self.environment['id'], session['id'])
services_list_ = self.application_catalog_client.\
get_services_list(self.environment['id'], session['id'])
self.assertEqual(0, len(services_list_))
self.application_catalog_client.\
create_service(self.environment['id'], session['id'], post_body)
services_list_ = self.application_catalog_client.\
get_services_list(self.environment['id'], session['id'])
self.assertEqual(1, len(services_list_))
@testtools.testcase.attr('smoke')
def test_get_service(self):
session = self.application_catalog_client.\

View File

@ -159,6 +159,32 @@ class TestServicesNegative(base.BaseApplicationCatalogTest):
session['id'],
service['?']['id'])
@testtools.testcase.attr('negative')
def test_put_services_without_env_id(self):
session = self.application_catalog_client.\
create_session(self.environment['id'])
self.addCleanup(self.application_catalog_client.delete_session,
self.environment['id'], session['id'])
put_body = [self._get_demo_app()]
self.assertRaises(exceptions.NotFound,
self.application_catalog_client.update_services,
None,
session['id'],
put_body)
@testtools.testcase.attr('negative')
def test_put_services_without_sess_id(self):
session = self.application_catalog_client.\
create_session(self.environment['id'])
self.addCleanup(self.application_catalog_client.delete_session,
self.environment['id'], session['id'])
put_body = [self._get_demo_app()]
self.assertRaises(exceptions.BadRequest,
self.application_catalog_client.update_services,
self.environment['id'],
"",
put_body)
class TestServicesNegativeTenantIsolation(base.BaseApplicationCatalogTest):

View File

@ -0,0 +1,6 @@
---
fixes:
- It is now possible to make a PUT request with body equal to '[]' to
'/environments/<env_id>/services' endpoint. This will result in removing
all apps from current session. This allows deleting the last application
from environment from CLI.