Add supoprt for D release use-case.
[sim/o1-interface.git] / ntsimulator / ntsim-ng / features / netconf_call_home / netconf_call_home.c
index b3bacb0..8952cb7 100644 (file)
 #include "core/framework.h"
 
 #define NETCONF_CALLHOME_ENABLED_SCHEMA_PATH        "/nts-network-function:simulation/network-function/netconf/call-home"
-#define NETCONF_CALLHOME_CURL_SEND_PAYLOAD_FORMAT   "{\"odl-netconf-callhome-server:device\":[{\"odl-netconf-callhome-server:unique-id\":\"%s\",\"odl-netconf-callhome-server:ssh-host-key\":\"%s\",\"odl-netconf-callhome-server:credentials\":{\"odl-netconf-callhome-server:username\":\"netconf\",\"odl-netconf-callhome-server:passwords\":[\"netconf\"]}}]}"
+#define NETCONF_CALLHOME_CURL_SEND_PAYLOAD_FORMAT   "{\"odl-netconf-callhome-server:device\":[{\"odl-netconf-callhome-server:unique-id\":\"%s\",\"odl-netconf-callhome-server:ssh-host-key\":\"%s\",\"odl-netconf-callhome-server:credentials\":{\"odl-netconf-callhome-server:username\":\"netconf\",\"odl-netconf-callhome-server:passwords\":[\"netconf!\"]}}]}"
 #define SDN_CONTROLLER_DETAILS_SCHEMA_PATH          "/nts-network-function:simulation/sdn-controller"
 
 static int create_ssh_callhome_endpoint(sr_session_ctx_t *current_session, struct lyd_node *netconf_node);
 static int create_tls_callhome_endpoint(sr_session_ctx_t *current_session, struct lyd_node *netconf_node);
 static int send_odl_callhome_configuration(sr_session_ctx_t *current_session);
 
+static int netconf_call_home_status = 0;
+
+int netconf_call_home_feature_get_status(void) {
+    return netconf_call_home_status;
+}
+
 int netconf_call_home_feature_start(sr_session_ctx_t *current_session) {
     assert(current_session);
     assert_session();
@@ -49,51 +55,55 @@ int netconf_call_home_feature_start(sr_session_ctx_t *current_session) {
         callhome_enabled = value->data.bool_val;
         sr_free_val(value);
     }
+    else {
+        // if value is not set yet, feature enable means we want to start call-home
+        callhome_enabled = true;
+    }
 
     if(callhome_enabled == false) {
-        log_message(2, "NETCONF CallHome is not enabled, not configuring NETCONF Server.\n");
+        log_add_verbose(2, "NETCONF CallHome is not enabled, not configuring NETCONF Server.\n");
         return NTS_ERR_OK;
     }
 
     struct lyd_node *netconf_node = 0;
     netconf_node = lyd_new_path(NULL, session_context, "/ietf-netconf-server:netconf-server", 0, 0, 0);
     if(netconf_node == 0) {
-        log_error("could not create a new lyd_node");
+        log_error("could not create a new lyd_node\n");
         return NTS_ERR_FAILED;
     }
 
     rc = create_ssh_callhome_endpoint(current_session, netconf_node);
     if(rc != NTS_ERR_OK) {
-        log_error("could not create SSH CallHome endpoint on the NETCONF Server");
+        log_error("could not create SSH CallHome endpoint on the NETCONF Server\n");
         return NTS_ERR_FAILED;
     }
 
     rc = create_tls_callhome_endpoint(current_session, netconf_node);
     if(rc != NTS_ERR_OK) {
-        log_error("could not create TLS CallHome endpoint on the NETCONF Server");
+        log_error("could not create TLS CallHome endpoint on the NETCONF Server\n");
         return NTS_ERR_FAILED;
     }
 
     rc = sr_edit_batch(current_session, netconf_node, "merge");
     if(rc != SR_ERR_OK) {
-        log_error("could not edit batch on datastore");
+        log_error("could not edit batch on datastore\n");
         return NTS_ERR_FAILED;
     }
 
     rc = sr_validate(current_session, "ietf-netconf-server", 0);
     if(rc != SR_ERR_OK) {
-        struct ly_err_item *err = ly_err_first(session_context);
-        log_error("sr_validate issues on STARTUP: %s", err->msg);
+        log_error("sr_validate issues on STARTUP\n");
         return NTS_ERR_FAILED;
     }
 
     rc = sr_apply_changes(current_session, 0, 0);
     if(rc != SR_ERR_OK) {
-        log_error("could not apply changes on datastore");
+        log_error("could not apply changes on datastore\n");
         return NTS_ERR_FAILED;
     }
 
     lyd_free_withsiblings(netconf_node);
+    netconf_call_home_status = 1;
 
     return NTS_ERR_OK;
 }
