|
|
ee3a35 |
From 3987cd929d859f900318b393133c3bdde8dfffd5 Mon Sep 17 00:00:00 2001
|
|
|
ee3a35 |
From: Rich Megginson <rmeggins@redhat.com>
|
|
|
ee3a35 |
Date: Tue, 28 Aug 2018 12:44:23 -0600
|
|
|
ee3a35 |
Subject: [PATCH] mmkubertnetes: action fails preparation cycle if kubernetes
|
|
|
ee3a35 |
API destroys resource during bootup sequence
|
|
|
ee3a35 |
|
|
|
ee3a35 |
The plugin was not handling 404 Not Found correctly when looking
|
|
|
ee3a35 |
up pods and namespaces. In this case, we assume the pod/namespace
|
|
|
ee3a35 |
was deleted, annotate the record with whatever metadata we have,
|
|
|
ee3a35 |
and cache the fact that the pod/namespace is missing so we don't
|
|
|
ee3a35 |
attempt to look it up again.
|
|
|
ee3a35 |
In addition, the plugin was not handling error 429 Busy correctly.
|
|
|
ee3a35 |
In this case, it should also annotate the record with whatever
|
|
|
ee3a35 |
metadata it has, and _not_ cache anything. By default the plugin
|
|
|
ee3a35 |
will retry every 5 seconds to connect to Kubernetes. This
|
|
|
ee3a35 |
behavior is controlled by the new config param `busyretryinterval`.
|
|
|
ee3a35 |
This commit also adds impstats counters so that admins can
|
|
|
ee3a35 |
view the state of the plugin to see if the lookups are working
|
|
|
ee3a35 |
or are returning errors. The stats are reported per-instance
|
|
|
ee3a35 |
or per-action to facilitate using multiple different actions
|
|
|
ee3a35 |
for different Kubernetes servers.
|
|
|
ee3a35 |
This commit also adds support for client cert auth to
|
|
|
ee3a35 |
Kubernetes via the two new config params `tls.mycert` and
|
|
|
ee3a35 |
`tls.myprivkey`.
|
|
|
ee3a35 |
---
|
|
|
ee3a35 |
contrib/mmkubernetes/mmkubernetes.c | 296 ++++++++++++++++++++++++----
|
|
|
ee3a35 |
1 files changed, 272 insertions(+), 24 deletions(-)
|
|
|
ee3a35 |
|
|
|
ee3a35 |
diff --git a/contrib/mmkubernetes/mmkubernetes.c b/contrib/mmkubernetes/mmkubernetes.c
|
|
|
ee3a35 |
index 422cb2577..5bf5b049d 100644
|
|
|
ee3a35 |
--- a/contrib/mmkubernetes/mmkubernetes.c
|
|
|
ee3a35 |
+++ b/contrib/mmkubernetes/mmkubernetes.c
|
|
|
ee3a35 |
@@ -52,9 +52,12 @@
|
|
|
ee3a35 |
#include "syslogd-types.h"
|
|
|
ee3a35 |
#include "module-template.h"
|
|
|
ee3a35 |
#include "errmsg.h"
|
|
|
ee3a35 |
+#include "statsobj.h"
|
|
|
ee3a35 |
#include "regexp.h"
|
|
|
ee3a35 |
#include "hashtable.h"
|
|
|
ee3a35 |
#include "srUtils.h"
|
|
|
ee3a35 |
+#include "unicode-helper.h"
|
|
|
ee3a35 |
+#include "datetime.h"
|
|
|
ee3a35 |
|
|
|
ee3a35 |
/* static data */
|
|
|
ee3a35 |
MODULE_TYPE_OUTPUT /* this is technically an output plugin */
|
|
|
ee3a35 |
@@ -62,6 +65,8 @@ MODULE_TYPE_KEEP /* releasing the module would cause a leak through libcurl */
|
|
|
ee3a35 |
DEF_OMOD_STATIC_DATA
|
|
|
ee3a35 |
DEFobjCurrIf(errmsg)
|
|
|
ee3a35 |
DEFobjCurrIf(regexp)
|
|
|
ee3a35 |
+DEFobjCurrIf(statsobj)
|
|
|
ee3a35 |
+DEFobjCurrIf(datetime)
|
|
|
ee3a35 |
|
|
|
ee3a35 |
#define HAVE_LOADSAMPLESFROMSTRING 1
|
|
|
ee3a35 |
#if defined(NO_LOADSAMPLESFROMSTRING)
|
|
|
ee3a35 |
@@ -95,12 +100,14 @@ DEFobjCurrIf(regexp)
|
|
|
ee3a35 |
#define DFLT_CONTAINER_NAME "$!CONTAINER_NAME" /* name of variable holding CONTAINER_NAME value */
|
|
|
ee3a35 |
#define DFLT_CONTAINER_ID_FULL "$!CONTAINER_ID_FULL" /* name of variable holding CONTAINER_ID_FULL value */
|
|
|
ee3a35 |
#define DFLT_KUBERNETES_URL "https://kubernetes.default.svc.cluster.local:443"
|
|
|
ee3a35 |
+#define DFLT_BUSY_RETRY_INTERVAL 5 /* retry every 5 seconds */
|
|
|
ee3a35 |
|
|
|
ee3a35 |
static struct cache_s {
|
|
|
ee3a35 |
const uchar *kbUrl;
|
|
|
ee3a35 |
struct hashtable *mdHt;
|
|
|
ee3a35 |
struct hashtable *nsHt;
|
|
|
ee3a35 |
pthread_mutex_t *cacheMtx;
|
|
|
ee3a35 |
+ int lastBusyTime;
|
|
|
ee3a35 |
} **caches;
|
|
|
ee3a35 |
|
|
|
ee3a35 |
typedef struct {
|
|
|
ee3a35 |
@@ -116,6 +123,8 @@ struct modConfData_s {
|
|
|
ee3a35 |
uchar *srcMetadataPath; /* where to get data for kubernetes queries */
|
|
|
ee3a35 |
uchar *dstMetadataPath; /* where to put metadata obtained from kubernetes */
|
|
|
ee3a35 |
uchar *caCertFile; /* File holding the CA cert (+optional chain) of CA that issued the Kubernetes server cert */
|
|
|
ee3a35 |
+ uchar *myCertFile; /* File holding cert corresponding to private key used for client cert auth */
|
|
|
ee3a35 |
+ uchar *myPrivKeyFile; /* File holding private key corresponding to cert used for client cert auth */
|
|
|
ee3a35 |
sbool allowUnsignedCerts; /* For testing/debugging - do not check for CA certs (CURLOPT_SSL_VERIFYPEER FALSE) */
|
|
|
ee3a35 |
uchar *token; /* The token value to use to authenticate to Kubernetes - takes precedence over tokenFile */
|
|
|
ee3a35 |
uchar *tokenFile; /* The file whose contents is the token value to use to authenticate to Kubernetes */
|
|
|
ee3a35 |
@@ -127,6 +136,7 @@ struct modConfData_s {
|
|
|
ee3a35 |
uchar *fnRulebase; /* lognorm rulebase filename for container log filename match */
|
|
|
ee3a35 |
char *contRules; /* lognorm rules for CONTAINER_NAME value match */
|
|
|
ee3a35 |
uchar *contRulebase; /* lognorm rulebase filename for CONTAINER_NAME value match */
|
|
|
ee3a35 |
+ int busyRetryInterval; /* how to handle 429 response - 0 means error, non-zero means retry every N seconds */
|
|
|
ee3a35 |
};
|
|
|
ee3a35 |
|
|
|
ee3a35 |
/* action (instance) configuration data */
|
|
|
ee3a35 |
@@ -135,6 +145,8 @@ typedef struct _instanceData {
|
|
|
ee3a35 |
msgPropDescr_t *srcMetadataDescr; /* where to get data for kubernetes queries */
|
|
|
ee3a35 |
uchar *dstMetadataPath; /* where to put metadata obtained from kubernetes */
|
|
|
ee3a35 |
uchar *caCertFile; /* File holding the CA cert (+optional chain) of CA that issued the Kubernetes server cert */
|
|
|
ee3a35 |
+ uchar *myCertFile; /* File holding cert corresponding to private key used for client cert auth */
|
|
|
ee3a35 |
+ uchar *myPrivKeyFile; /* File holding private key corresponding to cert used for client cert auth */
|
|
|
ee3a35 |
sbool allowUnsignedCerts; /* For testing/debugging - do not check for CA certs (CURLOPT_SSL_VERIFYPEER FALSE) */
|
|
|
ee3a35 |
uchar *token; /* The token value to use to authenticate to Kubernetes - takes precedence over tokenFile */
|
|
|
ee3a35 |
uchar *tokenFile; /* The file whose contents is the token value to use to authenticate to Kubernetes */
|
|
|
ee3a35 |
@@ -151,6 +163,7 @@ typedef struct _instanceData {
|
|
|
ee3a35 |
msgPropDescr_t *contNameDescr; /* CONTAINER_NAME field */
|
|
|
ee3a35 |
msgPropDescr_t *contIdFullDescr; /* CONTAINER_ID_FULL field */
|
|
|
ee3a35 |
struct cache_s *cache;
|
|
|
ee3a35 |
+ int busyRetryInterval; /* how to handle 429 response - 0 means error, non-zero means retry every N seconds */
|
|
|
ee3a35 |
} instanceData;
|
|
|
ee3a35 |
|
|
|
ee3a35 |
typedef struct wrkrInstanceData {
|
|
|
ee3a35 |
@@ -159,6 +172,16 @@ typedef struct wrkrInstanceData {
|
|
|
ee3a35 |
struct curl_slist *curlHdr;
|
|
|
ee3a35 |
char *curlRply;
|
|
|
ee3a35 |
size_t curlRplyLen;
|
|
|
ee3a35 |
+ statsobj_t *stats; /* stats for this instance */
|
|
|
ee3a35 |
+ STATSCOUNTER_DEF(k8sRecordSeen, mutK8sRecordSeen)
|
|
|
ee3a35 |
+ STATSCOUNTER_DEF(namespaceMetadataSuccess, mutNamespaceMetadataSuccess)
|
|
|
ee3a35 |
+ STATSCOUNTER_DEF(namespaceMetadataNotFound, mutNamespaceMetadataNotFound)
|
|
|
ee3a35 |
+ STATSCOUNTER_DEF(namespaceMetadataBusy, mutNamespaceMetadataBusy)
|
|
|
ee3a35 |
+ STATSCOUNTER_DEF(namespaceMetadataError, mutNamespaceMetadataError)
|
|
|
ee3a35 |
+ STATSCOUNTER_DEF(podMetadataSuccess, mutPodMetadataSuccess)
|
|
|
ee3a35 |
+ STATSCOUNTER_DEF(podMetadataNotFound, mutPodMetadataNotFound)
|
|
|
ee3a35 |
+ STATSCOUNTER_DEF(podMetadataBusy, mutPodMetadataBusy)
|
|
|
ee3a35 |
+ STATSCOUNTER_DEF(podMetadataError, mutPodMetadataError)
|
|
|
ee3a35 |
} wrkrInstanceData_t;
|
|
|
ee3a35 |
|
|
|
ee3a35 |
/* module parameters (v6 config format) */
|
|
|
ee3a35 |
@@ -167,6 +190,8 @@ static struct cnfparamdescr modpdescr[] = {
|
|
|
ee3a35 |
{ "srcmetadatapath", eCmdHdlrString, 0 },
|
|
|
ee3a35 |
{ "dstmetadatapath", eCmdHdlrString, 0 },
|
|
|
ee3a35 |
{ "tls.cacert", eCmdHdlrString, 0 },
|
|
|
ee3a35 |
+ { "tls.mycert", eCmdHdlrString, 0 },
|
|
|
ee3a35 |
+ { "tls.myprivkey", eCmdHdlrString, 0 },
|
|
|
ee3a35 |
{ "allowunsignedcerts", eCmdHdlrBinary, 0 },
|
|
|
ee3a35 |
{ "token", eCmdHdlrString, 0 },
|
|
|
ee3a35 |
{ "tokenfile", eCmdHdlrString, 0 },
|
|
|
ee3a35 |
@@ -174,7 +199,8 @@ static struct cnfparamdescr modpdescr[] = {
|
|
|
ee3a35 |
{ "de_dot", eCmdHdlrBinary, 0 },
|
|
|
ee3a35 |
{ "de_dot_separator", eCmdHdlrString, 0 },
|
|
|
ee3a35 |
{ "filenamerulebase", eCmdHdlrString, 0 },
|
|
|
ee3a35 |
- { "containerrulebase", eCmdHdlrString, 0 }
|
|
|
ee3a35 |
+ { "containerrulebase", eCmdHdlrString, 0 },
|
|
|
ee3a35 |
+ { "busyretryinterval", eCmdHdlrInt, 0 }
|
|
|
ee3a35 |
#if HAVE_LOADSAMPLESFROMSTRING == 1
|
|
|
ee3a35 |
,
|
|
|
ee3a35 |
{ "filenamerules", eCmdHdlrArray, 0 },
|
|
|
ee3a35 |
@@ -193,6 +219,8 @@ static struct cnfparamdescr actpdescr[] = {
|
|
|
ee3a35 |
{ "srcmetadatapath", eCmdHdlrString, 0 },
|
|
|
ee3a35 |
{ "dstmetadatapath", eCmdHdlrString, 0 },
|
|
|
ee3a35 |
{ "tls.cacert", eCmdHdlrString, 0 },
|
|
|
ee3a35 |
+ { "tls.mycert", eCmdHdlrString, 0 },
|
|
|
ee3a35 |
+ { "tls.myprivkey", eCmdHdlrString, 0 },
|
|
|
ee3a35 |
{ "allowunsignedcerts", eCmdHdlrBinary, 0 },
|
|
|
ee3a35 |
{ "token", eCmdHdlrString, 0 },
|
|
|
ee3a35 |
{ "tokenfile", eCmdHdlrString, 0 },
|
|
|
ee3a35 |
@@ -200,7 +228,8 @@ static struct cnfparamdescr actpdescr[] = {
|
|
|
ee3a35 |
{ "de_dot", eCmdHdlrBinary, 0 },
|
|
|
ee3a35 |
{ "de_dot_separator", eCmdHdlrString, 0 },
|
|
|
ee3a35 |
{ "filenamerulebase", eCmdHdlrString, 0 },
|
|
|
ee3a35 |
- { "containerrulebase", eCmdHdlrString, 0 }
|
|
|
ee3a35 |
+ { "containerrulebase", eCmdHdlrString, 0 },
|
|
|
ee3a35 |
+ { "busyretryinterval", eCmdHdlrInt, 0 }
|
|
|
ee3a35 |
#if HAVE_LOADSAMPLESFROMSTRING == 1
|
|
|
ee3a35 |
,
|
|
|
ee3a35 |
{ "filenamerules", eCmdHdlrArray, 0 },
|
|
|
ee3a35 |
@@ -493,8 +522,9 @@ ENDbeginCnfLoad
|
|
|
ee3a35 |
BEGINsetModCnf
|
|
|
ee3a35 |
struct cnfparamvals *pvals = NULL;
|
|
|
ee3a35 |
int i;
|
|
|
ee3a35 |
- FILE *fp;
|
|
|
ee3a35 |
+ FILE *fp = NULL;
|
|
|
ee3a35 |
int ret;
|
|
|
ee3a35 |
+ char errStr[1024];
|
|
|
ee3a35 |
CODESTARTsetModCnf
|
|
|
ee3a35 |
pvals = nvlstGetParams(lst, &modpblk, NULL);
|
|
|
ee3a35 |
if(pvals == NULL) {
|
|
|
ee3a35 |
@@ -509,6 +539,7 @@ CODESTARTsetModCnf
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
|
|
|
ee3a35 |
loadModConf->de_dot = DFLT_DE_DOT;
|
|
|
ee3a35 |
+ loadModConf->busyRetryInterval = DFLT_BUSY_RETRY_INTERVAL;
|
|
|
ee3a35 |
for(i = 0 ; i < modpblk.nParams ; ++i) {
|
|
|
ee3a35 |
if(!pvals[i].bUsed) {
|
|
|
ee3a35 |
continue;
|
|
|
ee3a35 |
@@ -528,11 +559,39 @@ CODESTARTsetModCnf
|
|
|
ee3a35 |
rs_strerror_r(errno, errStr, sizeof(errStr));
|
|
|
ee3a35 |
iRet = RS_RET_NO_FILE_ACCESS;
|
|
|
ee3a35 |
errmsg.LogError(0, iRet,
|
|
|
ee3a35 |
- "error: certificate file %s couldn't be accessed: %s\n",
|
|
|
ee3a35 |
+ "error: 'tls.cacert' file %s couldn't be accessed: %s\n",
|
|
|
ee3a35 |
loadModConf->caCertFile, errStr);
|
|
|
ee3a35 |
ABORT_FINALIZE(iRet);
|
|
|
ee3a35 |
} else {
|
|
|
ee3a35 |
fclose(fp);
|
|
|
ee3a35 |
+ fp = NULL;
|
|
|
ee3a35 |
+ }
|
|
|
ee3a35 |
+ } else if(!strcmp(modpblk.descr[i].name, "tls.mycert")) {
|
|
|
ee3a35 |
+ free(loadModConf->myCertFile);
|
|
|
ee3a35 |
+ loadModConf->myCertFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
|
ee3a35 |
+ fp = fopen((const char*)loadModConf->myCertFile, "r");
|
|
|
ee3a35 |
+ if(fp == NULL) {
|
|
|
ee3a35 |
+ rs_strerror_r(errno, errStr, sizeof(errStr));
|
|
|
ee3a35 |
+ iRet = RS_RET_NO_FILE_ACCESS;
|
|
|
ee3a35 |
+ LogError(0, iRet,
|
|
|
ee3a35 |
+ "error: 'tls.mycert' file %s couldn't be accessed: %s\n",
|
|
|
ee3a35 |
+ loadModConf->myCertFile, errStr);
|
|
|
ee3a35 |
+ } else {
|
|
|
ee3a35 |
+ fclose(fp);
|
|
|
ee3a35 |
+ fp = NULL;
|
|
|
ee3a35 |
+ }
|
|
|
ee3a35 |
+ } else if(!strcmp(modpblk.descr[i].name, "tls.myprivkey")) {
|
|
|
ee3a35 |
+ loadModConf->myPrivKeyFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
|
ee3a35 |
+ fp = fopen((const char*)loadModConf->myPrivKeyFile, "r");
|
|
|
ee3a35 |
+ if(fp == NULL) {
|
|
|
ee3a35 |
+ rs_strerror_r(errno, errStr, sizeof(errStr));
|
|
|
ee3a35 |
+ iRet = RS_RET_NO_FILE_ACCESS;
|
|
|
ee3a35 |
+ LogError(0, iRet,
|
|
|
ee3a35 |
+ "error: 'tls.myprivkey' file %s couldn't be accessed: %s\n",
|
|
|
ee3a35 |
+ loadModConf->myPrivKeyFile, errStr);
|
|
|
ee3a35 |
+ } else {
|
|
|
ee3a35 |
+ fclose(fp);
|
|
|
ee3a35 |
+ fp = NULL;
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
} else if(!strcmp(modpblk.descr[i].name, "allowunsignedcerts")) {
|
|
|
ee3a35 |
loadModConf->allowUnsignedCerts = pvals[i].val.d.n;
|
|
|
ee3a35 |
@@ -557,6 +614,7 @@ CODESTARTsetModCnf
|
|
|
ee3a35 |
ABORT_FINALIZE(iRet);
|
|
|
ee3a35 |
} else {
|
|
|
ee3a35 |
fclose(fp);
|
|
|
ee3a35 |
+ fp = NULL;
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
} else if(!strcmp(modpblk.descr[i].name, "annotation_match")) {
|
|
|
ee3a35 |
free_annotationmatch(&loadModConf->annotation_match);
|
|
|
ee3a35 |
@@ -586,6 +643,7 @@ CODESTARTsetModCnf
|
|
|
ee3a35 |
ABORT_FINALIZE(iRet);
|
|
|
ee3a35 |
} else {
|
|
|
ee3a35 |
fclose(fp);
|
|
|
ee3a35 |
+ fp = NULL;
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
#if HAVE_LOADSAMPLESFROMSTRING == 1
|
|
|
ee3a35 |
} else if(!strcmp(modpblk.descr[i].name, "containerrules")) {
|
|
|
ee3a35 |
@@ -606,7 +663,10 @@ CODESTARTsetModCnf
|
|
|
ee3a35 |
ABORT_FINALIZE(iRet);
|
|
|
ee3a35 |
} else {
|
|
|
ee3a35 |
fclose(fp);
|
|
|
ee3a35 |
+ fp = NULL;
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
+ } else if(!strcmp(modpblk.descr[i].name, "busyretryinterval")) {
|
|
|
ee3a35 |
+ loadModConf->busyRetryInterval = pvals[i].val.d.n;
|
|
|
ee3a35 |
} else {
|
|
|
ee3a35 |
dbgprintf("mmkubernetes: program error, non-handled "
|
|
|
ee3a35 |
"param '%s' in module() block\n", modpblk.descr[i].name);
|
|
|
ee3a35 |
@@ -650,6 +710,8 @@ CODESTARTsetModCnf
|
|
|
ee3a35 |
caches = calloc(1, sizeof(struct cache_s *));
|
|
|
ee3a35 |
|
|
|
ee3a35 |
finalize_it:
|
|
|
ee3a35 |
+ if (fp)
|
|
|
ee3a35 |
+ fclose(fp);
|
|
|
ee3a35 |
if(pvals != NULL)
|
|
|
ee3a35 |
cnfparamvalsDestruct(pvals, &modpblk);
|
|
|
ee3a35 |
ENDsetModCnf
|
|
|
ee3a35 |
@@ -667,6 +729,8 @@ CODESTARTfreeInstance
|
|
|
ee3a35 |
free(pData->srcMetadataDescr);
|
|
|
ee3a35 |
free(pData->dstMetadataPath);
|
|
|
ee3a35 |
free(pData->caCertFile);
|
|
|
ee3a35 |
+ free(pData->myCertFile);
|
|
|
ee3a35 |
+ free(pData->myPrivKeyFile);
|
|
|
ee3a35 |
free(pData->token);
|
|
|
ee3a35 |
free(pData->tokenFile);
|
|
|
ee3a35 |
free(pData->fnRules);
|
|
|
ee3a35 |
@@ -710,6 +774,45 @@ CODESTARTcreateWrkrInstance
|
|
|
ee3a35 |
char *tokenHdr = NULL;
|
|
|
ee3a35 |
FILE *fp = NULL;
|
|
|
ee3a35 |
char *token = NULL;
|
|
|
ee3a35 |
+ char *statsName = NULL;
|
|
|
ee3a35 |
+
|
|
|
ee3a35 |
+ CHKiRet(statsobj.Construct(&(pWrkrData->stats)));
|
|
|
ee3a35 |
+ if ((-1 == asprintf(&statsName, "mmkubernetes(%s)", pWrkrData->pData->kubernetesUrl)) ||
|
|
|
ee3a35 |
+ (!statsName)) {
|
|
|
ee3a35 |
+ ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
|
|
|
ee3a35 |
+ }
|
|
|
ee3a35 |
+ CHKiRet(statsobj.SetName(pWrkrData->stats, (uchar *)statsName));
|
|
|
ee3a35 |
+ free(statsName);
|
|
|
ee3a35 |
+ statsName = NULL;
|
|
|
ee3a35 |
+ CHKiRet(statsobj.SetOrigin(pWrkrData->stats, UCHAR_CONSTANT("mmkubernetes")));
|
|
|
ee3a35 |
+ STATSCOUNTER_INIT(pWrkrData->k8sRecordSeen, pWrkrData->mutK8sRecordSeen);
|
|
|
ee3a35 |
+ CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("recordseen"),
|
|
|
ee3a35 |
+ ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->k8sRecordSeen)));
|
|
|
ee3a35 |
+ STATSCOUNTER_INIT(pWrkrData->namespaceMetadataSuccess, pWrkrData->mutNamespaceMetadataSuccess);
|
|
|
ee3a35 |
+ CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacemetadatasuccess"),
|
|
|
ee3a35 |
+ ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceMetadataSuccess)));
|
|
|
ee3a35 |
+ STATSCOUNTER_INIT(pWrkrData->namespaceMetadataNotFound, pWrkrData->mutNamespaceMetadataNotFound);
|
|
|
ee3a35 |
+ CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacemetadatanotfound"),
|
|
|
ee3a35 |
+ ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceMetadataNotFound)));
|
|
|
ee3a35 |
+ STATSCOUNTER_INIT(pWrkrData->namespaceMetadataBusy, pWrkrData->mutNamespaceMetadataBusy);
|
|
|
ee3a35 |
+ CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacemetadatabusy"),
|
|
|
ee3a35 |
+ ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceMetadataBusy)));
|
|
|
ee3a35 |
+ STATSCOUNTER_INIT(pWrkrData->namespaceMetadataError, pWrkrData->mutNamespaceMetadataError);
|
|
|
ee3a35 |
+ CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("namespacemetadataerror"),
|
|
|
ee3a35 |
+ ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->namespaceMetadataError)));
|
|
|
ee3a35 |
+ STATSCOUNTER_INIT(pWrkrData->podMetadataSuccess, pWrkrData->mutPodMetadataSuccess);
|
|
|
ee3a35 |
+ CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podmetadatasuccess"),
|
|
|
ee3a35 |
+ ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podMetadataSuccess)));
|
|
|
ee3a35 |
+ STATSCOUNTER_INIT(pWrkrData->podMetadataNotFound, pWrkrData->mutPodMetadataNotFound);
|
|
|
ee3a35 |
+ CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podmetadatanotfound"),
|
|
|
ee3a35 |
+ ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podMetadataNotFound)));
|
|
|
ee3a35 |
+ STATSCOUNTER_INIT(pWrkrData->podMetadataBusy, pWrkrData->mutPodMetadataBusy);
|
|
|
ee3a35 |
+ CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podmetadatabusy"),
|
|
|
ee3a35 |
+ ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podMetadataBusy)));
|
|
|
ee3a35 |
+ STATSCOUNTER_INIT(pWrkrData->podMetadataError, pWrkrData->mutPodMetadataError);
|
|
|
ee3a35 |
+ CHKiRet(statsobj.AddCounter(pWrkrData->stats, UCHAR_CONSTANT("podmetadataerror"),
|
|
|
ee3a35 |
+ ctrType_IntCtr, CTR_FLAG_RESETTABLE, &(pWrkrData->podMetadataError)));
|
|
|
ee3a35 |
+ CHKiRet(statsobj.ConstructFinalize(pWrkrData->stats));
|
|
|
ee3a35 |
|
|
|
ee3a35 |
hdr = curl_slist_append(hdr, "Content-Type: text/json; charset=utf-8");
|
|
|
ee3a35 |
if (pWrkrData->pData->token) {
|
|
|
ee3a35 |
@@ -749,12 +852,20 @@ CODESTARTcreateWrkrInstance
|
|
|
ee3a35 |
curl_easy_setopt(ctx, CURLOPT_WRITEDATA, pWrkrData);
|
|
|
ee3a35 |
if(pWrkrData->pData->caCertFile)
|
|
|
ee3a35 |
curl_easy_setopt(ctx, CURLOPT_CAINFO, pWrkrData->pData->caCertFile);
|
|
|
ee3a35 |
+ if(pWrkrData->pData->myCertFile)
|
|
|
ee3a35 |
+ curl_easy_setopt(ctx, CURLOPT_SSLCERT, pWrkrData->pData->myCertFile);
|
|
|
ee3a35 |
+ if(pWrkrData->pData->myPrivKeyFile)
|
|
|
ee3a35 |
+ curl_easy_setopt(ctx, CURLOPT_SSLKEY, pWrkrData->pData->myPrivKeyFile);
|
|
|
ee3a35 |
if(pWrkrData->pData->allowUnsignedCerts)
|
|
|
ee3a35 |
curl_easy_setopt(ctx, CURLOPT_SSL_VERIFYPEER, 0);
|
|
|
ee3a35 |
|
|
|
ee3a35 |
pWrkrData->curlCtx = ctx;
|
|
|
ee3a35 |
finalize_it:
|
|
|
ee3a35 |
free(token);
|
|
|
ee3a35 |
+ free(statsName);
|
|
|
ee3a35 |
+ if ((iRet != RS_RET_OK) && pWrkrData->stats) {
|
|
|
ee3a35 |
+ statsobj.Destruct(&(pWrkrData->stats));
|
|
|
ee3a35 |
+ }
|
|
|
ee3a35 |
if (fp) {
|
|
|
ee3a35 |
fclose(fp);
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
@@ -765,6 +876,7 @@ BEGINfreeWrkrInstance
|
|
|
ee3a35 |
CODESTARTfreeWrkrInstance
|
|
|
ee3a35 |
curl_easy_cleanup(pWrkrData->curlCtx);
|
|
|
ee3a35 |
curl_slist_free_all(pWrkrData->curlHdr);
|
|
|
ee3a35 |
+ statsobj.Destruct(&(pWrkrData->stats));
|
|
|
ee3a35 |
ENDfreeWrkrInstance
|
|
|
ee3a35 |
|
|
|
ee3a35 |
|
|
|
ee3a35 |
@@ -790,6 +902,8 @@ cacheNew(const uchar *const url)
|
|
|
ee3a35 |
key_equals_string, (void (*)(void *)) json_object_put);
|
|
|
ee3a35 |
cache->nsHt = create_hashtable(100, hash_from_string,
|
|
|
ee3a35 |
key_equals_string, (void (*)(void *)) json_object_put);
|
|
|
ee3a35 |
+ dbgprintf("mmkubernetes: created cache mdht [%p] nsht [%p]\n",
|
|
|
ee3a35 |
+ cache->mdHt, cache->nsHt);
|
|
|
ee3a35 |
cache->cacheMtx = malloc(sizeof(pthread_mutex_t));
|
|
|
ee3a35 |
if (!cache->mdHt || !cache->nsHt || !cache->cacheMtx) {
|
|
|
ee3a35 |
free (cache);
|
|
|
ee3a35 |
@@ -797,6 +911,7 @@ cacheNew(const uchar *const url)
|
|
|
ee3a35 |
FINALIZE;
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
pthread_mutex_init(cache->cacheMtx, NULL);
|
|
|
ee3a35 |
+ cache->lastBusyTime = 0;
|
|
|
ee3a35 |
|
|
|
ee3a35 |
finalize_it:
|
|
|
ee3a35 |
return cache;
|
|
|
ee3a35 |
@@ -816,9 +931,10 @@ static void cacheFree(struct cache_s *cache)
|
|
|
ee3a35 |
BEGINnewActInst
|
|
|
ee3a35 |
struct cnfparamvals *pvals = NULL;
|
|
|
ee3a35 |
int i;
|
|
|
ee3a35 |
- FILE *fp;
|
|
|
ee3a35 |
+ FILE *fp = NULL;
|
|
|
ee3a35 |
char *rxstr = NULL;
|
|
|
ee3a35 |
char *srcMetadataPath = NULL;
|
|
|
ee3a35 |
+ char errStr[1024];
|
|
|
ee3a35 |
CODESTARTnewActInst
|
|
|
ee3a35 |
DBGPRINTF("newActInst (mmkubernetes)\n");
|
|
|
ee3a35 |
|
|
|
ee3a35 |
@@ -840,6 +956,7 @@ CODESTARTnewActInst
|
|
|
ee3a35 |
|
|
|
ee3a35 |
pData->de_dot = loadModConf->de_dot;
|
|
|
ee3a35 |
pData->allowUnsignedCerts = loadModConf->allowUnsignedCerts;
|
|
|
ee3a35 |
+ pData->busyRetryInterval = loadModConf->busyRetryInterval;
|
|
|
ee3a35 |
for(i = 0 ; i < actpblk.nParams ; ++i) {
|
|
|
ee3a35 |
if(!pvals[i].bUsed) {
|
|
|
ee3a35 |
continue;
|
|
|
ee3a35 |
@@ -872,6 +988,33 @@ CODESTARTnewActInst
|
|
|
ee3a35 |
ABORT_FINALIZE(iRet);
|
|
|
ee3a35 |
} else {
|
|
|
ee3a35 |
fclose(fp);
|
|
|
ee3a35 |
+ fp = NULL;
|
|
|
ee3a35 |
+ }
|
|
|
ee3a35 |
+ } else if(!strcmp(actpblk.descr[i].name, "tls.mycert")) {
|
|
|
ee3a35 |
+ pData->myCertFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
|
ee3a35 |
+ fp = fopen((const char*)pData->myCertFile, "r");
|
|
|
ee3a35 |
+ if(fp == NULL) {
|
|
|
ee3a35 |
+ rs_strerror_r(errno, errStr, sizeof(errStr));
|
|
|
ee3a35 |
+ iRet = RS_RET_NO_FILE_ACCESS;
|
|
|
ee3a35 |
+ LogError(0, iRet,
|
|
|
ee3a35 |
+ "error: 'tls.mycert' file %s couldn't be accessed: %s\n",
|
|
|
ee3a35 |
+ pData->myCertFile, errStr);
|
|
|
ee3a35 |
+ } else {
|
|
|
ee3a35 |
+ fclose(fp);
|
|
|
ee3a35 |
+ fp = NULL;
|
|
|
ee3a35 |
+ }
|
|
|
ee3a35 |
+ } else if(!strcmp(actpblk.descr[i].name, "tls.myprivkey")) {
|
|
|
ee3a35 |
+ pData->myPrivKeyFile = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
|
ee3a35 |
+ fp = fopen((const char*)pData->myPrivKeyFile, "r");
|
|
|
ee3a35 |
+ if(fp == NULL) {
|
|
|
ee3a35 |
+ rs_strerror_r(errno, errStr, sizeof(errStr));
|
|
|
ee3a35 |
+ iRet = RS_RET_NO_FILE_ACCESS;
|
|
|
ee3a35 |
+ LogError(0, iRet,
|
|
|
ee3a35 |
+ "error: 'tls.myprivkey' file %s couldn't be accessed: %s\n",
|
|
|
ee3a35 |
+ pData->myPrivKeyFile, errStr);
|
|
|
ee3a35 |
+ } else {
|
|
|
ee3a35 |
+ fclose(fp);
|
|
|
ee3a35 |
+ fp = NULL;
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
} else if(!strcmp(actpblk.descr[i].name, "allowunsignedcerts")) {
|
|
|
ee3a35 |
pData->allowUnsignedCerts = pvals[i].val.d.n;
|
|
|
ee3a35 |
@@ -892,6 +1034,7 @@ CODESTARTnewActInst
|
|
|
ee3a35 |
ABORT_FINALIZE(iRet);
|
|
|
ee3a35 |
} else {
|
|
|
ee3a35 |
fclose(fp);
|
|
|
ee3a35 |
+ fp = NULL;
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
} else if(!strcmp(actpblk.descr[i].name, "annotation_match")) {
|
|
|
ee3a35 |
free_annotationmatch(&pData->annotation_match);
|
|
|
ee3a35 |
@@ -921,6 +1063,7 @@ CODESTARTnewActInst
|
|
|
ee3a35 |
ABORT_FINALIZE(iRet);
|
|
|
ee3a35 |
} else {
|
|
|
ee3a35 |
fclose(fp);
|
|
|
ee3a35 |
+ fp = NULL;
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
#if HAVE_LOADSAMPLESFROMSTRING == 1
|
|
|
ee3a35 |
} else if(!strcmp(modpblk.descr[i].name, "containerrules")) {
|
|
|
ee3a35 |
@@ -941,7 +1083,10 @@ CODESTARTnewActInst
|
|
|
ee3a35 |
ABORT_FINALIZE(iRet);
|
|
|
ee3a35 |
} else {
|
|
|
ee3a35 |
fclose(fp);
|
|
|
ee3a35 |
+ fp = NULL;
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
+ } else if(!strcmp(actpblk.descr[i].name, "busyretryinterval")) {
|
|
|
ee3a35 |
+ pData->busyRetryInterval = pvals[i].val.d.n;
|
|
|
ee3a35 |
} else {
|
|
|
ee3a35 |
dbgprintf("mmkubernetes: program error, non-handled "
|
|
|
ee3a35 |
"param '%s' in action() block\n", actpblk.descr[i].name);
|
|
|
ee3a35 |
@@ -982,6 +1127,10 @@ CODESTARTnewActInst
|
|
|
ee3a35 |
pData->dstMetadataPath = (uchar *) strdup((char *) loadModConf->dstMetadataPath);
|
|
|
ee3a35 |
if(pData->caCertFile == NULL && loadModConf->caCertFile)
|
|
|
ee3a35 |
pData->caCertFile = (uchar *) strdup((char *) loadModConf->caCertFile);
|
|
|
ee3a35 |
+ if(pData->myCertFile == NULL && loadModConf->myCertFile)
|
|
|
ee3a35 |
+ pData->myCertFile = (uchar *) strdup((char *) loadModConf->myCertFile);
|
|
|
ee3a35 |
+ if(pData->myPrivKeyFile == NULL && loadModConf->myPrivKeyFile)
|
|
|
ee3a35 |
+ pData->myPrivKeyFile = (uchar *) strdup((char *) loadModConf->myPrivKeyFile);
|
|
|
ee3a35 |
if(pData->token == NULL && loadModConf->token)
|
|
|
ee3a35 |
pData->token = (uchar *) strdup((char *) loadModConf->token);
|
|
|
ee3a35 |
if(pData->tokenFile == NULL && loadModConf->tokenFile)
|
|
|
ee3a35 |
@@ -1018,6 +1167,8 @@ CODESTARTnewActInst
|
|
|
ee3a35 |
CODE_STD_FINALIZERnewActInst
|
|
|
ee3a35 |
if(pvals != NULL)
|
|
|
ee3a35 |
cnfparamvalsDestruct(pvals, &actpblk);
|
|
|
ee3a35 |
+ if(fp)
|
|
|
ee3a35 |
+ fclose(fp);
|
|
|
ee3a35 |
free(rxstr);
|
|
|
ee3a35 |
free(srcMetadataPath);
|
|
|
ee3a35 |
ENDnewActInst
|
|
|
ee3a35 |
@@ -1061,6 +1212,8 @@ CODESTARTfreeCnf
|
|
|
ee3a35 |
free(pModConf->srcMetadataPath);
|
|
|
ee3a35 |
free(pModConf->dstMetadataPath);
|
|
|
ee3a35 |
free(pModConf->caCertFile);
|
|
|
ee3a35 |
+ free(pModConf->myCertFile);
|
|
|
ee3a35 |
+ free(pModConf->myPrivKeyFile);
|
|
|
ee3a35 |
free(pModConf->token);
|
|
|
ee3a35 |
free(pModConf->tokenFile);
|
|
|
ee3a35 |
free(pModConf->de_dot_separator);
|
|
|
ee3a35 |
@@ -1069,8 +1222,11 @@ CODESTARTfreeCnf
|
|
|
ee3a35 |
free(pModConf->contRules);
|
|
|
ee3a35 |
free(pModConf->contRulebase);
|
|
|
ee3a35 |
free_annotationmatch(&pModConf->annotation_match);
|
|
|
ee3a35 |
- for(i = 0; caches[i] != NULL; i++)
|
|
|
ee3a35 |
+ for(i = 0; caches[i] != NULL; i++) {
|
|
|
ee3a35 |
+ dbgprintf("mmkubernetes: freeing cache [%d] mdht [%p] nsht [%p]\n",
|
|
|
ee3a35 |
+ i, caches[i]->mdHt, caches[i]->nsHt);
|
|
|
ee3a35 |
cacheFree(caches[i]);
|
|
|
ee3a35 |
+ }
|
|
|
ee3a35 |
free(caches);
|
|
|
ee3a35 |
ENDfreeCnf
|
|
|
ee3a35 |
|
|
|
ee3a35 |
@@ -1082,6 +1238,8 @@ CODESTARTdbgPrintInstInfo
|
|
|
ee3a35 |
dbgprintf("\tsrcMetadataPath='%s'\n", pData->srcMetadataDescr->name);
|
|
|
ee3a35 |
dbgprintf("\tdstMetadataPath='%s'\n", pData->dstMetadataPath);
|
|
|
ee3a35 |
dbgprintf("\ttls.cacert='%s'\n", pData->caCertFile);
|
|
|
ee3a35 |
+ dbgprintf("\ttls.mycert='%s'\n", pData->myCertFile);
|
|
|
ee3a35 |
+ dbgprintf("\ttls.myprivkey='%s'\n", pData->myPrivKeyFile);
|
|
|
ee3a35 |
dbgprintf("\tallowUnsignedCerts='%d'\n", pData->allowUnsignedCerts);
|
|
|
ee3a35 |
dbgprintf("\ttoken='%s'\n", pData->token);
|
|
|
ee3a35 |
dbgprintf("\ttokenFile='%s'\n", pData->tokenFile);
|
|
|
ee3a35 |
@@ -1093,6 +1251,7 @@ CODESTARTdbgPrintInstInfo
|
|
|
ee3a35 |
dbgprintf("\tfilenamerules='%s'\n", pData->fnRules);
|
|
|
ee3a35 |
dbgprintf("\tcontainerrules='%s'\n", pData->contRules);
|
|
|
ee3a35 |
#endif
|
|
|
ee3a35 |
+ dbgprintf("\tbusyretryinterval='%d'\n", pData->busyRetryInterval);
|
|
|
ee3a35 |
ENDdbgPrintInstInfo
|
|
|
ee3a35 |
|
|
|
ee3a35 |
|
|
|
ee3a35 |
@@ -1206,6 +1365,24 @@ queryKB(wrkrInstanceData_t *pWrkrData, char *url, struct json_object **rply)
|
|
|
ee3a35 |
struct json_object *jo;
|
|
|
ee3a35 |
long resp_code = 400;
|
|
|
ee3a35 |
|
|
|
ee3a35 |
+ if (pWrkrData->pData->cache->lastBusyTime) {
|
|
|
ee3a35 |
+ time_t now;
|
|
|
ee3a35 |
+ datetime.GetTime(&now;;
|
|
|
ee3a35 |
+ now -= pWrkrData->pData->cache->lastBusyTime;
|
|
|
ee3a35 |
+ if (now < pWrkrData->pData->busyRetryInterval) {
|
|
|
ee3a35 |
+ LogMsg(0, RS_RET_RETRY, LOG_DEBUG,
|
|
|
ee3a35 |
+ "mmkubernetes: Waited [%ld] of [%d] seconds for the requested url [%s]\n",
|
|
|
ee3a35 |
+ now, pWrkrData->pData->busyRetryInterval, url);
|
|
|
ee3a35 |
+ ABORT_FINALIZE(RS_RET_RETRY);
|
|
|
ee3a35 |
+ } else {
|
|
|
ee3a35 |
+ LogMsg(0, RS_RET_OK, LOG_DEBUG,
|
|
|
ee3a35 |
+ "mmkubernetes: Cleared busy status after [%d] seconds - "
|
|
|
ee3a35 |
+ "will retry the requested url [%s]\n",
|
|
|
ee3a35 |
+ pWrkrData->pData->busyRetryInterval, url);
|
|
|
ee3a35 |
+ pWrkrData->pData->cache->lastBusyTime = 0;
|
|
|
ee3a35 |
+ }
|
|
|
ee3a35 |
+ }
|
|
|
ee3a35 |
+
|
|
|
ee3a35 |
/* query kubernetes for pod info */
|
|
|
ee3a35 |
ccode = curl_easy_setopt(pWrkrData->curlCtx, CURLOPT_URL, url);
|
|
|
ee3a35 |
if(ccode != CURLE_OK)
|
|
|
ee3a35 |
@@ -1411,17 +1411,23 @@ queryKB(wrkrInstanceData_t *pWrkrData, char *url, struct json_object **rply)
|
|
|
ee3a35 |
ABORT_FINALIZE(RS_RET_ERR);
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
if(resp_code == 404) {
|
|
|
ee3a35 |
- errmsg.LogMsg(0, RS_RET_ERR, LOG_ERR,
|
|
|
ee3a35 |
+ errmsg.LogMsg(0, RS_RET_NOT_FOUND, LOG_INFO,
|
|
|
ee3a35 |
"mmkubernetes: Not Found: the resource does not exist at url [%s]\n",
|
|
|
ee3a35 |
url);
|
|
|
ee3a35 |
- ABORT_FINALIZE(RS_RET_ERR);
|
|
|
ee3a35 |
+ ABORT_FINALIZE(RS_RET_NOT_FOUND);
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
if(resp_code == 429) {
|
|
|
ee3a35 |
- errmsg.LogMsg(0, RS_RET_ERR, LOG_ERR,
|
|
|
ee3a35 |
+ if (pWrkrData->pData->busyRetryInterval) {
|
|
|
ee3a35 |
+ time_t now;
|
|
|
ee3a35 |
+ datetime.GetTime(&now;;
|
|
|
ee3a35 |
+ pWrkrData->pData->cache->lastBusyTime = now;
|
|
|
ee3a35 |
+ }
|
|
|
ee3a35 |
+
|
|
|
ee3a35 |
+ errmsg.LogMsg(0, RS_RET_RETRY, LOG_INFO,
|
|
|
ee3a35 |
"mmkubernetes: Too Many Requests: the server is too heavily loaded "
|
|
|
ee3a35 |
"to provide the data for the requested url [%s]\n",
|
|
|
ee3a35 |
url);
|
|
|
ee3a35 |
- ABORT_FINALIZE(RS_RET_ERR);
|
|
|
ee3a35 |
+ ABORT_FINALIZE(RS_RET_RETRY);
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
if(resp_code != 200) {
|
|
|
ee3a35 |
errmsg.LogMsg(0, RS_RET_ERR, LOG_ERR,
|
|
|
ee3a35 |
@@ -1299,12 +1482,14 @@ BEGINdoAction
|
|
|
ee3a35 |
char *mdKey = NULL;
|
|
|
ee3a35 |
struct json_object *jMetadata = NULL, *jMetadataCopy = NULL, *jMsgMeta = NULL,
|
|
|
ee3a35 |
*jo = NULL;
|
|
|
ee3a35 |
- int add_ns_metadata = 0;
|
|
|
ee3a35 |
+ int add_pod_metadata = 1;
|
|
|
ee3a35 |
CODESTARTdoAction
|
|
|
ee3a35 |
CHKiRet_Hdlr(extractMsgMetadata(pMsg, pWrkrData->pData, &jMsgMeta)) {
|
|
|
ee3a35 |
ABORT_FINALIZE((iRet == RS_RET_NOT_FOUND) ? RS_RET_OK : iRet);
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
|
|
|
ee3a35 |
+ STATSCOUNTER_INC(pWrkrData->k8sRecordSeen, pWrkrData->mutK8sRecordSeen);
|
|
|
ee3a35 |
+
|
|
|
ee3a35 |
if (fjson_object_object_get_ex(jMsgMeta, "pod_name", &jo))
|
|
|
ee3a35 |
podName = json_object_get_string(jo);
|
|
|
ee3a35 |
if (fjson_object_object_get_ex(jMsgMeta, "namespace_name", &jo))
|
|
|
ee3a35 |
@@ -1347,28 +1532,49 @@ CODESTARTdoAction
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
iRet = queryKB(pWrkrData, url, &jReply);
|
|
|
ee3a35 |
free(url);
|
|
|
ee3a35 |
- /* todo: implement support for the .orphaned namespace */
|
|
|
ee3a35 |
- if (iRet != RS_RET_OK) {
|
|
|
ee3a35 |
+ if (iRet == RS_RET_NOT_FOUND) {
|
|
|
ee3a35 |
+ /* negative cache namespace - make a dummy empty namespace metadata object */
|
|
|
ee3a35 |
+ jNsMeta = json_object_new_object();
|
|
|
ee3a35 |
+ STATSCOUNTER_INC(pWrkrData->namespaceMetadataNotFound,
|
|
|
ee3a35 |
+ pWrkrData->mutNamespaceMetadataNotFound);
|
|
|
ee3a35 |
+ } else if (iRet == RS_RET_RETRY) {
|
|
|
ee3a35 |
+ /* server is busy - retry or error */
|
|
|
ee3a35 |
+ STATSCOUNTER_INC(pWrkrData->namespaceMetadataBusy,
|
|
|
ee3a35 |
+ pWrkrData->mutNamespaceMetadataBusy);
|
|
|
ee3a35 |
+ if (0 == pWrkrData->pData->busyRetryInterval) {
|
|
|
ee3a35 |
+ pthread_mutex_unlock(pWrkrData->pData->cache->cacheMtx);
|
|
|
ee3a35 |
+ ABORT_FINALIZE(RS_RET_ERR);
|
|
|
ee3a35 |
+ }
|
|
|
ee3a35 |
+ add_pod_metadata = 0; /* don't cache pod metadata either - retry both */
|
|
|
ee3a35 |
+ } else if (iRet != RS_RET_OK) {
|
|
|
ee3a35 |
+ /* hard error - something the admin needs to fix e.g. network, config, auth */
|
|
|
ee3a35 |
json_object_put(jReply);
|
|
|
ee3a35 |
jReply = NULL;
|
|
|
ee3a35 |
+ STATSCOUNTER_INC(pWrkrData->namespaceMetadataError,
|
|
|
ee3a35 |
+ pWrkrData->mutNamespaceMetadataError);
|
|
|
ee3a35 |
pthread_mutex_unlock(pWrkrData->pData->cache->cacheMtx);
|
|
|
ee3a35 |
FINALIZE;
|
|
|
ee3a35 |
- }
|
|
|
ee3a35 |
-
|
|
|
ee3a35 |
- if(fjson_object_object_get_ex(jReply, "metadata", &jNsMeta)) {
|
|
|
ee3a35 |
+ } else if (fjson_object_object_get_ex(jReply, "metadata", &jNsMeta)) {
|
|
|
ee3a35 |
jNsMeta = json_object_get(jNsMeta);
|
|
|
ee3a35 |
parse_labels_annotations(jNsMeta, &pWrkrData->pData->annotation_match,
|
|
|
ee3a35 |
pWrkrData->pData->de_dot,
|
|
|
ee3a35 |
(const char *)pWrkrData->pData->de_dot_separator,
|
|
|
ee3a35 |
pWrkrData->pData->de_dot_separator_len);
|
|
|
ee3a35 |
- add_ns_metadata = 1;
|
|
|
ee3a35 |
+ STATSCOUNTER_INC(pWrkrData->namespaceMetadataSuccess,
|
|
|
ee3a35 |
+ pWrkrData->mutNamespaceMetadataSuccess);
|
|
|
ee3a35 |
} else {
|
|
|
ee3a35 |
/* namespace with no metadata??? */
|
|
|
ee3a35 |
errmsg.LogMsg(0, RS_RET_ERR, LOG_INFO,
|
|
|
ee3a35 |
"mmkubernetes: namespace [%s] has no metadata!\n", ns);
|
|
|
ee3a35 |
- jNsMeta = NULL;
|
|
|
ee3a35 |
+ /* negative cache namespace - make a dummy empty namespace metadata object */
|
|
|
ee3a35 |
+ jNsMeta = json_object_new_object();
|
|
|
ee3a35 |
+ STATSCOUNTER_INC(pWrkrData->namespaceMetadataSuccess,
|
|
|
ee3a35 |
+ pWrkrData->mutNamespaceMetadataSuccess);
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
|
|
|
ee3a35 |
+ if(jNsMeta) {
|
|
|
ee3a35 |
+ hashtable_insert(pWrkrData->pData->cache->nsHt, strdup(ns), jNsMeta);
|
|
|
ee3a35 |
+ }
|
|
|
ee3a35 |
json_object_put(jReply);
|
|
|
ee3a35 |
jReply = NULL;
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
@@ -1381,14 +1587,28 @@ CODESTARTdoAction
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
iRet = queryKB(pWrkrData, url, &jReply);
|
|
|
ee3a35 |
free(url);
|
|
|
ee3a35 |
- if(iRet != RS_RET_OK) {
|
|
|
ee3a35 |
- if(jNsMeta && add_ns_metadata) {
|
|
|
ee3a35 |
- hashtable_insert(pWrkrData->pData->cache->nsHt, strdup(ns), jNsMeta);
|
|
|
ee3a35 |
+ if (iRet == RS_RET_NOT_FOUND) {
|
|
|
ee3a35 |
+ /* negative cache pod - make a dummy empty pod metadata object */
|
|
|
ee3a35 |
+ iRet = RS_RET_OK;
|
|
|
ee3a35 |
+ STATSCOUNTER_INC(pWrkrData->podMetadataNotFound, pWrkrData->mutPodMetadataNotFound);
|
|
|
ee3a35 |
+ } else if (iRet == RS_RET_RETRY) {
|
|
|
ee3a35 |
+ /* server is busy - retry or error */
|
|
|
ee3a35 |
+ STATSCOUNTER_INC(pWrkrData->podMetadataBusy, pWrkrData->mutPodMetadataBusy);
|
|
|
ee3a35 |
+ if (0 == pWrkrData->pData->busyRetryInterval) {
|
|
|
ee3a35 |
+ pthread_mutex_unlock(pWrkrData->pData->cache->cacheMtx);
|
|
|
ee3a35 |
+ ABORT_FINALIZE(RS_RET_ERR);
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
+ add_pod_metadata = 0; /* do not cache so that we can retry */
|
|
|
ee3a35 |
+ iRet = RS_RET_OK;
|
|
|
ee3a35 |
+ } else if(iRet != RS_RET_OK) {
|
|
|
ee3a35 |
+ /* hard error - something the admin needs to fix e.g. network, config, auth */
|
|
|
ee3a35 |
json_object_put(jReply);
|
|
|
ee3a35 |
jReply = NULL;
|
|
|
ee3a35 |
+ STATSCOUNTER_INC(pWrkrData->podMetadataError, pWrkrData->mutPodMetadataError);
|
|
|
ee3a35 |
pthread_mutex_unlock(pWrkrData->pData->cache->cacheMtx);
|
|
|
ee3a35 |
FINALIZE;
|
|
|
ee3a35 |
+ } else {
|
|
|
ee3a35 |
+ STATSCOUNTER_INC(pWrkrData->podMetadataSuccess, pWrkrData->mutPodMetadataSuccess);
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
|
|
|
ee3a35 |
jo = json_object_new_object();
|
|
|
ee3a35 |
@@ -1435,11 +1655,9 @@ CODESTARTdoAction
|
|
|
ee3a35 |
json_object_object_add(jo, "container_id", json_object_get(jo2));
|
|
|
ee3a35 |
json_object_object_add(jMetadata, "docker", jo);
|
|
|
ee3a35 |
|
|
|
ee3a35 |
- hashtable_insert(pWrkrData->pData->cache->mdHt, mdKey, jMetadata);
|
|
|
ee3a35 |
- mdKey = NULL;
|
|
|
ee3a35 |
- if(jNsMeta && add_ns_metadata) {
|
|
|
ee3a35 |
- hashtable_insert(pWrkrData->pData->cache->nsHt, strdup(ns), jNsMeta);
|
|
|
ee3a35 |
- ns = NULL;
|
|
|
ee3a35 |
+ if (add_pod_metadata) {
|
|
|
ee3a35 |
+ hashtable_insert(pWrkrData->pData->cache->mdHt, mdKey, jMetadata);
|
|
|
ee3a35 |
+ mdKey = NULL;
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
}
|
|
|
ee3a35 |
|
|
|
ee3a35 |
@@ -1450,6 +1668,11 @@ CODESTARTdoAction
|
|
|
ee3a35 |
* outside of the cache lock
|
|
|
ee3a35 |
*/
|
|
|
ee3a35 |
jMetadataCopy = json_tokener_parse(json_object_get_string(jMetadata));
|
|
|
ee3a35 |
+ if (!add_pod_metadata) {
|
|
|
ee3a35 |
+ /* jMetadata object was created from scratch and not cached */
|
|
|
ee3a35 |
+ json_object_put(jMetadata);
|
|
|
ee3a35 |
+ jMetadata = NULL;
|
|
|
ee3a35 |
+ }
|
|
|
ee3a35 |
pthread_mutex_unlock(pWrkrData->pData->cache->cacheMtx);
|
|
|
ee3a35 |
/* the +1 is there to skip the leading '$' */
|
|
|
ee3a35 |
msgAddJSON(pMsg, (uchar *) pWrkrData->pData->dstMetadataPath + 1, jMetadataCopy, 0, 0);
|
|
|
ee3a35 |
@@ -1691,6 +1693,8 @@ BEGINmodExit
|
|
|
ee3a35 |
|
|
|
ee3a35 |
objRelease(regexp, LM_REGEXP_FILENAME);
|
|
|
ee3a35 |
objRelease(errmsg, CORE_COMPONENT);
|
|
|
ee3a35 |
+ objRelease(datetime, CORE_COMPONENT);
|
|
|
ee3a35 |
+ objRelease(statsobj, CORE_COMPONENT);
|
|
|
ee3a35 |
ENDmodExit
|
|
|
ee3a35 |
|
|
|
ee3a35 |
|
|
|
ee3a35 |
@@ -1705,6 +1711,8 @@ CODEmodInit_QueryRegCFSLineHdlr
|
|
|
ee3a35 |
DBGPRINTF("mmkubernetes: module compiled with rsyslog version %s.\n", VERSION);
|
|
|
ee3a35 |
CHKiRet(objUse(errmsg, CORE_COMPONENT));
|
|
|
ee3a35 |
CHKiRet(objUse(regexp, LM_REGEXP_FILENAME));
|
|
|
ee3a35 |
+ CHKiRet(objUse(datetime, CORE_COMPONENT));
|
|
|
ee3a35 |
+ CHKiRet(objUse(statsobj, CORE_COMPONENT));
|
|
|
ee3a35 |
|
|
|
ee3a35 |
/* CURL_GLOBAL_ALL initializes more than is needed but the
|
|
|
ee3a35 |
* libcurl documentation discourages use of other values
|
|
|
ee3a35 |
--- a/contrib/mmkubernetes/mmkubernetes.c
|
|
|
ee3a35 |
+++ b/contrib/mmkubernetes/mmkubernetes.c
|
|
|
ee3a35 |
@@ -560,7 +560,6 @@
|
|
|
ee3a35 |
loadModConf->caCertFile = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
|
ee3a35 |
fp = fopen((const char*)loadModConf->caCertFile, "r");
|
|
|
ee3a35 |
if(fp == NULL) {
|
|
|
ee3a35 |
- char errStr[1024];
|
|
|
ee3a35 |
rs_strerror_r(errno, errStr, sizeof(errStr));
|
|
|
ee3a35 |
iRet = RS_RET_NO_FILE_ACCESS;
|
|
|
ee3a35 |
errmsg.LogError(0, iRet,
|
|
|
ee3a35 |
@@ -608,7 +607,6 @@
|
|
|
ee3a35 |
loadModConf->tokenFile = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
|
ee3a35 |
fp = fopen((const char*)loadModConf->tokenFile, "r");
|
|
|
ee3a35 |
if(fp == NULL) {
|
|
|
ee3a35 |
- char errStr[1024];
|
|
|
ee3a35 |
rs_strerror_r(errno, errStr, sizeof(errStr));
|
|
|
ee3a35 |
iRet = RS_RET_NO_FILE_ACCESS;
|
|
|
ee3a35 |
errmsg.LogError(0, iRet,
|
|
|
ee3a35 |
@@ -638,7 +636,6 @@
|
|
|
ee3a35 |
loadModConf->fnRulebase = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
|
ee3a35 |
fp = fopen((const char*)loadModConf->fnRulebase, "r");
|
|
|
ee3a35 |
if(fp == NULL) {
|
|
|
ee3a35 |
- char errStr[1024];
|
|
|
ee3a35 |
rs_strerror_r(errno, errStr, sizeof(errStr));
|
|
|
ee3a35 |
iRet = RS_RET_NO_FILE_ACCESS;
|
|
|
ee3a35 |
errmsg.LogError(0, iRet,
|
|
|
ee3a35 |
@@ -659,7 +656,6 @@
|
|
|
ee3a35 |
loadModConf->contRulebase = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
|
ee3a35 |
fp = fopen((const char*)loadModConf->contRulebase, "r");
|
|
|
ee3a35 |
if(fp == NULL) {
|
|
|
ee3a35 |
- char errStr[1024];
|
|
|
ee3a35 |
rs_strerror_r(errno, errStr, sizeof(errStr));
|
|
|
ee3a35 |
iRet = RS_RET_NO_FILE_ACCESS;
|
|
|
ee3a35 |
errmsg.LogError(0, iRet,
|
|
|
ee3a35 |
@@ -975,7 +971,6 @@
|
|
|
ee3a35 |
pData->caCertFile = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
|
ee3a35 |
fp = fopen((const char*)pData->caCertFile, "r");
|
|
|
ee3a35 |
if(fp == NULL) {
|
|
|
ee3a35 |
- char errStr[1024];
|
|
|
ee3a35 |
rs_strerror_r(errno, errStr, sizeof(errStr));
|
|
|
ee3a35 |
iRet = RS_RET_NO_FILE_ACCESS;
|
|
|
ee3a35 |
errmsg.LogError(0, iRet,
|
|
|
ee3a35 |
@@ -1022,7 +1017,6 @@
|
|
|
ee3a35 |
pData->tokenFile = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
|
ee3a35 |
fp = fopen((const char*)pData->tokenFile, "r");
|
|
|
ee3a35 |
if(fp == NULL) {
|
|
|
ee3a35 |
- char errStr[1024];
|
|
|
ee3a35 |
rs_strerror_r(errno, errStr, sizeof(errStr));
|
|
|
ee3a35 |
iRet = RS_RET_NO_FILE_ACCESS;
|
|
|
ee3a35 |
errmsg.LogError(0, iRet,
|
|
|
ee3a35 |
@@ -1052,7 +1046,6 @@
|
|
|
ee3a35 |
pData->fnRulebase = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
|
ee3a35 |
fp = fopen((const char*)pData->fnRulebase, "r");
|
|
|
ee3a35 |
if(fp == NULL) {
|
|
|
ee3a35 |
- char errStr[1024];
|
|
|
ee3a35 |
rs_strerror_r(errno, errStr, sizeof(errStr));
|
|
|
ee3a35 |
iRet = RS_RET_NO_FILE_ACCESS;
|
|
|
ee3a35 |
errmsg.LogError(0, iRet,
|
|
|
ee3a35 |
@@ -1073,7 +1066,6 @@
|
|
|
ee3a35 |
pData->contRulebase = (uchar *) es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
|
ee3a35 |
fp = fopen((const char*)pData->contRulebase, "r");
|
|
|
ee3a35 |
if(fp == NULL) {
|
|
|
ee3a35 |
- char errStr[1024];
|
|
|
ee3a35 |
rs_strerror_r(errno, errStr, sizeof(errStr));
|
|
|
ee3a35 |
iRet = RS_RET_NO_FILE_ACCESS;
|
|
|
ee3a35 |
errmsg.LogError(0, iRet,
|