Commit b4379692 authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Device - IETF ACTN Driver:

- Minor code improvements in EthtServiceHandler, OsuTunnelHandler, and RestApiClient
parent 7b3ff4a8
Loading
Loading
Loading
Loading
+20 −5
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@

import enum, logging
from typing import Dict, List, Optional, Tuple, Union
from .RestApiClient import RestApiClient
from .RestApiClient import HTTP_STATUS_CREATED, HTTP_STATUS_NO_CONTENT, HTTP_STATUS_OK, RestApiClient

LOGGER = logging.getLogger(__name__)

@@ -110,11 +110,26 @@ class EthtServiceHandler:
    def __init__(self, rest_api_client : RestApiClient) -> None:
        self._rest_api_client = rest_api_client
        self._object_name     = 'EthtService'
        self._subpath_url     = '/ietf-eth-tran-service:etht-svc/etht-svc-instances'
        self._subpath_url     = '/ietf-eth-tran-service:etht-svc'

    def _rest_api_get(self, filters : List[Tuple[str, str]]) -> Union[Dict, List]:
        return self._rest_api_client.get(
            self._object_name, self._subpath_url, filters, expected_http_status={HTTP_STATUS_OK}
        )

    def _rest_api_update(self, data : Dict) -> bool:
        return self._rest_api_client.update(
            self._object_name, self._subpath_url, data, expected_http_status={HTTP_STATUS_CREATED}
        )

    def _rest_api_delete(self, filters : List[Tuple[str, str]]) -> bool:
        return self._rest_api_client.delete(
            self._object_name, self._subpath_url, filters, expected_http_status={HTTP_STATUS_NO_CONTENT}
        )

    def get(self, etht_service_name : Optional[str] = None) -> Union[Dict, List]:
        filters = [] if etht_service_name is None else [('etht-svc-name', etht_service_name)]
        data = self._rest_api_client.get(self._object_name, self._subpath_url, filters)
        data = self._rest_api_get(filters)

        if not isinstance(data, dict): return ValueError('data should be a dict')
        if 'ietf-eth-tran-service:etht-svc' not in data:
@@ -194,8 +209,8 @@ class EthtServiceHandler:
            src_static_routes=src_static_routes, dst_static_routes=dst_static_routes
        )

        return self._rest_api_client.update(self._object_name, self._subpath_url, data)
        return self._rest_api_update(data)

    def delete(self, etht_service_name : str) -> bool:
        filters = [('etht-svc-name', etht_service_name)]
        return self._rest_api_client.delete(self._object_name, self._subpath_url, filters)
        return self._rest_api_delete(filters)
+21 −6
Original line number Diff line number Diff line
@@ -13,8 +13,8 @@
# limitations under the License.

import enum, logging
from typing import Dict, List, Optional, Union
from .RestApiClient import RestApiClient
from typing import Dict, List, Optional, Tuple, Union
from .RestApiClient import HTTP_STATUS_CREATED, HTTP_STATUS_NO_CONTENT, HTTP_STATUS_OK, RestApiClient

LOGGER = logging.getLogger(__name__)

@@ -84,11 +84,26 @@ class OsuTunnelHandler:
    def __init__(self, rest_api_client : RestApiClient) -> None:
        self._rest_api_client = rest_api_client
        self._object_name     = 'OsuTunnel'
        self._subpath_url     = '/ietf-te:tunnel'
        self._subpath_url     = '/ietf-te:te/tunnels'

    def _rest_api_get(self, filters : List[Tuple[str, str]]) -> Union[Dict, List]:
        return self._rest_api_client.get(
            self._object_name, self._subpath_url, filters, expected_http_status={HTTP_STATUS_OK}
        )

    def _rest_api_update(self, data : Dict) -> bool:
        return self._rest_api_client.update(
            self._object_name, self._subpath_url, data, expected_http_status={HTTP_STATUS_CREATED}
        )

    def _rest_api_delete(self, filters : List[Tuple[str, str]]) -> bool:
        return self._rest_api_client.delete(
            self._object_name, self._subpath_url, filters, expected_http_status={HTTP_STATUS_NO_CONTENT}
        )

    def get(self, osu_tunnel_name : Optional[str] = None) -> Union[Dict, List]:
        filters = [] if osu_tunnel_name is None else [('name', osu_tunnel_name)]
        data = self._rest_api_client.get(self._object_name, self._subpath_url, filters)
        data = self._rest_api_get(filters)

        if not isinstance(data, dict): return ValueError('data should be a dict')
        if 'ietf-te:tunnel' not in data: return ValueError('data does not contain key "ietf-te:tunnel"')
