forked from DataDog/datadog-agent
/
host_tags.go
152 lines (126 loc) · 4.04 KB
/
host_tags.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package host
import (
"context"
"fmt"
"strings"
"time"
"github.com/StackVista/stackstate-agent/pkg/config"
"github.com/StackVista/stackstate-agent/pkg/util"
"github.com/StackVista/stackstate-agent/pkg/util/cache"
"github.com/StackVista/stackstate-agent/pkg/util/cloudproviders/gce"
"github.com/StackVista/stackstate-agent/pkg/util/docker"
"github.com/StackVista/stackstate-agent/pkg/util/ec2"
"github.com/StackVista/stackstate-agent/pkg/util/kubernetes/clustername"
k8s "github.com/StackVista/stackstate-agent/pkg/util/kubernetes/hostinfo"
"github.com/StackVista/stackstate-agent/pkg/util/log"
)
var retrySleepTime = time.Second
type providerDef struct {
retries int
getTags func(context.Context) ([]string, error)
retrieved bool
}
// this is a "low-tech" version of tagger/utils/taglist.go
// but host tags are handled separately here for now
func appendAndSplitTags(target []string, tags []string, splits map[string]string) []string {
if len(splits) == 0 {
return append(target, tags...)
}
for _, tag := range tags {
tagParts := strings.SplitN(tag, ":", 2)
if len(tagParts) != 2 {
target = append(target, tag)
continue
}
name := tagParts[0]
value := tagParts[1]
sep, ok := splits[name]
if !ok {
target = append(target, tag)
continue
}
for _, elt := range strings.Split(value, sep) {
target = append(target, fmt.Sprintf("%s:%s", name, elt))
}
}
return target
}
// GetHostTags get the host tags, optionally looking in the cache
func GetHostTags(ctx context.Context, cached bool) *Tags {
key := buildKey("hostTags")
if cached {
if x, found := cache.Cache.Get(key); found {
tags := x.(*Tags)
return tags
}
}
splits := config.Datadog.GetStringMapString("tag_value_split_separator")
appendToHostTags := func(old, new []string) []string {
return appendAndSplitTags(old, new, splits)
}
rawHostTags := config.GetConfiguredTags(false)
hostTags := make([]string, 0, len(rawHostTags))
hostTags = appendToHostTags(hostTags, rawHostTags)
env := config.Datadog.GetString("env")
if env != "" {
hostTags = appendToHostTags(hostTags, []string{"env:" + env})
}
hostname, _ := util.GetHostname(ctx)
clusterName := clustername.GetClusterName(ctx, hostname)
if len(clusterName) != 0 {
clusterNameTags := []string{"kube_cluster_name:" + clusterName}
if !config.Datadog.GetBool("disable_cluster_name_tag_key") {
clusterNameTags = append(clusterNameTags, "cluster_name:"+clusterName)
log.Info("Adding both tags cluster_name and kube_cluster_name. You can use 'disable_cluster_name_tag_key' in the Agent config to keep the kube_cluster_name tag only")
}
hostTags = appendToHostTags(hostTags, clusterNameTags)
}
gceTags := []string{}
getGCE := func(ctx context.Context) ([]string, error) {
rawGceTags, err := gce.GetTags(ctx)
if err != nil {
return nil, err
}
gceTags = appendToHostTags(gceTags, rawGceTags)
return nil, nil
}
providers := make(map[string]*providerDef)
if config.Datadog.GetBool("collect_ec2_tags") {
providers["ec2"] = &providerDef{1, ec2.GetTags, false}
}
if config.Datadog.GetBool("collect_gce_tags") {
providers["gce"] = &providerDef{1, getGCE, false}
}
if config.IsFeaturePresent(config.Kubernetes) {
providers["kubernetes"] = &providerDef{10, k8s.GetTags, false}
}
if config.IsFeaturePresent(config.Docker) {
providers["docker"] = &providerDef{1, docker.GetTags, false}
}
for {
for name, provider := range providers {
provider.retries--
tags, err := provider.getTags(ctx)
if err != nil {
log.Debugf("No %s host tags, remaining attempts: %d, err: %v", name, provider.retries, err)
} else {
provider.retrieved = true
hostTags = appendToHostTags(hostTags, tags)
log.Debugf("Host tags from %s retrieved successfully", name)
}
if provider.retrieved || provider.retries <= 0 {
delete(providers, name)
}
}
if len(providers) == 0 {
break
}
time.Sleep(retrySleepTime)
}
t := &Tags{
System: util.SortUniqInPlace(hostTags),
GoogleCloudPlatform: gceTags,
}
cache.Cache.Set(key, t, cache.NoExpiration)
return t
}