internal/kibana/send_config.go (78 lines of code) (raw):

// Licensed to Elasticsearch B.V. under one or more contributor // license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright // ownership. Elasticsearch B.V. licenses this file to you under // the Apache License, Version 2.0 (the "License"); you may // not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package kibana import ( "bytes" "context" "encoding/json" "fmt" "net/http" "strings" "github.com/elastic/elastic-agent-libs/mapstr" "github.com/elastic/go-ucfg" ) const kibanaConfigUploadPath = "/api/apm/fleet/apm_server_schema" // SendConfig marshals and uploads the provided config to kibana using the // provided ConnectingClient. It retries until its context has been canceled or // the upload succeeds. func SendConfig(ctx context.Context, client *Client, conf *ucfg.Config) error { // configuration options are already flattened (dotted) // any credentials for ES and Kibana are removed flat, err := flattenAndClean(conf) if err != nil { return err } b, err := json.Marshal(format(flat)) if err != nil { return err } resp, err := client.Send(ctx, http.MethodPost, kibanaConfigUploadPath, nil, nil, bytes.NewReader(b)) if err != nil { return err } defer resp.Body.Close() if resp.StatusCode > http.StatusOK { return fmt.Errorf("bad response %s", resp.Status) } return nil } func format(m map[string]interface{}) map[string]interface{} { return map[string]interface{}{"schema": m} } func flattenAndClean(conf *ucfg.Config) (map[string]interface{}, error) { m := mapstr.M{} if err := conf.Unpack(m); err != nil { return nil, err } flat := m.Flatten() out := make(mapstr.M, len(flat)) for k, v := range flat { // remove if elasticsearch is NOT in the front position? // *.elasticsearch.* according to axw if strings.Contains(k, "elasticsearch") { continue } if strings.Contains(k, "kibana") { continue } if strings.HasPrefix(k, "instrumentation") { continue } if strings.HasPrefix(k, "logging.") { switch k[8:] { case "level", "selectors", "metrics.enabled", "metrics.period": default: continue } } if strings.HasPrefix(k, "path") { continue } if k == "gc_percent" || k == "name" || k == "xpack.monitoring.enabled" { continue } if k == "apm-server.host" { v = "0.0.0.0:8200" } if strings.HasPrefix(k, "apm-server.ssl.") { // Following ssl related settings need to be synced: // apm-server.ssl.enabled // apm-server.ssl.certificate // apm-server.ssl.key switch k[15:] { case "enabled", "certificate", "key": default: continue } } out[k] = v } return out, nil }