From 8fe7485a600f60be9ac20af923a61d516cb0335e Mon Sep 17 00:00:00 2001
From: Andrew Moss <1043609+amoss@users.noreply.github.com>
Date: Tue, 31 Mar 2020 21:19:34 +0200
Subject: [PATCH] Switching over to soft feature flag (#8545)

Preparing for the cloud release. This changes how we handle the feature flag so that it no longer requires installer switches and can be set from the config file. This still requires internal access to use and is not ready for public access yet.
---
 Makefile.am             | 20 +++++++++++---------
 aclk/agent_cloud_link.c |  7 +++++++
 claim/claim.c           | 10 ++++++----
 configure.ac            | 24 +++++++++++++++---------
 daemon/commands.c       |  6 +++++-
 daemon/common.c         |  2 ++
 daemon/common.h         |  1 +
 daemon/main.c           | 15 +++++++++++++++
 database/rrddim.c       | 21 ++++++++++++++-------
 database/rrdset.c       | 12 ++++++++----
 health/health.c         |  9 ++++++---
 health/health_log.c     |  3 ++-
 netdata-installer.sh    |  4 ----
 web/api/web_api_v1.c    |  9 ++++++---
 14 files changed, 98 insertions(+), 45 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 9f1e7868ed..32a7894e38 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -469,14 +469,18 @@ BACKENDS_PLUGIN_FILES = \
     backends/prometheus/backend_prometheus.h \
     $(NULL)
 
-CLAIM_PLUGIN_FILES = \
+CLAIM_FILES = \
     claim/claim.c \
     claim/claim.h \
     $(NULL)
 
-ACLK_PLUGIN_FILES = \
+ACLK_FILES = \
     aclk/aclk_common.c \
     aclk/aclk_common.h \
+    $(NULL)
+
+if ENABLE_ACLK
+ACLK_FILES += \
     aclk/agent_cloud_link.c \
     aclk/agent_cloud_link.h \
     aclk/mqtt.c \
@@ -486,6 +490,9 @@ ACLK_PLUGIN_FILES = \
     aclk/aclk_lws_https_client.c \
     aclk/aclk_lws_https_client.h \
     $(NULL)
+endif
+
+
 
 EXPORTING_ENGINE_FILES = \
     exporting/exporting_engine.c \
@@ -575,15 +582,10 @@ NETDATA_FILES = \
     $(STREAMING_PLUGIN_FILES) \
     $(STATSD_PLUGIN_FILES) \
     $(WEB_PLUGIN_FILES) \
-    $(CLAIM_PLUGIN_FILES) \
+    $(CLAIM_FILES) \
+    $(ACLK_FILES) \
     $(NULL)
 
-if ENABLE_ACLK
-    NETDATA_FILES += \
-        $(ACLK_PLUGIN_FILES) \
-        $(NULL)
-endif
-
 if FREEBSD
     NETDATA_FILES += \
         $(FREEBSD_PLUGIN_FILES) \
diff --git a/aclk/agent_cloud_link.c b/aclk/agent_cloud_link.c
index 39e07a309c..a4e2896e4f 100644
--- a/aclk/agent_cloud_link.c
+++ b/aclk/agent_cloud_link.c
@@ -1309,6 +1309,10 @@ void *aclk_main(void *ptr)
     struct netdata_static_thread *query_thread;
 
     netdata_thread_cleanup_push(aclk_main_cleanup, ptr);
+    if (!netdata_cloud_setting) {
+        info("Killing ACLK thread -> cloud functionality has been disabled");
+        return NULL;
+    }
 
     info("Waiting for netdata to be ready");
     while (!netdata_ready) {
@@ -1755,6 +1759,9 @@ int aclk_update_chart(RRDHOST *host, char *chart_name, ACLK_CMD aclk_cmd)
     UNUSED(chart_name);
     return 0;
 #else
+    if (!netdata_cloud_setting)
+        return 0;
+
     if (host != localhost)
         return 0;
 
diff --git a/claim/claim.c b/claim/claim.c
index aabcc18a23..6e14cea658 100644
--- a/claim/claim.c
+++ b/claim/claim.c
@@ -41,11 +41,12 @@ extern struct registry registry;
 /* rrd_init() must have been called before this function */
 void claim_agent(char *claiming_arguments)
 {
-#ifndef ENABLE_CLOUD
-    info("The claiming feature has been disabled");
-    return;
-#endif
+    if (!netdata_cloud_setting) {
+        error("Refusing to claim agent -> cloud functionality has been disabled");
+        return;
+    }
 
+#ifndef DISABLE_CLOUD
     int exit_code;
     pid_t command_pid;
     char command_buffer[CLAIMING_COMMAND_LENGTH + 1];
@@ -106,6 +107,7 @@ void claim_agent(char *claiming_arguments)
     }
     error("Agent failed to be claimed with the following error message:");
     error("\"%s\"", claiming_errors[exit_code]);
+#endif
 }
 
 void load_claiming_state(void)
diff --git a/configure.ac b/configure.ac
index edad9f425e..06d8b81717 100644
--- a/configure.ac
+++ b/configure.ac
@@ -169,19 +169,18 @@ AC_ARG_ENABLE(
     [cloud],
     [AS_HELP_STRING([--disable-cloud],
                     [Disables all cloud functionality])],
-    [],
-    [enable_cloud="no"]
+    [ enable_cloud="$enableval" ],
+    [ enable_cloud="yes" ]
 )
 
 AC_MSG_CHECKING([if cloud functionality should be enabled])
-if test "${enable_cloud}" != "no"; then
-    AC_DEFINE([ENABLE_CLOUD], [1], [netdata cloud functionality])
-    aclk_required="detect"
-else
+if test "${enable_cloud}" = "no"; then
+    AC_DEFINE([DISABLE_CLOUD], [1], [disable netdata cloud functionality])
     aclk_required="no"
+else
+    aclk_required="detect"
 fi
 AC_MSG_RESULT([${enable_cloud}])
-AM_CONDITIONAL([ENABLE_CLOUD], [test "${enable_cloud}" = "yes"])
 
 # -----------------------------------------------------------------------------
 # netdata required checks
@@ -557,9 +556,16 @@ AM_CONDITIONAL([ENABLE_CAPABILITY], [test "${with_libcap}" = "yes"])
 # ACLK
 
 if test "$enable_cloud" = "yes"; then
-    AC_MSG_CHECKING([if libmosquitto static lib is present])
+    AC_MSG_CHECKING([if libmosquitto static lib is present (and builds)])
     if test -f "externaldeps/mosquitto/libmosquitto.a"; then
-        HAVE_libmosquitto_a="yes"
+        LIBS_SAVES="$LIBS"
+        LIBS="externaldeps/mosquitto/libmosquitto.a"
+        AC_LINK_IFELSE([AC_LANG_SOURCE([[int main (int argc, char **argv)) {
+                                             int m,mm,r;
+                                             mosquitto_lib_version(&m, &mm, &r);
+                                         }]]),
+                                        [HAVE_libmosquitto_a="yes"],
+                                        [HAVE_libmosquitto_a="no"]])
     else
         HAVE_libmosquitto_a="no"
         AC_DEFINE([ACLK_NO_LIBMOSQ], [1], [Libmosquitto.a was not found during build.])
