fix: segfault in ingress, persistentvolumeclaim, statefulset in kube_inventory (#9585)
This commit is contained in:
parent
3e1ebdb4c7
commit
a7582fb893
|
|
@ -39,11 +39,17 @@ func (ki *KubernetesInventory) gatherIngress(i netv1.Ingress, acc telegraf.Accum
|
||||||
tags["ip"] = ingress.IP
|
tags["ip"] = ingress.IP
|
||||||
|
|
||||||
for _, rule := range i.Spec.Rules {
|
for _, rule := range i.Spec.Rules {
|
||||||
|
if rule.IngressRuleValue.HTTP == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
for _, path := range rule.IngressRuleValue.HTTP.Paths {
|
for _, path := range rule.IngressRuleValue.HTTP.Paths {
|
||||||
fields["backend_service_port"] = path.Backend.Service.Port.Number
|
if path.Backend.Service != nil {
|
||||||
|
tags["backend_service_name"] = path.Backend.Service.Name
|
||||||
|
fields["backend_service_port"] = path.Backend.Service.Port.Number
|
||||||
|
}
|
||||||
|
|
||||||
fields["tls"] = i.Spec.TLS != nil
|
fields["tls"] = i.Spec.TLS != nil
|
||||||
|
|
||||||
tags["backend_service_name"] = path.Backend.Service.Name
|
|
||||||
tags["path"] = path.Path
|
tags["path"] = path.Path
|
||||||
tags["host"] = rule.Host
|
tags["host"] = rule.Host
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,114 @@ func TestIngress(t *testing.T) {
|
||||||
},
|
},
|
||||||
hasError: false,
|
hasError: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "no HTTPIngressRuleValue",
|
||||||
|
handler: &mockHandler{
|
||||||
|
responseMap: map[string]interface{}{
|
||||||
|
"/ingress/": netv1.IngressList{
|
||||||
|
Items: []netv1.Ingress{
|
||||||
|
{
|
||||||
|
Status: netv1.IngressStatus{
|
||||||
|
LoadBalancer: v1.LoadBalancerStatus{
|
||||||
|
Ingress: []v1.LoadBalancerIngress{
|
||||||
|
{
|
||||||
|
Hostname: "chron-1",
|
||||||
|
IP: "1.0.0.127",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spec: netv1.IngressSpec{
|
||||||
|
Rules: []netv1.IngressRule{
|
||||||
|
{
|
||||||
|
Host: "ui.internal",
|
||||||
|
IngressRuleValue: netv1.IngressRuleValue{
|
||||||
|
HTTP: nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Generation: 12,
|
||||||
|
Namespace: "ns1",
|
||||||
|
Name: "ui-lb",
|
||||||
|
CreationTimestamp: metav1.Time{Time: now},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
hasError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no IngressServiceBackend",
|
||||||
|
handler: &mockHandler{
|
||||||
|
responseMap: map[string]interface{}{
|
||||||
|
"/ingress/": netv1.IngressList{
|
||||||
|
Items: []netv1.Ingress{
|
||||||
|
{
|
||||||
|
Status: netv1.IngressStatus{
|
||||||
|
LoadBalancer: v1.LoadBalancerStatus{
|
||||||
|
Ingress: []v1.LoadBalancerIngress{
|
||||||
|
{
|
||||||
|
Hostname: "chron-1",
|
||||||
|
IP: "1.0.0.127",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spec: netv1.IngressSpec{
|
||||||
|
Rules: []netv1.IngressRule{
|
||||||
|
{
|
||||||
|
Host: "ui.internal",
|
||||||
|
IngressRuleValue: netv1.IngressRuleValue{
|
||||||
|
HTTP: &netv1.HTTPIngressRuleValue{
|
||||||
|
Paths: []netv1.HTTPIngressPath{
|
||||||
|
{
|
||||||
|
Path: "/",
|
||||||
|
Backend: netv1.IngressBackend{
|
||||||
|
Service: nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Generation: 12,
|
||||||
|
Namespace: "ns1",
|
||||||
|
Name: "ui-lb",
|
||||||
|
CreationTimestamp: metav1.Time{Time: now},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
output: []telegraf.Metric{
|
||||||
|
testutil.MustMetric(
|
||||||
|
"kubernetes_ingress",
|
||||||
|
map[string]string{
|
||||||
|
"ingress_name": "ui-lb",
|
||||||
|
"namespace": "ns1",
|
||||||
|
"ip": "1.0.0.127",
|
||||||
|
"hostname": "chron-1",
|
||||||
|
"host": "ui.internal",
|
||||||
|
"path": "/",
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"tls": false,
|
||||||
|
"generation": int64(12),
|
||||||
|
"created": now.UnixNano(),
|
||||||
|
},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
hasError: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range tests {
|
for _, v := range tests {
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,12 @@ func (ki *KubernetesInventory) gatherPersistentVolumeClaim(pvc corev1.Persistent
|
||||||
"phase_type": phaseType,
|
"phase_type": phaseType,
|
||||||
}
|
}
|
||||||
tags := map[string]string{
|
tags := map[string]string{
|
||||||
"pvc_name": pvc.Name,
|
"pvc_name": pvc.Name,
|
||||||
"namespace": pvc.Namespace,
|
"namespace": pvc.Namespace,
|
||||||
"phase": string(pvc.Status.Phase),
|
"phase": string(pvc.Status.Phase),
|
||||||
"storageclass": *pvc.Spec.StorageClassName,
|
}
|
||||||
|
if pvc.Spec.StorageClassName != nil {
|
||||||
|
tags["storageclass"] = *pvc.Spec.StorageClassName
|
||||||
}
|
}
|
||||||
if pvc.Spec.Selector != nil {
|
if pvc.Spec.Selector != nil {
|
||||||
for key, val := range pvc.Spec.Selector.MatchLabels {
|
for key, val := range pvc.Spec.Selector.MatchLabels {
|
||||||
|
|
|
||||||
|
|
@ -134,6 +134,58 @@ func TestPersistentVolumeClaim(t *testing.T) {
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "no storage class name",
|
||||||
|
handler: &mockHandler{
|
||||||
|
responseMap: map[string]interface{}{
|
||||||
|
"/persistentvolumeclaims/": &corev1.PersistentVolumeClaimList{
|
||||||
|
Items: []corev1.PersistentVolumeClaim{
|
||||||
|
{
|
||||||
|
Status: corev1.PersistentVolumeClaimStatus{
|
||||||
|
Phase: "bound",
|
||||||
|
},
|
||||||
|
Spec: corev1.PersistentVolumeClaimSpec{
|
||||||
|
VolumeName: "pvc-dc870fd6-1e08-11e8-b226-02aa4bc06eb8",
|
||||||
|
StorageClassName: nil,
|
||||||
|
Selector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{
|
||||||
|
"select1": "s1",
|
||||||
|
"select2": "s2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Namespace: "ns1",
|
||||||
|
Name: "pc1",
|
||||||
|
Labels: map[string]string{
|
||||||
|
"lab1": "v1",
|
||||||
|
"lab2": "v2",
|
||||||
|
},
|
||||||
|
CreationTimestamp: metav1.Time{Time: now},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
output: []telegraf.Metric{
|
||||||
|
testutil.MustMetric(
|
||||||
|
"kubernetes_persistentvolumeclaim",
|
||||||
|
map[string]string{
|
||||||
|
"pvc_name": "pc1",
|
||||||
|
"namespace": "ns1",
|
||||||
|
"phase": "bound",
|
||||||
|
"selector_select1": "s1",
|
||||||
|
"selector_select2": "s2",
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"phase_type": 0,
|
||||||
|
},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
hasError: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range tests {
|
for _, v := range tests {
|
||||||
|
|
|
||||||
|
|
@ -28,16 +28,20 @@ func (ki *KubernetesInventory) gatherStatefulSet(s v1.StatefulSet, acc telegraf.
|
||||||
"replicas_current": status.CurrentReplicas,
|
"replicas_current": status.CurrentReplicas,
|
||||||
"replicas_ready": status.ReadyReplicas,
|
"replicas_ready": status.ReadyReplicas,
|
||||||
"replicas_updated": status.UpdatedReplicas,
|
"replicas_updated": status.UpdatedReplicas,
|
||||||
"spec_replicas": *s.Spec.Replicas,
|
|
||||||
"observed_generation": s.Status.ObservedGeneration,
|
"observed_generation": s.Status.ObservedGeneration,
|
||||||
}
|
}
|
||||||
|
if s.Spec.Replicas != nil {
|
||||||
|
fields["spec_replicas"] = *s.Spec.Replicas
|
||||||
|
}
|
||||||
tags := map[string]string{
|
tags := map[string]string{
|
||||||
"statefulset_name": s.Name,
|
"statefulset_name": s.Name,
|
||||||
"namespace": s.Namespace,
|
"namespace": s.Namespace,
|
||||||
}
|
}
|
||||||
for key, val := range s.Spec.Selector.MatchLabels {
|
if s.Spec.Selector != nil {
|
||||||
if ki.selectorFilter.Match(key) {
|
for key, val := range s.Spec.Selector.MatchLabels {
|
||||||
tags["selector_"+key] = val
|
if ki.selectorFilter.Match(key) {
|
||||||
|
tags["selector_"+key] = val
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,114 @@ func TestStatefulSet(t *testing.T) {
|
||||||
},
|
},
|
||||||
hasError: false,
|
hasError: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "no label selector",
|
||||||
|
handler: &mockHandler{
|
||||||
|
responseMap: map[string]interface{}{
|
||||||
|
"/statefulsets/": &v1.StatefulSetList{
|
||||||
|
Items: []v1.StatefulSet{
|
||||||
|
{
|
||||||
|
Status: v1.StatefulSetStatus{
|
||||||
|
Replicas: 2,
|
||||||
|
CurrentReplicas: 4,
|
||||||
|
ReadyReplicas: 1,
|
||||||
|
UpdatedReplicas: 3,
|
||||||
|
ObservedGeneration: 119,
|
||||||
|
},
|
||||||
|
Spec: v1.StatefulSetSpec{
|
||||||
|
Replicas: toInt32Ptr(3),
|
||||||
|
Selector: nil,
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Generation: 332,
|
||||||
|
Namespace: "ns1",
|
||||||
|
Name: "sts1",
|
||||||
|
CreationTimestamp: metav1.Time{Time: now},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
output: []telegraf.Metric{
|
||||||
|
testutil.MustMetric(
|
||||||
|
"kubernetes_statefulset",
|
||||||
|
map[string]string{
|
||||||
|
"namespace": "ns1",
|
||||||
|
"statefulset_name": "sts1",
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"generation": int64(332),
|
||||||
|
"observed_generation": int64(119),
|
||||||
|
"created": now.UnixNano(),
|
||||||
|
"spec_replicas": int32(3),
|
||||||
|
"replicas": int32(2),
|
||||||
|
"replicas_current": int32(4),
|
||||||
|
"replicas_ready": int32(1),
|
||||||
|
"replicas_updated": int32(3),
|
||||||
|
},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
hasError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no desired number of replicas",
|
||||||
|
handler: &mockHandler{
|
||||||
|
responseMap: map[string]interface{}{
|
||||||
|
"/statefulsets/": &v1.StatefulSetList{
|
||||||
|
Items: []v1.StatefulSet{
|
||||||
|
{
|
||||||
|
Status: v1.StatefulSetStatus{
|
||||||
|
Replicas: 2,
|
||||||
|
CurrentReplicas: 4,
|
||||||
|
ReadyReplicas: 1,
|
||||||
|
UpdatedReplicas: 3,
|
||||||
|
ObservedGeneration: 119,
|
||||||
|
},
|
||||||
|
Spec: v1.StatefulSetSpec{
|
||||||
|
Replicas: nil,
|
||||||
|
Selector: &metav1.LabelSelector{
|
||||||
|
MatchLabels: map[string]string{
|
||||||
|
"select1": "s1",
|
||||||
|
"select2": "s2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Generation: 332,
|
||||||
|
Namespace: "ns1",
|
||||||
|
Name: "sts1",
|
||||||
|
CreationTimestamp: metav1.Time{Time: now},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
output: []telegraf.Metric{
|
||||||
|
testutil.MustMetric(
|
||||||
|
"kubernetes_statefulset",
|
||||||
|
map[string]string{
|
||||||
|
"namespace": "ns1",
|
||||||
|
"statefulset_name": "sts1",
|
||||||
|
"selector_select1": "s1",
|
||||||
|
"selector_select2": "s2",
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"generation": int64(332),
|
||||||
|
"observed_generation": int64(119),
|
||||||
|
"created": now.UnixNano(),
|
||||||
|
"replicas": int32(2),
|
||||||
|
"replicas_current": int32(4),
|
||||||
|
"replicas_ready": int32(1),
|
||||||
|
"replicas_updated": int32(3),
|
||||||
|
},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
hasError: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range tests {
|
for _, v := range tests {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue