From e79f84b8bdf63ab91ed30c1de718f7a0ba2250bf Mon Sep 17 00:00:00 2001 From: Ian Duffy Date: Fri, 9 Jun 2017 02:05:54 +0100 Subject: [PATCH] Fixes #173 - Add senza version to /api/status endpoint Exposes the senza version on the system to /api/status as a field labelled `senza_version`. Additionally, it sets a header of `X-Senza-Version`. Signed-off-by: Ian Duffy --- lizzy/api.py | 3 +++ lizzy/swagger/lizzy.yaml | 45 ++++++++++++++++++++++++++++++++++++++++ tests/test_app.py | 12 +++++++++++ 3 files changed, 60 insertions(+) diff --git a/lizzy/api.py b/lizzy/api.py index 83d9221..99da657 100644 --- a/lizzy/api.py +++ b/lizzy/api.py @@ -16,6 +16,7 @@ from lizzy.security import bouncer from lizzy.util import filter_empty_values from lizzy.version import VERSION +from senza import __version__ as SENZA_VERSION logger = logging.getLogger('lizzy.api') # pylint: disable=invalid-name @@ -24,6 +25,7 @@ def _make_headers(**kwargs: Dict[str, str]) -> dict: headers = {'x-Lizzy-{key}'.format(key=k.title()): v.replace('\n', '\\n') for k, v in kwargs.items()} headers['X-Lizzy-Version'] = VERSION + headers['X-Senza-Version'] = SENZA_VERSION return headers @@ -293,6 +295,7 @@ def get_app_status(): status_info = { 'version': os.environ.get("APPLICATION_VERSION", ""), + 'senza_version': SENZA_VERSION, 'status': status, 'config': { name: getattr(config, name) diff --git a/lizzy/swagger/lizzy.yaml b/lizzy/swagger/lizzy.yaml index 592d1f6..cbaede1 100644 --- a/lizzy/swagger/lizzy.yaml +++ b/lizzy/swagger/lizzy.yaml @@ -58,6 +58,9 @@ paths: X-Lizzy-Version: description: Lizzy Version type: string + X-Senza-Version: + description: Senza Version + type: string schema: type: array items: @@ -69,6 +72,9 @@ paths: X-Lizzy-Version: description: Lizzy Version type: string + X-Senza-Version: + description: Senza Version + type: string schema: $ref: '#/definitions/problem' post: @@ -86,6 +92,9 @@ paths: X-Lizzy-Version: description: Lizzy Version type: string + X-Senza-Version: + description: Senza Version + type: string X-Lizzy-Output: description: Senza Output type: string @@ -95,6 +104,9 @@ paths: X-Lizzy-Version: description: Lizzy Version type: string + X-Senza-Version: + description: Senza Version + type: string schema: $ref: '#/definitions/problem' 401: @@ -104,6 +116,9 @@ paths: X-Lizzy-Version: description: Lizzy Version type: string + X-Senza-Version: + description: Senza Version + type: string schema: $ref: '#/definitions/problem' security: @@ -142,6 +157,9 @@ paths: X-Lizzy-Version: description: Lizzy Version type: string + X-Senza-Version: + description: Senza Version + type: string schema: $ref: '#/definitions/stack' 401: @@ -168,6 +186,9 @@ paths: X-Lizzy-Version: description: Lizzy Version type: string + X-Senza-Version: + description: Senza Version + type: string schema: $ref: '#/definitions/problem' 500: @@ -177,6 +198,9 @@ paths: X-Lizzy-Version: description: Lizzy Version type: string + X-Senza-Version: + description: Senza Version + type: string X-Lizzy-Output: description: Senza Output type: string @@ -207,6 +231,9 @@ paths: X-Lizzy-Version: description: Lizzy Version type: string + X-Senza-Version: + description: Senza Version + type: string schema: type: object $ref: '#/definitions/stack' @@ -217,6 +244,9 @@ paths: X-Lizzy-Version: description: Lizzy Version type: string + X-Senza-Version: + description: Senza Version + type: string schema: $ref: '#/definitions/problem' 404: @@ -226,6 +256,9 @@ paths: X-Lizzy-Version: description: Lizzy Version type: string + X-Senza-Version: + description: Senza Version + type: string schema: $ref: '#/definitions/problem' security: @@ -270,6 +303,9 @@ paths: X-Lizzy-Version: description: Lizzy Version type: string + X-Senza-Version: + description: Senza Version + type: string schema: type: object properties: @@ -284,6 +320,9 @@ paths: X-Lizzy-Version: description: Lizzy Version type: string + X-Senza-Version: + description: Senza Version + type: string schema: $ref: '#/definitions/problem' @@ -302,12 +341,18 @@ paths: X-Lizzy-Version: description: Lizzy Version type: string + X-Senza-Version: + description: Senza Version + type: string schema: type: object properties: version: type: string description: Lizzy version running + senza_version: + type: string + description: Senza version running status: type: string config: diff --git a/tests/test_app.py b/tests/test_app.py index 73d99c4..ee07072 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -14,6 +14,7 @@ from lizzy.models.stack import Stack from lizzy.service import setup_webapp from lizzy.version import VERSION +from senza import __version__ as SENZA_VERSION CURRENT_VERSION = VERSION @@ -117,6 +118,7 @@ def test_security(app, mock_senza): get_stacks = app.get('/api/stacks', headers=GOOD_HEADERS) assert get_stacks.status_code == 200 assert get_stacks.headers['X-Lizzy-Version'] == CURRENT_VERSION + assert get_stacks.headers['X-Senza-Version'] == SENZA_VERSION inexistent_url = app.get('/api/does-not-exist', headers=GOOD_HEADERS) assert inexistent_url.status_code == 404 @@ -198,6 +200,7 @@ def test_bad_senza_yaml(app, monkeypatch, mock_senza): response = json.loads(request.data.decode()) assert response['title'] == 'Invalid senza yaml' assert request.headers['X-Lizzy-Version'] == CURRENT_VERSION + assert request.headers['X-Senza-Version'] == SENZA_VERSION mock_senza = MagicMock() mock_senza.return_value = mock_senza @@ -255,6 +258,7 @@ def test_new_stack(app, mock_senza, expected_tags) assert request.status_code == 201 assert request.headers['X-Lizzy-Version'] == CURRENT_VERSION + assert request.headers['X-Senza-Version'] == SENZA_VERSION response = json.loads(request.get_data().decode()) assert len(response) == 5 assert response['stack_name'] == 'abc' @@ -295,6 +299,7 @@ def test_get_stack(app, mock_senza): response = app.get('/api/stacks/stack-1', headers=GOOD_HEADERS) assert response.headers['X-Lizzy-Version'] == CURRENT_VERSION + assert response.headers['X-Senza-Version'] == SENZA_VERSION payload = json.loads(response.data.decode()) # type: dict assert parameters == payload.keys() @@ -341,6 +346,7 @@ def test_get_stack_404(app, mock_senza): request = app.get('/api/stacks/stack-404', headers=GOOD_HEADERS) assert request.status_code == 404 assert request.headers['X-Lizzy-Version'] == CURRENT_VERSION + assert request.headers['X-Senza-Version'] == SENZA_VERSION @pytest.mark.parametrize( @@ -366,6 +372,7 @@ def test_delete(app, mock_senza, stack_id, region, dry_run, force): request = app.delete(url, data=json.dumps(data), headers=GOOD_HEADERS) assert request.status_code == 204 assert request.headers['X-Lizzy-Version'] == CURRENT_VERSION + assert request.headers['X-Senza-Version'] == SENZA_VERSION mock_senza.assert_called_once_with(region) mock_senza.remove.assert_called_once_with(stack_id, dry_run=dry_run, force=force) @@ -374,6 +381,7 @@ def test_delete(app, mock_senza, stack_id, region, dry_run, force): request = app.delete(url, data=json.dumps(data), headers=GOOD_HEADERS) assert request.status_code == 204 assert request.headers['X-Lizzy-Version'] == CURRENT_VERSION + assert request.headers['X-Senza-Version'] == SENZA_VERSION @pytest.mark.parametrize( @@ -407,6 +415,7 @@ def test_patch(monkeypatch, app, mock_senza): stack_name='stack', stack_version='1') assert request.headers['X-Lizzy-Version'] == CURRENT_VERSION + assert request.headers['X-Senza-Version'] == SENZA_VERSION # Should return 500 when not possible to change the traffic # while running the one of the senza commands an error occurs @@ -422,6 +431,7 @@ def test_patch(monkeypatch, app, mock_senza): data=json.dumps({})) assert request.status_code == 202 assert request.headers['X-Lizzy-Version'] == CURRENT_VERSION + assert request.headers['X-Senza-Version'] == SENZA_VERSION # Run in a different region mock_senza.traffic.reset() @@ -439,6 +449,7 @@ def test_patch(monkeypatch, app, mock_senza): data=json.dumps(update_image)) assert request.status_code == 202 assert request.headers['X-Lizzy-Version'] == CURRENT_VERSION + assert request.headers['X-Senza-Version'] == SENZA_VERSION mock_senza.patch.assert_called_once_with('stack', '1', 'ami-2323') mock_senza.respawn_instances.assert_called_once_with('stack', '1') @@ -496,6 +507,7 @@ def test_patch404(app, mock_senza): data=json.dumps(data)) assert response.status_code == 404 assert response.headers['X-Lizzy-Version'] == CURRENT_VERSION + assert response.headers['X-Senza-Version'] == SENZA_VERSION def test_api_discovery_endpoint(app):