Commit 179b2b4b authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Common - Tools - Rest Conf, and propagation of change along code:

- Created REST Conf Tools module
- Moved here a generic client and server
- Propagated changes along code
parent f4c93c1f
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
# Generic RESTCONF Client

This server implements a basic RESTCONF Client that can be potentially used for any case.

See a simple working example in folder `src/tests/tools/simap_server`
+8 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@

import logging, requests
from typing import Any, Dict, Optional, Set
from .RestApiClient import RestApiClient
from common.tools.rest_api.client.RestApiClient import RestApiClient


HOST_META_URL = '{:s}://{:s}:{:d}/.well-known/host-meta'
@@ -35,6 +35,7 @@ class RestConfClient(RestApiClient):

        self._discover_base_url()


    def _discover_base_url(self) -> None:
        host_meta_url = HOST_META_URL.format(self._scheme, self._address, self._port)
        host_meta : Dict = super().get(host_meta_url, expected_status_codes={requests.codes['OK']})
@@ -58,6 +59,7 @@ class RestConfClient(RestApiClient):

        self._base_url = str(href).replace('//', '/')


    def get(
        self, endpoint : str,
        expected_status_codes : Set[int] = {requests.codes['OK']}
@@ -67,6 +69,7 @@ class RestConfClient(RestApiClient):
            expected_status_codes=expected_status_codes
        )


    def post(
        self, endpoint : str, body : Optional[Any] = None,
        expected_status_codes : Set[int] = {requests.codes['CREATED']}
@@ -76,6 +79,7 @@ class RestConfClient(RestApiClient):
            expected_status_codes=expected_status_codes
        )


    def put(
        self, endpoint : str, body : Optional[Any] = None,
        expected_status_codes : Set[int] = {requests.codes['CREATED'], requests.codes['NO_CONTENT']}
@@ -85,6 +89,7 @@ class RestConfClient(RestApiClient):
            expected_status_codes=expected_status_codes
        )


    def patch(
        self, endpoint : str, body : Optional[Any] = None,
        expected_status_codes : Set[int] = {requests.codes['NO_CONTENT']}
@@ -94,6 +99,7 @@ class RestConfClient(RestApiClient):
            expected_status_codes=expected_status_codes
        )


    def delete(
        self, endpoint : str, body : Optional[Any] = None,
        expected_status_codes : Set[int] = {requests.codes['NO_CONTENT']}
@@ -103,6 +109,7 @@ class RestConfClient(RestApiClient):
            expected_status_codes=expected_status_codes
        )


    def rpc(
        self, endpoint : str, body : Optional[Any] = None,
        expected_status_codes : Set[int] = {requests.codes['CREATED']}
+14 −0
Original line number Diff line number Diff line
# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# 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.
+66 −0
Original line number Diff line number Diff line
# Copyright 2022-2025 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# 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.

FROM python:3.9-slim

# Install dependencies
RUN apt-get --yes --quiet --quiet update && \
    apt-get --yes --quiet --quiet install git build-essential cmake libpcre2-dev python3-dev python3-cffi && \
    rm -rf /var/lib/apt/lists/*

# Download, build and install libyang. Note that APT package is outdated
# - Ref: https://github.com/CESNET/libyang
# - Ref: https://github.com/CESNET/libyang-python/
RUN mkdir -p /var/libyang
RUN git clone https://github.com/CESNET/libyang.git /var/libyang
WORKDIR /var/libyang
RUN git fetch
RUN git checkout v2.1.148
RUN mkdir -p /var/libyang/build
WORKDIR /var/libyang/build
RUN cmake -D CMAKE_BUILD_TYPE:String="Release" ..
RUN make
RUN make install
RUN ldconfig

# Set Python to show logs as they occur
ENV PYTHONUNBUFFERED=0

# Get generic Python packages
RUN python3 -m pip install --upgrade pip
RUN python3 -m pip install --upgrade setuptools wheel
RUN python3 -m pip install --upgrade pip-tools

# Create component sub-folders, get specific Python packages
RUN mkdir -p /var/teraflow/restconf_server/
WORKDIR /var/teraflow/restconf_server/
COPY ./requirements.in ./requirements.in
RUN pip-compile --quiet --output-file=requirements.txt requirements.in
RUN python3 -m pip install -r requirements.txt

# Add component files into working directory
COPY ./yang/*.yang ./yang/
COPY ./restconf_server/*.py ./restconf_server/
COPY ./startup.json ./startup.json

# Configure RESTCONF Server
ENV RESTCONF_PREFIX="/restconf"
ENV YANG_SEARCH_PATH="./yang"
ENV STARTUP_FILE="./startup.json"

# Configure Flask for production
ENV FLASK_ENV="production"

# Start the service
ENTRYPOINT ["gunicorn", "--workers", "1", "--worker-class", "eventlet", "--bind", "0.0.0.0:8080", "restconf_server.app:app"]
Loading