@@ -103,23 +113,9 @@ static int create_ssh_callhome_endpoint(sr_session_ctx_t *current_session, struc
     assert(current_session);
     assert(netconf_node);
 
-    sr_val_t *value = 0;
-
-    bool callhome_enabled = false;
-    int rc = sr_get_item(current_session, NETCONF_CALLHOME_ENABLED_SCHEMA_PATH, 0, &value);
-    if(rc == SR_ERR_OK) {
-        callhome_enabled = value->data.bool_val;
-        sr_free_val(value);
-    }
-
-    if(callhome_enabled == false) {
-        log_message(2, "NETCONF CallHome is not enabled, not configuring NETCONF Server.\n");
-        return NTS_ERR_OK;
-    }
-
     controller_details_t *controller = controller_details_get(current_session);
     if(controller == 0) {
-        log_error("controller_details_get failed");
+        log_error("controller_details_get failed\n");
         return NTS_ERR_FAILED;
     }
 
@@ -128,7 +124,7 @@ static int create_ssh_callhome_endpoint(sr_session_ctx_t *current_session, struc
     controller_details_free(controller);
 
     if(controller_ip == 0) {
-        log_error("strdup failed");
+        log_error("strdup failed\n");
         return NTS_ERR_FAILED;
     }
 
@@ -136,7 +132,7 @@ static int create_ssh_callhome_endpoint(sr_session_ctx_t *current_session, struc
     sprintf(xpath, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='default-client']/endpoints/endpoint[name='callhome-ssh']/ssh/tcp-client-parameters/keepalives/idle-time");
     struct lyd_node *rcl = lyd_new_path(netconf_node, 0, xpath, "1", 0, LYD_PATH_OPT_NOPARENTRET);
     if(rcl == 0) {
-        log_error("could not created yang path");
+        log_error("could not created yang path\n");
         free(controller_ip);
         return NTS_ERR_FAILED;
     }
@@ -144,7 +140,7 @@ static int create_ssh_callhome_endpoint(sr_session_ctx_t *current_session, struc
     sprintf(xpath, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='default-client']/endpoints/endpoint[name='callhome-ssh']/ssh/tcp-client-parameters/keepalives/max-probes");
     rcl = lyd_new_path(netconf_node, 0, xpath, "10", 0, LYD_PATH_OPT_NOPARENTRET);
     if(rcl == 0) {
-        log_error("could not created yang path");
+        log_error("could not created yang path\n");
         free(controller_ip);
         return NTS_ERR_FAILED;
     }
@@ -152,7 +148,7 @@ static int create_ssh_callhome_endpoint(sr_session_ctx_t *current_session, struc
     sprintf(xpath, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='default-client']/endpoints/endpoint[name='callhome-ssh']/ssh/tcp-client-parameters/keepalives/probe-interval");
     rcl = lyd_new_path(netconf_node, 0, xpath, "5", 0, LYD_PATH_OPT_NOPARENTRET);
     if(rcl == 0) {
-        log_error("could not created yang path");
+        log_error("could not created yang path\n");
         free(controller_ip);
         return NTS_ERR_FAILED;
     }
@@ -160,7 +156,7 @@ static int create_ssh_callhome_endpoint(sr_session_ctx_t *current_session, struc
     sprintf(xpath, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='default-client']/endpoints/endpoint[name='callhome-ssh']/ssh/tcp-client-parameters/remote-address");
     rcl = lyd_new_path(netconf_node, 0, xpath, controller_ip, 0, LYD_PATH_OPT_NOPARENTRET);
     if(rcl == 0) {
-        log_error("could not created yang path");
+        log_error("could not created yang path\n");
         free(controller_ip);
         return NTS_ERR_FAILED;
     }
@@ -171,55 +167,55 @@ static int create_ssh_callhome_endpoint(sr_session_ctx_t *current_session, struc
     sprintf(port, "%d", controller_callhome_port);
     rcl = lyd_new_path(netconf_node, 0, xpath, port, 0, LYD_PATH_OPT_NOPARENTRET);
     if(rcl == 0) {
-        log_error("could not created yang path");
+        log_error("could not created yang path\n");
         return NTS_ERR_FAILED;
     }
 
     sprintf(xpath, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='default-client']/endpoints/endpoint[name='callhome-ssh']/ssh/ssh-server-parameters/server-identity/host-key[name='default-key']/public-key/keystore-reference");
     rcl = lyd_new_path(netconf_node, 0, xpath, KS_KEY_NAME, 0, LYD_PATH_OPT_NOPARENTRET);
     if(rcl == 0) {
-        log_error("could not created yang path");
+        log_error("could not created yang path\n");
         return NTS_ERR_FAILED;
     }
 
     sprintf(xpath, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='default-client']/endpoints/endpoint[name='callhome-ssh']/ssh/ssh-server-parameters/client-authentication/supported-authentication-methods/publickey");
     rcl = lyd_new_path(netconf_node, 0, xpath, "", 0, LYD_PATH_OPT_NOPARENTRET);
     if(rcl == 0) {
-        log_error("could not created yang path");
+        log_error("could not created yang path\n");
         return NTS_ERR_FAILED;
     }
 
     sprintf(xpath, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='default-client']/endpoints/endpoint[name='callhome-ssh']/ssh/ssh-server-parameters/client-authentication/supported-authentication-methods/passsword");
     rcl = lyd_new_path(netconf_node, 0, xpath, "", 0, LYD_PATH_OPT_NOPARENTRET);
     if(rcl == 0) {
-        log_error("could not created yang path");
+        log_error("could not created yang path\n");
         return NTS_ERR_FAILED;
     }
 
     sprintf(xpath, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='default-client']/endpoints/endpoint[name='callhome-ssh']/ssh/ssh-server-parameters/client-authentication/supported-authentication-methods/other");
     rcl = lyd_new_path(netconf_node, 0, xpath, "interactive", 0, LYD_PATH_OPT_NOPARENTRET);
     if(rcl == 0) {
-        log_error("could not created yang path");
+        log_error("could not created yang path\n");
         return NTS_ERR_FAILED;
     }
 
     sprintf(xpath, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='default-client']/endpoints/endpoint[name='callhome-ssh']/ssh/ssh-server-parameters/client-authentication/users");
     rcl = lyd_new_path(netconf_node, 0, xpath, "", 0, LYD_PATH_OPT_NOPARENTRET);
     if(rcl == 0) {
-        log_error("could not created yang path");
+        log_error("could not created yang path\n");
         return NTS_ERR_FAILED;
     }
 
     sprintf(xpath, "/ietf-netconf-server:netconf-server/call-home/netconf-client[name='default-client']/connection-type/persistent");
     rcl = lyd_new_path(netconf_node, 0, xpath, "", 0, LYD_PATH_OPT_NOPARENTRET);
     if(rcl == 0) {
-        log_error("could not created yang path");
+        log_error("could not created yang path\n");
         return NTS_ERR_FAILED;
     }
 
-    rc = send_odl_callhome_configuration(current_session);
+    int rc = send_odl_callhome_configuration(current_session);
     if(rc != NTS_ERR_OK) {
-        log_message(2, "could not send ODL Call Home configuration.\n");
+        log_add_verbose(2, "could not send ODL Call Home configuration.\n");
     }
 
     return NTS_ERR_OK;
@@ -240,40 +236,41 @@ static int send_odl_callhome_configuration(sr_session_ctx_t *current_session) {
 
     char *public_ssh_key = read_key(SERVER_PUBLIC_SSH_KEY_PATH);
     if(public_ssh_key == 0) {
-        log_error("could not read the public ssh key from file %s", SERVER_PUBLIC_SSH_KEY_PATH);
+        log_error("could not read the public ssh key from file %s\n", SERVER_PUBLIC_SSH_KEY_PATH);
         return NTS_ERR_FAILED;
     }
 
     char *ssh_key_string;
     ssh_key_string = strtok(public_ssh_key, " ");
     ssh_key_string = strtok(NULL, " ");
+    ssh_key_string[strlen(ssh_key_string) - 1] = 0; // trim the newline character
 
     // checkAS we have hardcoded here the username and password of the NETCONF Server
     char *odl_callhome_payload = 0;
-    asprintf(&odl_callhome_payload, NETCONF_CALLHOME_CURL_SEND_PAYLOAD_FORMAT, framework_environment.hostname, ssh_key_string);
+    asprintf(&odl_callhome_payload, NETCONF_CALLHOME_CURL_SEND_PAYLOAD_FORMAT, framework_environment.settings.hostname, ssh_key_string);
     free(public_ssh_key);
     if(odl_callhome_payload == 0) {
-        log_error("bad asprintf");
+        log_error("bad asprintf\n");
         return NTS_ERR_FAILED;
     }
 
     controller_details_t *controller = controller_details_get(current_session);
     if(controller == 0) {
-        log_error("controller_details_get failed");
+        log_error("controller_details_get failed\n");
         return NTS_ERR_FAILED;
     }
     
     char *url = 0;
-    asprintf(&url, "%s/rests/data/odl-netconf-callhome-server:netconf-callhome-server/allowed-devices/device=%s", controller->base_url, framework_environment.hostname);
+    asprintf(&url, "%s/rests/data/odl-netconf-callhome-server:netconf-callhome-server/allowed-devices/device=%s", controller->base_url, framework_environment.settings.hostname);
     if(url == 0) {
-        log_error("bad asprintf");
+        log_error("bad asprintf\n");
         controller_details_free(controller);
         return NTS_ERR_FAILED;
     }
 
     int rc = http_request(url, controller->username, controller->password, "PUT", odl_callhome_payload, 0, 0);
     if(rc != NTS_ERR_OK) {
-        log_error("http_request failed");
+        log_error("http_request failed\n");
     }
     
     free(url);