Skip to content

Commit

Permalink
Add BearerToken Defaults for Kubernetes Plugins
Browse files Browse the repository at this point in the history
Due to Kubernetes RBAC policies, it's extremely rare and unlikely that
anyone will run these plugins outside of the cluster. With that in-mind,
we should use as many defaults as possible to remove configuration.

All pods within Kubernetes have a ServiceAccount token mounted in to this
location, which shouldn't need to be repeated each time.
  • Loading branch information
rawkode committed Oct 18, 2019
1 parent be7c71a commit f5550e3
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 15 deletions.
30 changes: 16 additions & 14 deletions plugins/inputs/kube_inventory/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ avoid cardinality issues:
# namespace = "default"

## Use bearer token for authorization. ('bearer_token' takes priority)
## If both of these are empty, we'll use the default serviceaccount:
## at: /run/secrets/kubernetes.io/serviceaccount/token
# bearer_token = "/path/to/bearer/token"
## OR
# bearer_token_string = "abc_123"
Expand Down Expand Up @@ -236,25 +238,25 @@ subjects:

The persistentvolume "phase" is saved in the `phase` tag with a correlated numeric field called `phase_type` corresponding with that tag value.

|Tag value |Corresponding field value|
-----------|-------------------------|
|bound | 0 |
|failed | 1 |
|pending | 2 |
|released | 3 |
|available | 4 |
|unknown | 5 |
| Tag value | Corresponding field value |
| --------- | ------------------------- |
| bound | 0 |
| failed | 1 |
| pending | 2 |
| released | 3 |
| available | 4 |
| unknown | 5 |

#### pvc `phase_type`

The persistentvolumeclaim "phase" is saved in the `phase` tag with a correlated numeric field called `phase_type` corresponding with that tag value.

|Tag value |Corresponding field value|
-----------|-------------------------|
|bound | 0 |
|lost | 1 |
|pending | 2 |
|unknown | 3 |
| Tag value | Corresponding field value |
| --------- | ------------------------- |
| bound | 0 |
| lost | 1 |
| pending | 2 |
| unknown | 3 |


### Example Output:
Expand Down
15 changes: 15 additions & 0 deletions plugins/inputs/kube_inventory/kube_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"io/ioutil"
"log"
"os"
"strconv"
"strings"
"sync"
Expand All @@ -19,6 +20,10 @@ import (
"github.com/influxdata/telegraf/plugins/inputs"
)

const (
defaultServiceAccountPath = "/run/secrets/kubernetes.io/serviceaccount/token"
)

// KubernetesInventory represents the config object for the plugin.
type KubernetesInventory struct {
URL string `toml:"url"`
Expand All @@ -42,6 +47,8 @@ var sampleConfig = `
# namespace = "default"
## Use bearer token for authorization. ('bearer_token' takes priority)
## If both of these are empty, we'll use the default serviceaccount:
## at: /run/secrets/kubernetes.io/serviceaccount/token
# bearer_token = "/path/to/bearer/token"
## OR
# bearer_token_string = "abc_123"
Expand Down Expand Up @@ -122,6 +129,13 @@ var availableCollectors = map[string]func(ctx context.Context, acc telegraf.Accu
}

func (ki *KubernetesInventory) initClient() (*client, error) {
// Even neither are provided, use the default service account.
if ki.BearerToken == "" && ki.BearerTokenString == "" {
if _, err := os.Stat(defaultServiceAccountPath); err == nil {
ki.BearerToken = defaultServiceAccountPath
}
}

if ki.BearerToken != "" {
token, err := ioutil.ReadFile(ki.BearerToken)
if err != nil {
Expand Down Expand Up @@ -176,6 +190,7 @@ func init() {
return &KubernetesInventory{
ResponseTimeout: internal.Duration{Duration: time.Second * 5},
Namespace: "default",
BearerToken: "/run/secrets/kubernetes.io/serviceaccount/token",
}
})
}
2 changes: 2 additions & 0 deletions plugins/inputs/kubernetes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ avoid cardinality issues:
url = "http://127.0.0.1:10255"

## Use bearer token for authorization. ('bearer_token' takes priority)
## If both of these are empty, we'll use the default serviceaccount:
## at: /run/secrets/kubernetes.io/serviceaccount/token
# bearer_token = "/path/to/bearer/token"
## OR
# bearer_token_string = "abc_123"
Expand Down
13 changes: 12 additions & 1 deletion plugins/inputs/kubernetes/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"io/ioutil"
"net/http"
"net/url"
"os"
"strings"
"time"

Expand Down Expand Up @@ -36,6 +37,8 @@ var sampleConfig = `
url = "http://127.0.0.1:10255"
## Use bearer token for authorization. ('bearer_token' takes priority)
## If both of these are empty, we'll use the default serviceaccount:
## at: /run/secrets/kubernetes.io/serviceaccount/token
# bearer_token = "/path/to/bearer/token"
## OR
# bearer_token_string = "abc_123"
Expand All @@ -52,7 +55,8 @@ var sampleConfig = `
`

const (
summaryEndpoint = `%s/stats/summary`
summaryEndpoint = `%s/stats/summary`
defaultServiceAccountPath = "/run/secrets/kubernetes.io/serviceaccount/token"
)

func init() {
Expand Down Expand Up @@ -108,6 +112,13 @@ func (k *Kubernetes) gatherSummary(baseURL string, acc telegraf.Accumulator) err
}
}

// Even neither are provided, use the default service account.
if k.BearerToken == "" && k.BearerTokenString == "" {
if _, err := os.Stat(defaultServiceAccountPath); err == nil {
k.BearerToken = defaultServiceAccountPath
}
}

if k.BearerToken != "" {
token, err := ioutil.ReadFile(k.BearerToken)
if err != nil {
Expand Down

0 comments on commit f5550e3

Please sign in to comment.