--- /dev/null
+#include <libyang/libyang.h>
+#include <sysrepo.h>
+
+#include "callbacks.h"
+#include "conversion.h"
+#include "common/sysrepo_conf.h"
+
+
+static int kresd_change_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath,
+sr_event_t event, uint32_t request_id, void *private_data)
+{
+ if(event == SR_EV_CHANGE)
+ {
+ /* validation actions*/
+ }
+ else if (event == SR_EV_DONE)
+ {
+ int err = SR_ERR_OK;
+ sr_change_oper_t oper;
+ sr_val_t *old_value = NULL;
+ sr_val_t *new_value = NULL;
+ sr_change_iter_t *it = NULL;
+
+ err = sr_get_changes_iter(session, XPATH_BASE"/*/*//.", &it);
+ if (err != SR_ERR_OK) goto cleanup;
+
+ while ((sr_get_change_next(session, it, &oper, &old_value, &new_value)) == SR_ERR_OK) {
+
+ printf("%s\n", new_value->xpath);
+
+ /* apply configuration here */
+
+ sr_free_val(old_value);
+ sr_free_val(new_value);
+ }
+
+ cleanup:
+ sr_free_change_iter(it);
+
+ if(err != SR_ERR_OK && err != SR_ERR_NOT_FOUND)
+ printf("Error: %s\n",sr_strerror(err));
+ }
+ else if(event == SR_EV_ABORT)
+ {
+ /* abortion actions */
+ }
+
+ return SR_ERR_OK;
+}
+
+int sysrepo_subscr_register(sr_session_ctx_t *session, sr_subscription_ctx_t **subscription)
+{
+ int err = SR_ERR_OK;
+
+ err = sr_module_change_subscribe(session, YM_COMMON, XPATH_BASE,
+ kresd_change_cb, NULL, 0, SR_SUBSCR_NO_THREAD|SR_SUBSCR_ENABLED, subscription);
+ if (err != SR_ERR_OK)
+ return err;
+
+ return err;
+}
\ No newline at end of file
--- /dev/null
+#pragma once
+
+#include <libyang/libyang.h>
+#include <sysrepo.h>
+
+/** Register sysrepo subscriptions */
+int sysrepo_subscr_register(sr_session_ctx_t *session, sr_subscription_ctx_t **subscription);
\ No newline at end of file
#include <stdlib.h>
#include <string.h>
-#include "helpers.h"
+#include "string_helper.h"
/// Source: https://stackoverflow.com/questions/47116974/remove-a-substring-from-a-string-in-c
char *remove_substr(char *str, const char *substr) {
int sysrepo_repo_config()
{
- /*
- This function will probably be called on knot-resolver
- installation or by `kres-watcher` when something
- wents wrong with sysrepo.
+ /*
+ This function will probably be called on knot-resolver
+ installation or by `kres-watcher` when something
+ wents wrong with sysrepo.
- Configures sysrepo:
- 1. install/import YANG modules
- 2. enable features
- 3. import json data to startup datastore
- 4. clean up any stale connections of clients that no longer exist
- */
- return 0;
+ Configures sysrepo:
+ 1. install/import YANG modules
+ 2. enable features
+ 3. import json data to startup datastore
+ 4. clean up any stale connections of clients that no longer exist
+ */
+
+ return 0;
}
\ No newline at end of file
#include <sysrepo.h>
#include <libyang/libyang.h>
-/* sysrepo globals */
-#define YM_DIR ""
-#define YM_COMMON "cznic-resolver-common"
-#define YM_KRES "cznic-resolver-knot"
-#define XPATH_BASE "/" YM_COMMON ":dns-resolver"
-
-/* Function to configure sysrepo repository */
-int sysrepo_repo_config();
\ No newline at end of file
+#define YM_COMMON "cznic-resolver-common"
+#define YM_KRES "cznic-resolver-knot"
+#define XPATH_BASE "/" YM_COMMON ":dns-resolver"
+#define XPATH_GC XPATH_BASE"/cache/"YM_KRES":garbage-collector"
+#define XPATH_RPC_BASE "/"YM_COMMON
+
+
+/** Configures sysrepo repository for usage with knot-resolver */
+int sysrepo_repo_config();
--- /dev/null
+#include "conv_funcs.h"
+
+/* Conversion functions */
\ No newline at end of file
--- /dev/null
+#pragma once
\ No newline at end of file
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <lua.h>
+#include <sysrepo.h>
+
+#include "conversion.h"
+#include "conv_funcs.h"
+#include "modules/sysrepo/common/sysrepo_conf.h"
+
+
+/** Configuration conversion table:
+ * sysrepo config datastore <<-->> kres config */
+static const conversion_row_t conversion_table[] = {
+ { NULL }
+};
--- /dev/null
+#pragma once
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <lua.h>
+#include <sysrepo.h>
+
+
+typedef struct conversion_row conversion_row_t;
+
+struct conversion_row {
+ const char * xpath;
+ /* set configuration functions
+ 1. prepare value on xpath for Lua function and then push it to Lua stack
+ 2. execute Lua function with previously pushed parameters result save on top of Lua stack
+ 3. get result from top of Lua stack, parse and validate it => SR_ERR_OK
+ */
+
+ /* get configuration functions
+ 1. prepare parametrs based on xpath for Lua function to get configured value and push it to top of Lua stack
+ 2. execute Lua function with previously pushed parameters result save on top of Lua stack
+ 3. get result from top of Lua stack, convert it to type on xpath and push it to sysrepo
+ */
+
+ /* dlete configuration functions
+ 1. prepare parameters based on xpath for Lua function to delete configuration, push on top of Lua stack
+ 2. execute Lua function to delete config, result save to top of Lua stack
+ 3. read result from Lua stack and confirm if it was successfull
+ */
+};
# C module: sysrepo
sysrepo_src = files([
- 'sysrepo.c',
+ 'sysrepo.c',
+ 'callbacks.c',
+ 'conversion.c',
+ 'conv_funcs.c',
])
c_src_lint += sysrepo_src
sysrepo_common_src = files([
- 'common/sysrepo_conf.c',
- 'common/sysrepo_conf.h',
- 'common/helpers.h',
- 'common/helpers.c',
+ 'common/sysrepo_conf.c',
+ 'common/sysrepo_conf.h',
+ 'common/string_helper.h',
+ 'common/string_helper.c',
])
c_src_lint += sysrepo_common_src
if build_sysrepo
- sysrepo_mod = shared_module(
+ sysrepo_mod = shared_module(
'sysrepo',
sysrepo_src,
- sysrepo_common_src,
+ sysrepo_common_src,
dependencies: [
luajit_inc,
libyang,
- libsysrepo,
+ libsysrepo,
],
include_directories: mod_inc_dir,
name_prefix: '',
+/* Copyright (C) 2019 CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <uv.h>
#include <sysrepo.h>
#include "lib/module.h"
+#include "common/sysrepo_conf.h"
+#include "callbacks.h"
+
+
+typedef struct el_subscription_ctx el_subscription_ctx_t;
+/** Callback for our sysrepo subscriptions */
+typedef void (*el_subsription_cb)(el_subscription_ctx_t *el_subscr, int status);
+
+/** Context for our sysrepo subscriptions.
+ * might add some other fields in future */
+struct el_subscription_ctx {
+ sr_conn_ctx_t *connection;
+ sr_session_ctx_t * session;
+ sr_subscription_ctx_t *subscription;
+ el_subsription_cb callback;
+ uv_poll_t uv_handle;
+};
+
+void el_subscr_finish_closing(uv_handle_t *handle)
+{
+ el_subscription_ctx_t *el_subscr = handle->data;
+ assert(el_subscr);
+ free(el_subscr);
+}
+
+/** Free a event loop subscription. */
+void el_subscription_free(el_subscription_ctx_t *el_subscr)
+{
+ sr_disconnect(el_subscr->connection);
+ uv_close((uv_handle_t *)&el_subscr->uv_handle, el_subscr_finish_closing);
+}
+
+static void el_subscr_cb_tramp(uv_poll_t *handle, int status, int events)
+{
+ el_subscription_ctx_t *el_subscr = handle->data;
+ el_subscr->callback(el_subscr, status);
+}
+
+/** Start a new event loop subscription. */
+static el_subscription_ctx_t * el_subscription_new(sr_subscription_ctx_t *sr_subscr, el_subsription_cb el_callback)
+{
+ int fd;
+ errno = sr_get_event_pipe(sr_subscr, &fd);
+ if (errno != SR_ERR_OK) return NULL;
+ el_subscription_ctx_t *el_subscr = malloc(sizeof(*el_subscr));
+ if (!el_subscr) return NULL;
+ errno = uv_poll_init(uv_default_loop(), &el_subscr->uv_handle, fd);
+ if (errno) {
+ free(el_subscr);
+ return NULL;
+ }
+ el_subscr->subscription = sr_subscr;
+ el_subscr->callback = el_callback;
+ el_subscr->uv_handle.data = el_subscr;
+ errno = uv_poll_start(&el_subscr->uv_handle, UV_READABLE, el_subscr_cb_tramp);
+ if (errno) {
+ el_subscription_free(el_subscr);
+ return NULL;
+ }
+ return el_subscr;
+}
+
+static void el_subscr_cb(el_subscription_ctx_t *el_subscr, int status)
+{
+ if (status) {
+ /* some error */
+ return;
+ }
+ /* normal state */
+ sr_process_events(el_subscr->subscription, el_subscr->session,NULL);
+}
KR_EXPORT
-int nsid_init(struct kr_module *module) {
+int sysrepo_init(struct kr_module *module)
+{
+ int ret = SR_ERR_OK;
+ sr_conn_ctx_t *sr_connection = NULL;
+ sr_session_ctx_t *sr_session = NULL;
+ sr_subscription_ctx_t *sr_subscription = NULL;
+
+ /* connect to sysrepo */
+ ret = sr_connect(0, &sr_connection);
+ if (ret != SR_ERR_OK)
+ goto cleanup;
+
+ /* Try to recover (clean up) any stale connections of clients that no longer exist */
+ ret = sr_connection_recover(sr_connection);
+ if (ret != SR_ERR_OK)
+ goto cleanup;
+
+ /* start a new session on RUNNING datastore */
+ ret = sr_session_start(sr_connection, SR_DS_RUNNING, &sr_session);
+ if (ret != SR_ERR_OK)
+ goto cleanup;
+
+ /* register sysrepo subscriptions and callbacks*/
+ ret = sysrepo_subscr_register(sr_session, &sr_subscription);
+ if (ret != SR_ERR_OK)
+ goto cleanup;
+
+ /* add subscriptions to kres event loop */
+ el_subscription_ctx_t *el_subscr = el_subscription_new(sr_subscription, el_subscr_cb);
+ if (!el_subscr)
+ goto cleanup;
+
+ el_subscr->connection = sr_connection;
+ el_subscr->session = sr_session;
+ module->data = el_subscr;
return kr_ok();
+
+ cleanup:
+ sr_disconnect(sr_connection);
+ return kr_error(ret);
}
KR_EXPORT
-int nsid_deinit(struct kr_module *module) {
-
+int sysrepo_deinit(struct kr_module *module)
+{
+ el_subscription_ctx_t *el_subscr = module->data;
+ el_subscription_free(el_subscr);
return kr_ok();
}
-KR_MODULE_EXPORT(sysrepo)
+KR_MODULE_EXPORT(sysrepo)
\ No newline at end of file
#include <libyang/libyang.h>
#include "modules/sysrepo/common/sysrepo_conf.h"
-#include "modules/sysrepo/common/helpers.h"
-
-#define XPATH_GC XPATH_BASE"/cache/"YM_KRES":garbage-collector"
+#include "modules/sysrepo/common/string_helper.h"
#endif