diff --git a/daemon/commands.c b/daemon/commands.c
index e4a33c91bc..295972e6fe 100644
--- a/daemon/commands.c
+++ b/daemon/commands.c
@@ -186,7 +186,7 @@ static cmd_status_t cmd_reload_claiming_state_execute(char *args, char **message
     (void)args;
     (void)message;
 
-#ifndef ENABLE_CLOUD
+#ifdef DISABLE_CLOUD
     info("The claiming feature has been disabled");
     return CMD_STATUS_FAILURE;
 #endif
@@ -194,6 +194,10 @@ static cmd_status_t cmd_reload_claiming_state_execute(char *args, char **message
     info("Cloud functionality is not enabled because of missing dependencies at build-time.");
     return CMD_STATUS_FAILURE;
 #endif
+    if (!netdata_cloud_setting) {
+        error("Cannot reload claiming status -> cloud functionality has been disabled");
+        return CMD_STATUS_FAILURE;
+    }
 
     error_log_limit_unlimited();
     info("COMMAND: Reloading Agent Claiming configuration.");
diff --git a/daemon/common.c b/daemon/common.c
index 67497a4e93..7061040445 100644
--- a/daemon/common.c
+++ b/daemon/common.c
@@ -14,3 +14,5 @@ char *netdata_configured_home_dir            = CACHE_DIR;
 char *netdata_configured_host_prefix         = NULL;
 char *netdata_configured_timezone            = NULL;
 int netdata_ready;
+int netdata_cloud_setting;
+
diff --git a/daemon/common.h b/daemon/common.h
index ffe4145b51..fe799efe09 100644
--- a/daemon/common.h
+++ b/daemon/common.h
@@ -88,5 +88,6 @@ extern int netdata_zero_metrics_enabled;
 extern int netdata_anonymous_statistics_enabled;
 
 extern int netdata_ready;
+extern int netdata_cloud_setting;
 
 #endif /* NETDATA_COMMON_H */
diff --git a/daemon/main.c b/daemon/main.c
index e64f040ece..38c831f1e7 100644
--- a/daemon/main.c
+++ b/daemon/main.c
@@ -575,6 +575,21 @@ static void get_netdata_configured_variables() {
     get_system_HZ();
     get_system_cpus();
     get_system_pid_max();
+
+    // --------------------------------------------------------------------
+    // Check if the cloud is enabled
+#ifdef DISABLE_CLOUD
+    netdata_cloud_setting = 0;
+#else
+    char *cloud = config_get(CONFIG_SECTION_GLOBAL, "netdata cloud", "coming soon");
+    if (!strcmp(cloud, "coming soon")) {
+        netdata_cloud_setting = 0;          // Note: this flips to 1 after the release
+    } else if (!strcmp(cloud, "enable")) {
+        netdata_cloud_setting = 1;
+    } else if (!strcmp(cloud, "disable")) {
+        netdata_cloud_setting = 0;
+    }
+#endif
 }
 
 static void get_system_timezone(void) {
diff --git a/database/rrddim.c b/database/rrddim.c
index 11f43ab321..3e94021e78 100644
--- a/database/rrddim.c
+++ b/database/rrddim.c
@@ -184,7 +184,8 @@ void rrdcalc_link_to_rrddim(RRDDIM *rd, RRDSET *st, RRDHOST *host) {
         }
     }
 #ifdef ENABLE_ACLK
-    aclk_update_chart(st->rrdhost, st->id, ACLK_CMD_CHART);
+    if (netdata_cloud_setting)
+        aclk_update_chart(st->rrdhost, st->id, ACLK_CMD_CHART);
 #endif
 }
 
@@ -428,7 +429,8 @@ RRDDIM *rrddim_add_custom(RRDSET *st, const char *id, const char *name, collecte
     }
     rrdset_unlock(st);
 #ifdef ENABLE_ACLK
-    aclk_update_chart(host, st->id, ACLK_CMD_CHART);
+    if (netdata_cloud_setting)
+        aclk_update_chart(host, st->id, ACLK_CMD_CHART);
 #endif
     return(rd);
 }