@@ -149,8 +164,8 @@ class OsuTunnelHandler:
            odu_type, osuflex_number, delay, bidirectional=bidirectional
        )

        return self._rest_api_client.update(self._object_name, self._subpath_url, data)
        return self._rest_api_update(data)

    def delete(self, osu_tunnel_name : str) -> bool:
        filters = [('name', osu_tunnel_name)]
        return self._rest_api_client.delete(self._object_name, self._subpath_url, filters)
        return self._rest_api_delete(filters)
+21 −13
Original line number Diff line number Diff line
@@ -14,20 +14,25 @@

import copy, json, logging, requests
from requests.auth import HTTPBasicAuth
from typing import Any, Dict, List, Tuple, Union
from typing import Any, Dict, List, Set, Tuple, Union

LOGGER = logging.getLogger(__name__)

DEFAULT_BASE_URL = '/restconf/data'
DEFAULT_SCHEMA   = 'http'
DEFAULT_BASE_URL = '/restconf/v2/data'
DEFAULT_SCHEMA   = 'https'
DEFAULT_TIMEOUT  = 120
DEFAULT_VERIFY   = False

HTTP_STATUS_OK         = 200
HTTP_STATUS_CREATED    = 201
HTTP_STATUS_ACCEPTED   = 202
HTTP_STATUS_NO_CONTENT = 204

HTTP_OK_CODES = {
    200,    # OK
    201,    # Created
    202,    # Accepted
    204,    # No Content
    HTTP_STATUS_OK,
    HTTP_STATUS_CREATED,
    HTTP_STATUS_ACCEPTED,
    HTTP_STATUS_NO_CONTENT,
}

class RestApiClient:
@@ -44,7 +49,8 @@ class RestApiClient:
        self._verify  = int(settings.get('verify',  DEFAULT_VERIFY ))

    def get(
        self, object_name : str, url : str, filters : List[Tuple[str, str]]
        self, object_name : str, url : str, filters : List[Tuple[str, str]],
        expected_http_status : Set[int] = {HTTP_STATUS_OK}
    ) -> Union[Dict, List]:
        str_filters = ''.join([
            '[{:s}={:s}]'.format(filter_field, filter_value)
@@ -59,7 +65,7 @@ class RestApiClient:
        )
        LOGGER.info('  Response: {:s}'.format(str(response)))

        if response.status_code in HTTP_OK_CODES: return json.loads(response.content)
        if response.status_code in expected_http_status: return json.loads(response.content)

        MSG = 'Could not get {:s}({:s}): status_code={:s} reply={:s}'
        msg = MSG.format(str(object_name), str(str_filters), str(response.status_code), str(response))
@@ -67,7 +73,8 @@ class RestApiClient:
        return Exception(msg)

    def update(
        self, object_name : str, url : str, data : Dict, headers : Dict[str, Any] = dict()
        self, object_name : str, url : str, data : Dict, headers : Dict[str, Any] = dict(),
        expected_http_status : Set[int] = HTTP_OK_CODES
    ) -> bool:
        headers = copy.deepcopy(headers)
        if 'content-type' not in {header_name.lower() for header_name in headers.keys()}:
@@ -81,14 +88,15 @@ class RestApiClient:
        )
        LOGGER.info('  Response: {:s}'.format(str(response)))

        if response.status_code in HTTP_OK_CODES: return True
        if response.status_code in expected_http_status: return True

        MSG = 'Could not create/update {:s}({:s}): status_code={:s} reply={:s}'
        LOGGER.error(MSG.format(str(object_name), str(data), str(response.status_code), str(response)))
        return False

    def delete(
        self, object_name : str, url : str, filters : List[Tuple[str, str]]
        self, object_name : str, url : str, filters : List[Tuple[str, str]],
        expected_http_status : Set[int] = HTTP_OK_CODES
    ) -> bool:
        str_filters = ''.join([
            '[{:s}={:s}]'.format(filter_field, filter_value)
@@ -103,7 +111,7 @@ class RestApiClient:
        )
        LOGGER.info('  Response: {:s}'.format(str(response)))

        if response.status_code in HTTP_OK_CODES: return True
        if response.status_code in expected_http_status: return True

        MSG = 'Could not delete {:s}({:s}): status_code={:s} reply={:s}'
        LOGGER.error(MSG.format(str(object_name), str(str_filters), str(response.status_code), str(response)))