Skip to content

Commit 726ea20

Browse files
authored
Merge pull request #175 from sheldor1510/api-versioning
Enabled API versioning
2 parents ea766aa + 0386c8f commit 726ea20

File tree

6 files changed

+181
-14
lines changed

6 files changed

+181
-14
lines changed

docs/esi-leap-api-version-history.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# REST API Version History
2+
3+
## 1.0
4+
This is the initial (and current) version of the API.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Copyright (c) 2015 Intel Corporation
2+
# All Rights Reserved.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
5+
# not use this file except in compliance with the License. You may obtain
6+
# a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
# License for the specific language governing permissions and limitations
14+
# under the License.
15+
16+
# Borrowed from Ironic
17+
18+
# This is the version 1 API
19+
BASE_VERSION = 1
20+
21+
# Here goes a short log of changes in every version.
22+
# Refer to docs/esi-leap-api-version-history.md for a detailed
23+
# explanation of what each version contains.
24+
#
25+
# v1.0: API at the point in time when versioning support was added.
26+
27+
MINOR_0_INITIAL_VERSION = 0
28+
29+
# When adding another version, update:
30+
# - MINOR_MAX_VERSION
31+
# - docs/esi-leap-api-version-history.md with a detailed
32+
# explanation of what changed in the new version
33+
34+
MINOR_MAX_VERSION = MINOR_0_INITIAL_VERSION
35+
36+
# String representations of the minor and maximum versions
37+
_MIN_VERSION_STRING = "{}.{}".format(BASE_VERSION, MINOR_0_INITIAL_VERSION)
38+
_MAX_VERSION_STRING = "{}.{}".format(BASE_VERSION, MINOR_MAX_VERSION)
39+
40+
41+
def min_version_string():
42+
"""Returns the minimum supported API version (as a string)"""
43+
return _MIN_VERSION_STRING
44+
45+
46+
def max_version_string():
47+
"""Returns the maximum supported API version (as a string)."""
48+
return _MAX_VERSION_STRING

esi_leap/api/controllers/version.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
13+
# Borrowed from Ironic
14+
15+
ID_VERSION1 = "v1"
16+
17+
18+
def all_versions(host_url):
19+
return [default_version(host_url)]
20+
21+
22+
def default_version(host_url):
23+
"""Return a dict representing the current default version
24+
25+
id: The ID of the (major) version, also acts as the release number
26+
links: A list containing one link that points to the current version
27+
of the API
28+
29+
status: Status of the version, one of CURRENT, SUPPORTED, DEPRECATED
30+
31+
min_version: The current, maximum supported (major.minor) version of API.
32+
33+
version: Minimum supported (major.minor) version of API.
34+
"""
35+
36+
from esi_leap.api.controllers.v1 import versions
37+
38+
return {
39+
"id": ID_VERSION1,
40+
"links": [{"href": "{0}/{1}".format(host_url, ID_VERSION1), "rel": "self"}],
41+
"status": "CURRENT",
42+
"min_version": versions.min_version_string(),
43+
"version": versions.max_version_string(),
44+
}

esi_leap/common/health.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
from oslo_serialization import jsonutils
2+
from esi_leap.api.controllers import version
23

34

45
def root(host_url):
56
return {
67
"name": "ESI Leap API",
78
"description": "ESI Leap is an OpenStack service for leasing baremetal nodes, designed to run on top of multi-tenant Ironic.",
8-
"versions": [
9-
{
10-
"id": "v1.0",
11-
"status": "CURRENT",
12-
"links": [{"href": "{0}/v1".format(host_url), "rel": "self"}],
13-
}
14-
],
9+
"default_version": version.default_version(host_url),
10+
"versions": version.all_versions(host_url),
1511
}
1612

1713

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Copyright (c) 2015 Intel Corporation
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
# Borrowed from Ironic
15+
16+
"""
17+
Tests for the versions constants and methods.
18+
"""
19+
20+
import re
21+
22+
from esi_leap.api.controllers.v1 import versions
23+
from esi_leap.tests import base
24+
25+
26+
class TestVersionConstants(base.TestCase):
27+
def setUp(self):
28+
super(TestVersionConstants, self).setUp()
29+
30+
# Get all of our named constants. They all begin with r'MINOR_[0-9]'
31+
self.minor_consts = [x for x in dir(versions) if re.search(r"^MINOR_[0-9]", x)]
32+
33+
# Sort key needs to be an integer
34+
def minor_key(x):
35+
return int(x.split("_", 2)[1])
36+
37+
self.minor_consts.sort(key=minor_key)
38+
39+
def test_max_ver_str(self):
40+
# Test to make sure _MAX_VERSION_STRING corresponds with the largest
41+
# MINOR_ constant
42+
43+
max_ver = "1.{}".format(getattr(versions, self.minor_consts[-1]))
44+
self.assertEqual(max_ver, versions._MAX_VERSION_STRING)
45+
46+
def test_min_ver_str(self):
47+
# Try to make sure someone doesn't change the _MIN_VERSION_STRING by
48+
# accident and make sure it exists
49+
self.assertEqual("1.0", versions._MIN_VERSION_STRING)
50+
51+
def test_name_value_match(self):
52+
# Test to make sure variable name matches the value. For example
53+
# MINOR_99_FOO should equal 99
54+
55+
for var_name in self.minor_consts:
56+
version = int(var_name.split("_", 2)[1])
57+
self.assertEqual(
58+
version,
59+
getattr(versions, var_name),
60+
'Constant "{}" does not equal {}'.format(var_name, version),
61+
)
62+
63+
def test_duplicates(self):
64+
# Test to make sure no duplicates values
65+
66+
seen_values = set()
67+
for var_name in self.minor_consts:
68+
value = getattr(versions, var_name)
69+
self.assertNotIn(
70+
value,
71+
seen_values,
72+
"The value {} has been used more than once".format(value),
73+
)
74+
seen_values.add(value)
75+
76+
77+
class TestMaxVersionString(base.TestCase):
78+
def test_max_version_not_pinned(self):
79+
self.assertEqual(versions._MAX_VERSION_STRING, versions.max_version_string())

esi_leap/tests/common/test_health.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
# under the License.
1212

1313
from esi_leap.common import health
14+
from esi_leap.api.controllers import version
1415
from esi_leap.tests import base
1516
from oslo_serialization import jsonutils
1617

@@ -21,13 +22,8 @@ def test_root(self):
2122
expected_result = {
2223
"name": "ESI Leap API",
2324
"description": "ESI Leap is an OpenStack service for leasing baremetal nodes, designed to run on top of multi-tenant Ironic.",
24-
"versions": [
25-
{
26-
"id": "v1.0",
27-
"status": "CURRENT",
28-
"links": [{"href": "{0}/v1".format(host_url), "rel": "self"}],
29-
}
30-
],
25+
"default_version": version.default_version(host_url),
26+
"versions": version.all_versions(host_url),
3127
}
3228
result = health.root(host_url)
3329
self.assertEqual(result, expected_result)

0 commit comments

Comments
 (0)