@@ -484,7 +486,8 @@ void rrddim_free(RRDSET *st, RRDDIM *rd)
             break;
     }
 #ifdef ENABLE_ACLK
-    aclk_update_chart(st->rrdhost, st->id, ACLK_CMD_CHART);
+    if (netdata_cloud_setting)
+        aclk_update_chart(st->rrdhost, st->id, ACLK_CMD_CHART);
 #endif
 }
 
@@ -505,7 +508,8 @@ int rrddim_hide(RRDSET *st, const char *id) {
 
     rrddim_flag_set(rd, RRDDIM_FLAG_HIDDEN);
 #ifdef ENABLE_ACLK
-    aclk_update_chart(st->rrdhost, st->id, ACLK_CMD_CHART);
+    if (netdata_cloud_setting)
+        aclk_update_chart(st->rrdhost, st->id, ACLK_CMD_CHART);
 #endif
     return 0;
 }
@@ -522,7 +526,8 @@ int rrddim_unhide(RRDSET *st, const char *id) {
 
     rrddim_flag_clear(rd, RRDDIM_FLAG_HIDDEN);
 #ifdef ENABLE_ACLK
-    aclk_update_chart(st->rrdhost, st->id, ACLK_CMD_CHART);
+    if (netdata_cloud_setting)
+        aclk_update_chart(st->rrdhost, st->id, ACLK_CMD_CHART);
 #endif
     return 0;
 }
@@ -533,7 +538,8 @@ inline void rrddim_is_obsolete(RRDSET *st, RRDDIM *rd) {
     rrddim_flag_set(rd, RRDDIM_FLAG_OBSOLETE);
     rrdset_flag_set(st, RRDSET_FLAG_OBSOLETE_DIMENSIONS);
 #ifdef ENABLE_ACLK
-    aclk_update_chart(st->rrdhost, st->id, ACLK_CMD_CHART);
+    if (netdata_cloud_setting)
+        aclk_update_chart(st->rrdhost, st->id, ACLK_CMD_CHART);
 #endif
 }
 
@@ -542,7 +548,8 @@ inline void rrddim_isnot_obsolete(RRDSET *st __maybe_unused, RRDDIM *rd) {
 
     rrddim_flag_clear(rd, RRDDIM_FLAG_OBSOLETE);
 #ifdef ENABLE_ACLK
-    aclk_update_chart(st->rrdhost, st->id, ACLK_CMD_CHART);
+    if (netdata_cloud_setting)
+        aclk_update_chart(st->rrdhost, st->id, ACLK_CMD_CHART);
 #endif
 }
 
