From f934ab86c5634875d6f4b77856bc0430d0babdad Mon Sep 17 00:00:00 2001 From: Sachin Frayne <32795683+sachin-frayne@users.noreply.github.com> Date: Fri, 20 Sep 2024 09:11:40 +0200 Subject: [PATCH] [kibana] support api_key (#40360) * [kibana] support api_key * changes username and password to generic values * make check formatting changes * removes skip-go-installation option * fixes: naked return in func * adds skip-go-installation back * only sets header if apikey is not empty --------- Co-authored-by: VihasMakwana <121151420+VihasMakwana@users.noreply.github.com> --- metricbeat/docs/modules/kibana.asciidoc | 3 +++ metricbeat/metricbeat.reference.yml | 3 +++ metricbeat/module/kibana/_meta/config-xpack.yml | 1 + .../module/kibana/_meta/config.reference.yml | 3 +++ metricbeat/module/kibana/_meta/config.yml | 1 + .../kibana/cluster_actions/cluster_actions.go | 2 +- .../module/kibana/cluster_rules/cluster_rules.go | 2 +- metricbeat/module/kibana/config.go | 4 +++- metricbeat/module/kibana/kibana.go | 9 ++++++--- metricbeat/module/kibana/metricset.go | 12 ++++++++++++ .../module/kibana/node_actions/node_actions.go | 2 +- metricbeat/module/kibana/node_rules/node_rules.go | 2 +- metricbeat/module/kibana/settings/settings.go | 14 ++++++++++---- metricbeat/module/kibana/stats/stats.go | 2 +- metricbeat/module/kibana/status/status.go | 3 +++ metricbeat/modules.d/kibana-xpack.yml.disabled | 1 + metricbeat/modules.d/kibana.yml.disabled | 1 + x-pack/metricbeat/metricbeat.reference.yml | 3 +++ 18 files changed, 55 insertions(+), 13 deletions(-) diff --git a/metricbeat/docs/modules/kibana.asciidoc b/metricbeat/docs/modules/kibana.asciidoc index 6757d8db80e..70c1054f463 100644 --- a/metricbeat/docs/modules/kibana.asciidoc +++ b/metricbeat/docs/modules/kibana.asciidoc @@ -51,6 +51,9 @@ metricbeat.modules: hosts: ["localhost:5601"] basepath: "" enabled: true + #username: "user" + #password: "secret" + #api_key: "foo:bar" # Set to true to send data collected by module to X-Pack # Monitoring instead of metricbeat-* indices. diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml index 1724eb6e999..b87cdb049fe 100644 --- a/metricbeat/metricbeat.reference.yml +++ b/metricbeat/metricbeat.reference.yml @@ -493,6 +493,9 @@ metricbeat.modules: hosts: ["localhost:5601"] basepath: "" enabled: true + #username: "user" + #password: "secret" + #api_key: "foo:bar" # Set to true to send data collected by module to X-Pack # Monitoring instead of metricbeat-* indices. diff --git a/metricbeat/module/kibana/_meta/config-xpack.yml b/metricbeat/module/kibana/_meta/config-xpack.yml index 73dffedb072..d45d2895b03 100644 --- a/metricbeat/module/kibana/_meta/config-xpack.yml +++ b/metricbeat/module/kibana/_meta/config-xpack.yml @@ -5,3 +5,4 @@ #basepath: "" #username: "user" #password: "secret" + #api_key: "foo:bar" diff --git a/metricbeat/module/kibana/_meta/config.reference.yml b/metricbeat/module/kibana/_meta/config.reference.yml index 466dd7899dd..3dbb3285237 100644 --- a/metricbeat/module/kibana/_meta/config.reference.yml +++ b/metricbeat/module/kibana/_meta/config.reference.yml @@ -4,6 +4,9 @@ hosts: ["localhost:5601"] basepath: "" enabled: true + #username: "user" + #password: "secret" + #api_key: "foo:bar" # Set to true to send data collected by module to X-Pack # Monitoring instead of metricbeat-* indices. diff --git a/metricbeat/module/kibana/_meta/config.yml b/metricbeat/module/kibana/_meta/config.yml index f997985d3c2..3b4317c527f 100644 --- a/metricbeat/module/kibana/_meta/config.yml +++ b/metricbeat/module/kibana/_meta/config.yml @@ -6,3 +6,4 @@ #basepath: "" #username: "user" #password: "secret" + #api_key: "foo:bar" diff --git a/metricbeat/module/kibana/cluster_actions/cluster_actions.go b/metricbeat/module/kibana/cluster_actions/cluster_actions.go index cb50ce6c21a..b4e1e6e4fe7 100644 --- a/metricbeat/module/kibana/cluster_actions/cluster_actions.go +++ b/metricbeat/module/kibana/cluster_actions/cluster_actions.go @@ -88,7 +88,7 @@ func (m *MetricSet) Fetch(r mb.ReporterV2) (err error) { } func (m *MetricSet) validate() (err error, versionSupported bool) { - kibanaVersion, err := kibana.GetVersion(m.actionsHTTP, kibana.ClusterActionsPath) + kibanaVersion, err := kibana.GetVersion(m.actionsHTTP, kibana.ClusterActionsPath, m.ApiKey) if err != nil { return err, false } diff --git a/metricbeat/module/kibana/cluster_rules/cluster_rules.go b/metricbeat/module/kibana/cluster_rules/cluster_rules.go index 6131b5cdc5e..bbb9b182cc4 100644 --- a/metricbeat/module/kibana/cluster_rules/cluster_rules.go +++ b/metricbeat/module/kibana/cluster_rules/cluster_rules.go @@ -88,7 +88,7 @@ func (m *MetricSet) Fetch(r mb.ReporterV2) (err error) { } func (m *MetricSet) validate() (err error, versionSupported bool) { - kibanaVersion, err := kibana.GetVersion(m.rulesHTTP, kibana.ClusterRulesPath) + kibanaVersion, err := kibana.GetVersion(m.rulesHTTP, kibana.ClusterRulesPath, m.ApiKey) if err != nil { return err, false } diff --git a/metricbeat/module/kibana/config.go b/metricbeat/module/kibana/config.go index 748ba6bb5e3..e559d946856 100644 --- a/metricbeat/module/kibana/config.go +++ b/metricbeat/module/kibana/config.go @@ -19,12 +19,14 @@ package kibana // Config defines the structure for the Kibana module configuration options type Config struct { - XPackEnabled bool `config:"xpack.enabled"` + XPackEnabled bool `config:"xpack.enabled"` + ApiKey string `config:"api_key"` } // DefaultConfig returns the default configuration for the Kibana module func DefaultConfig() Config { return Config{ XPackEnabled: false, + ApiKey: "", } } diff --git a/metricbeat/module/kibana/kibana.go b/metricbeat/module/kibana/kibana.go index 9a3fa60b12e..499f5c5ede5 100644 --- a/metricbeat/module/kibana/kibana.go +++ b/metricbeat/module/kibana/kibana.go @@ -96,8 +96,8 @@ func NewModule(base mb.BaseModule) (mb.Module, error) { } // GetVersion returns the version of the Kibana instance -func GetVersion(http *helper.HTTP, currentPath string) (*version.V, error) { - content, err := fetchPath(http, currentPath, StatusPath) +func GetVersion(http *helper.HTTP, currentPath string, apiKey string) (*version.V, error) { + content, err := fetchPath(http, currentPath, StatusPath, apiKey) if err != nil { return nil, err } @@ -144,7 +144,7 @@ func IsUsageExcludable(currentKibanaVersion *version.V) bool { v7_0_1.LessThanOrEqual(false, currentKibanaVersion) } -func fetchPath(http *helper.HTTP, currentPath, newPath string) ([]byte, error) { +func fetchPath(http *helper.HTTP, currentPath, newPath string, apiKey string) ([]byte, error) { currentURI := http.GetURI() defer http.SetURI(currentURI) // Reset after this request @@ -159,5 +159,8 @@ func fetchPath(http *helper.HTTP, currentPath, newPath string) ([]byte, error) { // Http helper includes the HostData with username and password http.SetURI(u.String()) + if apiKey != "" { + http.SetHeader("Authorization", "ApiKey "+apiKey) + } return http.FetchContent() } diff --git a/metricbeat/module/kibana/metricset.go b/metricbeat/module/kibana/metricset.go index 1a68669fe58..f547373cb6b 100644 --- a/metricbeat/module/kibana/metricset.go +++ b/metricbeat/module/kibana/metricset.go @@ -18,6 +18,9 @@ package kibana import ( + "encoding/base64" + "fmt" + "github.com/elastic/beats/v7/metricbeat/mb" ) @@ -25,6 +28,7 @@ import ( type MetricSet struct { mb.BaseMetricSet XPackEnabled bool + ApiKey string } // NewMetricSet creates a metricset that can be used to build other metricsets @@ -35,8 +39,16 @@ func NewMetricSet(base mb.BaseMetricSet) (*MetricSet, error) { return nil, err } + if config.ApiKey != "" { + hostData := base.HostData() + if hostData.User != "" || hostData.Password != "" { + return nil, fmt.Errorf("cannot set both api_key and username/password") + } + } + return &MetricSet{ base, config.XPackEnabled, + base64.StdEncoding.EncodeToString([]byte(config.ApiKey)), }, nil } diff --git a/metricbeat/module/kibana/node_actions/node_actions.go b/metricbeat/module/kibana/node_actions/node_actions.go index f6f742ccffa..83d8b97d4df 100644 --- a/metricbeat/module/kibana/node_actions/node_actions.go +++ b/metricbeat/module/kibana/node_actions/node_actions.go @@ -88,7 +88,7 @@ func (m *MetricSet) Fetch(r mb.ReporterV2) (err error) { } func (m *MetricSet) validate() (err error, versionSupported bool) { - kibanaVersion, err := kibana.GetVersion(m.actionsHTTP, kibana.NodeActionsPath) + kibanaVersion, err := kibana.GetVersion(m.actionsHTTP, kibana.NodeActionsPath, m.ApiKey) if err != nil { return err, false } diff --git a/metricbeat/module/kibana/node_rules/node_rules.go b/metricbeat/module/kibana/node_rules/node_rules.go index 5af7234c54b..34fe0f91268 100644 --- a/metricbeat/module/kibana/node_rules/node_rules.go +++ b/metricbeat/module/kibana/node_rules/node_rules.go @@ -88,7 +88,7 @@ func (m *MetricSet) Fetch(r mb.ReporterV2) (err error) { } func (m *MetricSet) validate() (err error, versionSupported bool) { - kibanaVersion, err := kibana.GetVersion(m.rulesHTTP, kibana.NodeRulesPath) + kibanaVersion, err := kibana.GetVersion(m.rulesHTTP, kibana.NodeRulesPath, m.ApiKey) if err != nil { return err, false } diff --git a/metricbeat/module/kibana/settings/settings.go b/metricbeat/module/kibana/settings/settings.go index b2468bfa461..2d8b9f943ea 100644 --- a/metricbeat/module/kibana/settings/settings.go +++ b/metricbeat/module/kibana/settings/settings.go @@ -45,13 +45,19 @@ var ( // MetricSet type defines all fields of the MetricSet type MetricSet struct { + *kibana.MetricSet mb.BaseMetricSet settingsHTTP *helper.HTTP } // New create a new instance of the MetricSet func New(base mb.BaseMetricSet) (mb.MetricSet, error) { + ms, err := kibana.NewMetricSet(base) + if err != nil { + return nil, err + } return &MetricSet{ + MetricSet: ms, BaseMetricSet: base, }, nil } @@ -61,12 +67,12 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { // descriptive error must be returned. func (m *MetricSet) Fetch(r mb.ReporterV2) (err error) { if err = m.init(); err != nil { - return + return err } content, err := m.settingsHTTP.FetchContent() if err != nil { - return + return err } return eventMapping(r, content) @@ -80,7 +86,7 @@ func (m *MetricSet) init() (err error) { httpHelper.SetHeaderDefault(productorigin.Header, productorigin.Beats) - kibanaVersion, err := kibana.GetVersion(httpHelper, kibana.SettingsPath) + kibanaVersion, err := kibana.GetVersion(httpHelper, kibana.SettingsPath, m.ApiKey) if err != nil { return err } @@ -93,5 +99,5 @@ func (m *MetricSet) init() (err error) { m.settingsHTTP, err = helper.NewHTTP(m.BaseMetricSet) - return + return err } diff --git a/metricbeat/module/kibana/stats/stats.go b/metricbeat/module/kibana/stats/stats.go index 5b96525b0e5..6659bf6eddf 100644 --- a/metricbeat/module/kibana/stats/stats.go +++ b/metricbeat/module/kibana/stats/stats.go @@ -93,7 +93,7 @@ func (m *MetricSet) Fetch(r mb.ReporterV2) (err error) { } func (m *MetricSet) init() (err error, versionSupported bool) { - kibanaVersion, err := kibana.GetVersion(m.statsHTTP, kibana.StatsPath) + kibanaVersion, err := kibana.GetVersion(m.statsHTTP, kibana.StatsPath, m.ApiKey) if err != nil { return err, false } diff --git a/metricbeat/module/kibana/status/status.go b/metricbeat/module/kibana/status/status.go index 7715ca48cb9..62a1a0b0e4d 100644 --- a/metricbeat/module/kibana/status/status.go +++ b/metricbeat/module/kibana/status/status.go @@ -72,6 +72,9 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { // It returns the event which is then forward to the output. In case of an error, a // descriptive error must be returned. func (m *MetricSet) Fetch(r mb.ReporterV2) error { + if m.ApiKey != "" { + m.http.SetHeader("Authorization", "ApiKey "+m.ApiKey) + } content, err := m.http.FetchContent() if err != nil { return err diff --git a/metricbeat/modules.d/kibana-xpack.yml.disabled b/metricbeat/modules.d/kibana-xpack.yml.disabled index 91471a7c212..7bc747f0fe9 100644 --- a/metricbeat/modules.d/kibana-xpack.yml.disabled +++ b/metricbeat/modules.d/kibana-xpack.yml.disabled @@ -8,3 +8,4 @@ #basepath: "" #username: "user" #password: "secret" + #api_key: "foo:bar" diff --git a/metricbeat/modules.d/kibana.yml.disabled b/metricbeat/modules.d/kibana.yml.disabled index 27ca4b1a05f..138d3bd6e60 100644 --- a/metricbeat/modules.d/kibana.yml.disabled +++ b/metricbeat/modules.d/kibana.yml.disabled @@ -9,3 +9,4 @@ #basepath: "" #username: "user" #password: "secret" + #api_key: "foo:bar" diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index abf484f473e..8a3ba9cbd5b 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -892,6 +892,9 @@ metricbeat.modules: hosts: ["localhost:5601"] basepath: "" enabled: true + #username: "user" + #password: "secret" + #api_key: "foo:bar" # Set to true to send data collected by module to X-Pack # Monitoring instead of metricbeat-* indices.