Commit f49d6a3a authored by Pavel Spirek's avatar Pavel Spirek

Implemented GET method for operations, allowed conf-commit for empty staging datastore

parent 59d725fc
......@@ -15,6 +15,7 @@ from yangson.instance import NonexistentInstance, InstanceValueError, RootNode
from .config import CONFIG_GLOBAL, CONFIG_HTTP, CONFIG_NACM, API_ROOT_data, API_ROOT_RUNNING_data, API_ROOT_ops
from .helpers import CertHelpers, DateTimeHelpers, ErrorHelpers, LogHelpers, SSLCertT
from .handler_list import OP_HANDLERS
from .errors import BackendError
from .nacm import NacmForbiddenError
from .data import (
......@@ -122,9 +123,9 @@ class HttpResponse:
pass
try:
err_body["error-message"] = exception.message
err_body["error-message"] = exception.__class__.__name__ + ": " + exception.message
except AttributeError:
err_body["error-message"] = str(exception)
err_body["error-message"] = exception.__class__.__name__ + ": " + str(exception)
if err_apptag is not None:
err_body["error-app-tag"] = err_apptag
......@@ -733,6 +734,58 @@ def create_api_op(ds: BaseDatastore):
return api_op_closure
def create_api_get_op(ds: BaseDatastore):
def api_op_closure(headers: OrderedDict, data: Optional[str], client_cert: SSLCertT) -> HttpResponse:
username = CertHelpers.get_field(client_cert, "emailAddress")
info("[{}] get_op: {}".format(username, headers[":path"]))
api_pth = headers[":path"][len(API_ROOT_ops):].rstrip("/")
op_name_fq = api_pth[1:].split("/", maxsplit=1)[0]
op_names_dict = dict(map(lambda n: (n[0], None), OP_HANDLERS.handlers))
if api_pth == "":
# GET root
ret_data = {
"ietf-restconf:operations": op_names_dict
}
else:
# GET particular operation
try:
ns, op_name = op_name_fq.split(":", maxsplit=1)
except ValueError:
return HttpResponse.error(
HttpStatus.BadRequest,
RestconfErrType.Protocol,
ERRTAG_MALFORMED,
"Operation name must be in fully-qualified format"
)
if op_names_dict.get(op_name_fq, -1) != -1:
ret_data = {
op_name_fq: None
}
else:
# Not found
ret_data = None
if ret_data is None:
http_resp = HttpResponse.error(
HttpStatus.NotFound,
RestconfErrType.Protocol,
ERRTAG_INVVALUE,
err_path=api_pth,
err_msg="Operation name not found"
)
else:
response = json.dumps(ret_data, indent=4)
http_resp = HttpResponse(HttpStatus.Ok, response.encode(), CT_YANG_JSON)
return http_resp
return api_op_closure
def options_api(headers: OrderedDict, data: Optional[str], client_cert: SSLCertT) -> HttpResponse:
info("api_options: {}".format(headers[":path"]))
headers_extra = OrderedDict()
......
......@@ -39,7 +39,12 @@ class OpHandlersContainer:
return ret_data
def jetconf_conf_commit(self, rpc: RpcInfo) -> JsonNodeT:
try:
usr_journal = self.ds.get_user_journal(rpc.username)
except StagingDataException:
usr_journal = None
if usr_journal is not None:
try:
self.ds.lock_data(rpc.username)
commit_res = usr_journal.commit(self.ds)
......@@ -49,6 +54,8 @@ class OpHandlersContainer:
self.ds.unlock_data()
self.ds.drop_user_journal(rpc.username)
else:
commit_res = False
ret_data = {
"status": "OK",
......@@ -90,7 +97,7 @@ class OpHandlersContainer:
def register_op_handlers(ds: BaseDatastore):
op_handlers_obj = OpHandlersContainer(ds)
OP_HANDLERS.register(op_handlers_obj.jetconf_conf_start, "jetconf:conf-start")
# OP_HANDLERS.register(op_handlers_obj.jetconf_conf_start, "jetconf:conf-start")
OP_HANDLERS.register(op_handlers_obj.jetconf_conf_status, "jetconf:conf-status")
OP_HANDLERS.register(op_handlers_obj.jetconf_conf_reset, "jetconf:conf-reset")
OP_HANDLERS.register(op_handlers_obj.jetconf_conf_commit, "jetconf:conf-commit")
......
......@@ -283,6 +283,7 @@ class RestServer:
api_post = handlers.create_post_api(datastore)
api_put = handlers.create_put_api(datastore)
api_delete = handlers.create_api_delete(datastore)
api_get_op = handlers.create_api_get_op(datastore)
api_op = handlers.create_api_op(datastore)
self.http_handlers.register(lambda m, p: (m == "GET") and (p.startswith(API_ROOT_data)), api_get)
......@@ -292,6 +293,7 @@ class RestServer:
self.http_handlers.register(lambda m, p: (m == "POST") and (p.startswith(API_ROOT_data)), api_post)
self.http_handlers.register(lambda m, p: (m == "PUT") and (p.startswith(API_ROOT_data)), api_put)
self.http_handlers.register(lambda m, p: (m == "DELETE") and (p.startswith(API_ROOT_data)), api_delete)
self.http_handlers.register(lambda m, p: (m == "GET") and (p.startswith(API_ROOT_ops)), api_get_op)
self.http_handlers.register(lambda m, p: (m == "POST") and (p.startswith(API_ROOT_ops)), api_op)
self.http_handlers.register(lambda m, p: m == "OPTIONS", handlers.options_api)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment