Skip to content

Commit

Permalink
Merge pull request #175 from sheldor1510/api-versioning
Browse files Browse the repository at this point in the history
Enabled API versioning
  • Loading branch information
tzumainn authored Sep 17, 2024
2 parents ea766aa + 0386c8f commit 726ea20
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 14 deletions.
4 changes: 4 additions & 0 deletions docs/esi-leap-api-version-history.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# REST API Version History

## 1.0
This is the initial (and current) version of the API.
48 changes: 48 additions & 0 deletions esi_leap/api/controllers/v1/versions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright (c) 2015 Intel Corporation
# 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.

# Borrowed from Ironic

# This is the version 1 API
BASE_VERSION = 1

# Here goes a short log of changes in every version.
# Refer to docs/esi-leap-api-version-history.md for a detailed
# explanation of what each version contains.
#
# v1.0: API at the point in time when versioning support was added.

MINOR_0_INITIAL_VERSION = 0

# When adding another version, update:
# - MINOR_MAX_VERSION
# - docs/esi-leap-api-version-history.md with a detailed
# explanation of what changed in the new version

MINOR_MAX_VERSION = MINOR_0_INITIAL_VERSION

# String representations of the minor and maximum versions
_MIN_VERSION_STRING = "{}.{}".format(BASE_VERSION, MINOR_0_INITIAL_VERSION)
_MAX_VERSION_STRING = "{}.{}".format(BASE_VERSION, MINOR_MAX_VERSION)


def min_version_string():
"""Returns the minimum supported API version (as a string)"""
return _MIN_VERSION_STRING


def max_version_string():
"""Returns the maximum supported API version (as a string)."""
return _MAX_VERSION_STRING
44 changes: 44 additions & 0 deletions esi_leap/api/controllers/version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# 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.

# Borrowed from Ironic

ID_VERSION1 = "v1"


def all_versions(host_url):
return [default_version(host_url)]


def default_version(host_url):
"""Return a dict representing the current default version
id: The ID of the (major) version, also acts as the release number
links: A list containing one link that points to the current version
of the API
status: Status of the version, one of CURRENT, SUPPORTED, DEPRECATED
min_version: The current, maximum supported (major.minor) version of API.
version: Minimum supported (major.minor) version of API.
"""

from esi_leap.api.controllers.v1 import versions

return {
"id": ID_VERSION1,
"links": [{"href": "{0}/{1}".format(host_url, ID_VERSION1), "rel": "self"}],
"status": "CURRENT",
"min_version": versions.min_version_string(),
"version": versions.max_version_string(),
}
10 changes: 3 additions & 7 deletions esi_leap/common/health.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
from oslo_serialization import jsonutils
from esi_leap.api.controllers import version


def root(host_url):
return {
"name": "ESI Leap API",
"description": "ESI Leap is an OpenStack service for leasing baremetal nodes, designed to run on top of multi-tenant Ironic.",
"versions": [
{
"id": "v1.0",
"status": "CURRENT",
"links": [{"href": "{0}/v1".format(host_url), "rel": "self"}],
}
],
"default_version": version.default_version(host_url),
"versions": version.all_versions(host_url),
}


Expand Down
79 changes: 79 additions & 0 deletions esi_leap/tests/api/controllers/v1/test_versions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Copyright (c) 2015 Intel Corporation
#
# 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.
# Borrowed from Ironic

"""
Tests for the versions constants and methods.
"""

import re

from esi_leap.api.controllers.v1 import versions
from esi_leap.tests import base


class TestVersionConstants(base.TestCase):
def setUp(self):
super(TestVersionConstants, self).setUp()

# Get all of our named constants. They all begin with r'MINOR_[0-9]'
self.minor_consts = [x for x in dir(versions) if re.search(r"^MINOR_[0-9]", x)]

# Sort key needs to be an integer
def minor_key(x):
return int(x.split("_", 2)[1])

self.minor_consts.sort(key=minor_key)

def test_max_ver_str(self):
# Test to make sure _MAX_VERSION_STRING corresponds with the largest
# MINOR_ constant

max_ver = "1.{}".format(getattr(versions, self.minor_consts[-1]))
self.assertEqual(max_ver, versions._MAX_VERSION_STRING)

def test_min_ver_str(self):
# Try to make sure someone doesn't change the _MIN_VERSION_STRING by
# accident and make sure it exists
self.assertEqual("1.0", versions._MIN_VERSION_STRING)

def test_name_value_match(self):
# Test to make sure variable name matches the value. For example
# MINOR_99_FOO should equal 99

for var_name in self.minor_consts:
version = int(var_name.split("_", 2)[1])
self.assertEqual(
version,
getattr(versions, var_name),
'Constant "{}" does not equal {}'.format(var_name, version),
)

def test_duplicates(self):
# Test to make sure no duplicates values

seen_values = set()
for var_name in self.minor_consts:
value = getattr(versions, var_name)
self.assertNotIn(
value,
seen_values,
"The value {} has been used more than once".format(value),
)
seen_values.add(value)


class TestMaxVersionString(base.TestCase):
def test_max_version_not_pinned(self):
self.assertEqual(versions._MAX_VERSION_STRING, versions.max_version_string())
10 changes: 3 additions & 7 deletions esi_leap/tests/common/test_health.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# under the License.

from esi_leap.common import health
from esi_leap.api.controllers import version
from esi_leap.tests import base
from oslo_serialization import jsonutils

Expand All @@ -21,13 +22,8 @@ def test_root(self):
expected_result = {
"name": "ESI Leap API",
"description": "ESI Leap is an OpenStack service for leasing baremetal nodes, designed to run on top of multi-tenant Ironic.",
"versions": [
{
"id": "v1.0",
"status": "CURRENT",
"links": [{"href": "{0}/v1".format(host_url), "rel": "self"}],
}
],
"default_version": version.default_version(host_url),
"versions": version.all_versions(host_url),
}
result = health.root(host_url)
self.assertEqual(result, expected_result)
Expand Down

0 comments on commit 726ea20

Please sign in to comment.