Update for upcoming openstacksdk changes

The resource2/proxy2 migration is finally done, so resource2/proxy2 will
be resource/proxy in the next openstacksdk release.

In the release after that, Profile is going away as are entrypoints
plugins. This handles fixing most of that in a way that should work with
both old and new.

There are two additional places where it is problematic due to profile
in the API. I've left a TODO note there and will send in a followup
patch to handle those.

Note: The masakari command doesn't work yet with this fix.

Co-Authored-By: Kengo Takahara <takahara-kn@njk.co.jp>
Change-Id: I0c7145c7726e8a5895451ec4e08ae3bf6f324c7a
This commit is contained in:
Monty Taylor 2018-01-17 13:09:20 -06:00 committed by Kengo Takahara
parent 61dcbfbcb6
commit 1b55986c23
8 changed files with 147 additions and 49 deletions

View File

@ -227,3 +227,18 @@ def get_uuid_by_name(manager, name, segment=None):
uuid = getattr(item, 'uuid')
break
return uuid
def is_new_sdk(sdk_version):
"""Returns whether the openstacksdk version is new.
:param version: Version of openstacksdk
:return: Returns False if the version is 0.9.19 or 0.10.0.
Otherwise returns True.
"""
# NOTE(Takahara): This sdk version check will be removed once the minimum
# openstacksdk version is bumped > 0.10.0.
if sdk_version.find('0.9.19') == 0 or sdk_version.find('0.10.0') == 0:
return False
else:
return True

View File