diff --git a/database/rrdset.c b/database/rrdset.c
index ced1021ac7..d0554f0f30 100644
--- a/database/rrdset.c
+++ b/database/rrdset.c
@@ -425,8 +425,10 @@ void rrdset_delete(RRDSET *st) {
 
     recursively_delete_dir(st->cache_dir, "left-over chart");
 #ifdef ENABLE_ACLK
-    aclk_del_collector(st->rrdhost->hostname, st->plugin_name, st->module_name);
-    aclk_update_chart(st->rrdhost, st->id, ACLK_CMD_CHARTDEL);
+    if (netdata_cloud_setting) {
+        aclk_del_collector(st->rrdhost->hostname, st->plugin_name, st->module_name);
+        aclk_update_chart(st->rrdhost, st->id, ACLK_CMD_CHARTDEL);
+    }
 #endif
 }
 
@@ -768,8 +770,10 @@ RRDSET *rrdset_create_custom(
 
     rrdhost_unlock(host);
 #ifdef ENABLE_ACLK
-    aclk_add_collector(host->hostname, plugin, module);
-    aclk_update_chart(host, st->id, ACLK_CMD_CHART);
+    if (netdata_cloud_setting) {
+        aclk_add_collector(host->hostname, plugin, module);
+        aclk_update_chart(host, st->id, ACLK_CMD_CHART);
+    }
 #endif
     return(st);
 }
diff --git a/health/health.c b/health/health.c
index d3e01faf1c..cbc7554cb4 100644
--- a/health/health.c
+++ b/health/health.c
@@ -180,7 +180,8 @@ void health_reload_host(RRDHOST *host) {
  */
 void health_reload(void) {
 #ifdef ENABLE_ACLK
-    aclk_single_update_disable();
+    if (netdata_cloud_setting)
+        aclk_single_update_disable();
 #endif
     rrd_rdlock();
 
@@ -190,8 +191,10 @@ void health_reload(void) {
 
     rrd_unlock();
 #ifdef ENABLE_ACLK
-    aclk_single_update_enable();
-    aclk_alarm_reload();
+    if (netdata_cloud_setting) {
+        aclk_single_update_enable();
+        aclk_alarm_reload();
+    }
 #endif
 }
 
diff --git a/health/health_log.c b/health/health_log.c
index 802923d492..b9ea52a4f0 100644
--- a/health/health_log.c
+++ b/health/health_log.c
@@ -153,7 +153,8 @@ inline void health_alarm_log_save(RRDHOST *host, ALARM_ENTRY *ae) {
         }
     }
 #ifdef ENABLE_ACLK
-    aclk_update_alarm(host, ae);
+    if (netdata_cloud_setting)
+        aclk_update_alarm(host, ae);
 #endif
 }
 
diff --git a/netdata-installer.sh b/netdata-installer.sh
index 3676cb7d76..6e8137ed16 100755
--- a/netdata-installer.sh
+++ b/netdata-installer.sh
@@ -283,10 +283,6 @@ while [ -n "${1}" ]; do
       NETDATA_DISABLE_CLOUD=1
       NETDATA_CONFIGURE_OPTIONS="${NETDATA_CONFIGURE_OPTIONS//--disable-cloud/} --disable-cloud"
       ;;
-    "--cloud-testing")          # Temporary, until we flip the feature flag. Internal use only
-      unset NETDATA_DISABLE_CLOUD
-      NETDATA_CONFIGURE_OPTIONS="${NETDATA_CONFIGURE_OPTIONS//--disable-cloud/} --enable-cloud"
-      ;;
     "--install")
       NETDATA_PREFIX="${2}/netdata"
       shift 1
diff --git a/web/api/web_api_v1.c b/web/api/web_api_v1.c
index d0dd0cd014..2d8c7a8147 100644
--- a/web/api/web_api_v1.c
+++ b/web/api/web_api_v1.c
@@ -862,10 +862,13 @@ inline int web_client_api_request_v1_info_fill_buffer(RRDHOST *host, BUFFER *wb)
     chartcollectors2json(host, wb);
     buffer_strcat(wb, "\n\t],\n");
 
-#ifdef ENABLE_CLOUD
-    buffer_strcat(wb, "\t\"cloud-enabled\": true,\n");
-#else
+#ifdef DISABLE_CLOUD
     buffer_strcat(wb, "\t\"cloud-enabled\": false,\n");
+#else
+    if (netdata_cloud_setting)
+        buffer_strcat(wb, "\t\"cloud-enabled\": true,\n");
+    else
+        buffer_strcat(wb, "\t\"cloud-enabled\": false,\n");
 #endif
 #ifdef ENABLE_ACLK
     buffer_strcat(wb, "\t\"cloud-available\": true,\n");