@ -15,10 +15,20 @@
import logging
from openstack import connection
from openstack import profile
from openstack import version
from osc_lib import utils
from masakariclient.common import utils as masakariclient_utils
from masakariclient.sdk.ha import ha_service
from masakariclient.sdk.ha.v1 import _proxy
if masakariclient_utils.is_new_sdk(version.__version__):
from openstack import service_description
_new_sdk = True
else:
from openstack import profile
_new_sdk = False
LOG = logging.getLogger(__name__)
@ -33,6 +43,30 @@ API_VERSIONS = {
def make_client(instance):
"""Returns a ha proxy"""
if _new_sdk:
return _make_client_new(instance)
else:
return _make_client_old(instance)
def _make_client_new(instance):
desc = service_description.ServiceDescription(
service_type='ha', proxy_class=_proxy.Proxy)
conn = connection.Connection(
session=instance.session, extra_services=[desc])
conn.add_service(desc)
if version.__version__.find('0.11.0') == 0:
client = conn.ha
else:
client = conn.ha.proxy_class(
session=instance.session, service_type='ha')
return client
def _make_client_old(instance):
prof = profile.Profile()
prof._add_service(ha_service.HAService(version="v1"))
prof.set_region(API_NAME, instance.region_name)

View File

@ -22,6 +22,10 @@ from masakariclient.sdk.ha import ha_service
LOG = logging.getLogger(__name__)
# TODO(mordred) This will need to be updated, which will be an API break.
# Not sure what the best way to deal with that is. Perhaps just add a
# config argument and use it if it's there. I mean, a human can't create
# a Profile once they've installed a new enough SDK.
def create_connection(prof=None, user_agent=None, **kwargs):
"""Create connection to masakari_api."""

View File

@ -12,15 +12,23 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from openstack import proxy2
from openstack import resource2
from openstack import version
from masakariclient.common import utils as masakariclient_utils
from masakariclient.sdk.ha.v1 import host as _host
from masakariclient.sdk.ha.v1 import notification as _notification
from masakariclient.sdk.ha.v1 import segment as _segment
class Proxy(proxy2.BaseProxy):
if masakariclient_utils.is_new_sdk(version.__version__):
from openstack import proxy
from openstack import resource
else:
from openstack import proxy2 as proxy
from openstack import resource2 as resource
class Proxy(proxy.BaseProxy):
"""Proxy class for ha resource handling.
Create method for each action of each API.
@ -163,7 +171,7 @@ class Proxy(proxy2.BaseProxy):
:raises: :class:`~openstack.exceptions.ResourceNotFound`
when no resource can be found.
"""
host_id = resource2.Resource._get_id(host)
host_id = resource.Resource._get_id(host)
return self._get(_host.Host, host_id, segment_id=segment_id)
def update_host(self, segment_id, host, **attrs):
@ -176,7 +184,7 @@ class Proxy(proxy2.BaseProxy):
:returns: The updated host
"""
host_id = resource2.Resource._get_id(host)
host_id = resource.Resource._get_id(host)
return self._update(_host.Host, host_id, segment_id=segment_id,
**attrs)
@ -195,6 +203,6 @@ class Proxy(proxy2.BaseProxy):
:returns: ``None``
"""
host_id = resource2.Resource._get_id(host)
host_id = resource.Resource._get_id(host)
return self._delete(_host.Host, host_id, segment_id=segment_id,
ignore_missing=ignore_missing)

View File

@ -12,12 +12,21 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from openstack import resource2
from openstack import version
from masakariclient.common import utils as masakariclient_utils
from masakariclient.sdk.ha import ha_service
class Host(resource2.Resource):
if masakariclient_utils.is_new_sdk(version.__version__):
from openstack import resource
_new_sdk = True
else:
from openstack import resource2 as resource
_new_sdk = False
class Host(resource.Resource):
resource_key = "host"
resources_key = "hosts"
base_path = "/segments/%(segment_id)s/hosts"
@ -41,29 +50,29 @@ class Host(resource2.Resource):
# for properties of host API
#: A ID of representing this host
id = resource2.URI("id")
id = resource.URI("id")
#: A Uuid of representing this host
uuid = resource2.Body("uuid")
uuid = resource.Body("uuid")
#: A failover segment ID of this host(in URI)
segment_id = resource2.URI("segment_id")
segment_id = resource.URI("segment_id")
#: A created time of this host
created_at = resource2.Body("created_at")
created_at = resource.Body("created_at")
#: A latest updated time of this host
updated_at = resource2.Body("updated_at")
updated_at = resource.Body("updated_at")
#: A name of this host
name = resource2.Body("name")
name = resource.Body("name")
#: A type of this host
type = resource2.Body("type")
type = resource.Body("type")
#: A control attributes of this host
control_attributes = resource2.Body("control_attributes")
control_attributes = resource.Body("control_attributes")
#: A maintenance status of this host
on_maintenance = resource2.Body("on_maintenance")
on_maintenance = resource.Body("on_maintenance")
#: A reservation status of this host
reserved = resource2.Body("reserved")
reserved = resource.Body("reserved")
#: A failover segment ID of this host(in Body)
failover_segment_id = resource2.Body("failover_segment_id")
failover_segment_id = resource.Body("failover_segment_id")
_query_mapping = resource2.QueryParameters(
_query_mapping = resource.QueryParameters(
"sort_key", "sort_dir", failover_segment_id="failover_segment_id",
type="type", on_maintenance="on_maintenance", reserved="reserved")
@ -72,7 +81,11 @@ class Host(resource2.Resource):
request = self._prepare_request(prepend_key=prepend_key)
del request.body['id']
request_body = {"host": request.body}
res = session.put(request.uri, endpoint_filter=self.service,
json=request_body, headers=request.headers)
if _new_sdk:
res = session.put(request.url, endpoint_filter=self.service,
json=request_body, headers=request.headers)
else:
res = session.put(request.uri, endpoint_filter=self.service,
json=request_body, headers=request.headers)
self._translate_response(res, has_body=has_body)
return self

View File

@ -12,12 +12,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from openstack import resource2
from openstack import version
from masakariclient.common import utils as masakariclient_utils
from masakariclient.sdk.ha import ha_service
class Notification(resource2.Resource):
if masakariclient_utils.is_new_sdk(version.__version__):
from openstack import resource
else:
from openstack import resource2 as resource
class Notification(resource.Resource):
resource_key = "notification"
resources_key = "notifications"
base_path = "/notifications"
@ -39,27 +46,27 @@ class Notification(resource2.Resource):
# for properties of notifications API
#: A ID of representing this notification.
id = resource2.Body("id")
id = resource.Body("id")
#: A Uuid of representing this notification.
notification_uuid = resource2.Body("notification_uuid")
notification_uuid = resource.Body("notification_uuid")
#: A created time of representing this notification.
created_at = resource2.Body("created_at")
created_at = resource.Body("created_at")
#: A latest updated time of representing this notification.
updated_at = resource2.Body("updated_at")
updated_at = resource.Body("updated_at")
#: The type of failure. Valuse values include ''COMPUTE_HOST'',
#: ''VM'', ''PROCESS''
type = resource2.Body("type")
type = resource.Body("type")
#: The hostname of this notification.
hostname = resource2.Body("hostname")
hostname = resource.Body("hostname")
#: The status for this notitication.
status = resource2.Body("status")
status = resource.Body("status")
#: The generated_time for this notitication.
generated_time = resource2.Body("generated_time")
generated_time = resource.Body("generated_time")
#: The payload of this notification.
payload = resource2.Body("payload")
payload = resource.Body("payload")
#: The source host uuid of this notification.
source_host_uuid = resource2.Body("source_host_uuid")
source_host_uuid = resource.Body("source_host_uuid")
_query_mapping = resource2.QueryParameters(
_query_mapping = resource.QueryParameters(
"sort_key", "sort_dir", source_host_uuid="source_host_uuid",
type="type", status="status", generated_since="generated-since")

View File

@ -12,12 +12,21 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from openstack import resource2
from openstack import version
from masakariclient.common import utils as masakariclient_utils
from masakariclient.sdk.ha import ha_service
class Segment(resource2.Resource):
if masakariclient_utils.is_new_sdk(version.__version__):
from openstack import resource
_new_sdk = True
else:
from openstack import resource2 as resource
_new_sdk = False
class Segment(resource.Resource):
resource_key = "segment"
resources_key = "segments"
base_path = "/segments"
@ -41,23 +50,23 @@ class Segment(resource2.Resource):
# for properties of each API
#: A ID of representing this segment.
id = resource2.Body("id")
id = resource.Body("id")
#: A Uuid of representing this segment.
uuid = resource2.Body("uuid")
uuid = resource.Body("uuid")
#: A created time of representing this segment.
created_at = resource2.Body("created_at")
created_at = resource.Body("created_at")
#: A latest updated time of representing this segment.
updated_at = resource2.Body("updated_at")
updated_at = resource.Body("updated_at")
#: The name of this segment.
name = resource2.Body("name")
name = resource.Body("name")
#: The description of this segment.
description = resource2.Body("description")
description = resource.Body("description")
#: The recovery method of this segment.
recovery_method = resource2.Body("recovery_method")
recovery_method = resource.Body("recovery_method")
#: The service type of this segment.
service_type = resource2.Body("service_type")
service_type = resource.Body("service_type")
_query_mapping = resource2.QueryParameters(
_query_mapping = resource.QueryParameters(
"sort_key", "sort_dir", recovery_method="recovery_method",
service_type="service_type")
@ -66,7 +75,11 @@ class Segment(resource2.Resource):
request = self._prepare_request(prepend_key=prepend_key)
del request.body['id']
request_body = {"segment": request.body}
ret = session.put(request.uri, endpoint_filter=self.service,
json=request_body, headers=request.headers)
if _new_sdk:
ret = session.put(request.url, endpoint_filter=self.service,
json=request_body, headers=request.headers)
else:
ret = session.put(request.uri, endpoint_filter=self.service,
json=request_body, headers=request.headers)
self._translate_response(ret, has_body=has_body)
return self

View File

@ -17,6 +17,10 @@ from masakariclient.sdk.ha import connection
class Client(object):
# TODO(mordred) This will need to be updated, which will be an API break.
# Not sure what the best way to deal with that is. Perhaps just add a
# config argument and use it if it's there. I mean, a human can't create
# a Profile once they've installed a new enough SDK.
def __init__(self, prof=None, user_agent=None, **kwargs):
self.con = connection.create_connection(
prof=prof, user_agent=user_agent, **kwargs)