Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Ingest Manager] Keep http and logging config during enroll #25132

Merged
merged 9 commits into from
Apr 20, 2021
1 change: 1 addition & 0 deletions x-pack/elastic-agent/CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,5 @@
- Add status subcommand {pull}24856[24856]
- Add leader_election provider for k8s {pull}24267[24267]
- Add --fleet-server-service-token and FLEET_SERVER_SERVICE_TOKEN options {pull}25083[25083]
- Keep http and logging config during enroll {pull}25132[25132]
- Log output of container to $LOGS_PATH/elastic-agent-start.log when LOGS_PATH set {pull}25150[25150]
12 changes: 8 additions & 4 deletions x-pack/elastic-agent/pkg/agent/application/info/agent_id.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors"
"github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/storage"
"github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/config"
monitoringConfig "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/monitoring/config"
)

// defaultAgentConfigFile is a name of file used to store agent information
Expand All @@ -27,8 +28,9 @@ const defaultLogLevel = "info"
const maxRetriesloadAgentInfo = 5

type persistentAgentInfo struct {
ID string `json:"id" yaml:"id" config:"id"`
LogLevel string `json:"logging.level,omitempty" yaml:"logging.level,omitempty" config:"logging.level,omitempty"`
ID string `json:"id" yaml:"id" config:"id"`
LogLevel string `json:"logging.level,omitempty" yaml:"logging.level,omitempty" config:"logging.level,omitempty"`
MonitoringHTTP *monitoringConfig.MonitoringHTTPConfig `json:"monitoring.http,omitempty" yaml:"monitoring.http,omitempty" config:"monitoring.http,omitempty"`
}

type ioStore interface {
Expand Down Expand Up @@ -90,7 +92,8 @@ func getInfoFromStore(s ioStore, logLevel string) (*persistentAgentInfo, error)
agentInfoSubMap, found := configMap[agentInfoKey]
if !found {
return &persistentAgentInfo{
LogLevel: logLevel,
LogLevel: logLevel,
MonitoringHTTP: monitoringConfig.DefaultConfig().HTTP,
}, nil
}

Expand All @@ -100,7 +103,8 @@ func getInfoFromStore(s ioStore, logLevel string) (*persistentAgentInfo, error)
}

pid := &persistentAgentInfo{
LogLevel: logLevel,
LogLevel: logLevel,
MonitoringHTTP: monitoringConfig.DefaultConfig().HTTP,
}
if err := cc.Unpack(&pid); err != nil {
return nil, errors.New(err, "failed to unpack stored config to map")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,12 @@ func fleetToReader(agentInfo *info.AgentInfo, cfg *configuration.Configuration)
configToStore := map[string]interface{}{
"fleet": cfg.Fleet,
"agent": map[string]interface{}{
"id": agentInfo.AgentID(),
"id": agentInfo.AgentID(),
"logging.level": cfg.Settings.LoggingConfig.Level,
"monitoring.http": cfg.Settings.MonitoringConfig.HTTP,
},
}

data, err := yaml.Marshal(configToStore)
if err != nil {
return nil, err
Expand Down
87 changes: 74 additions & 13 deletions x-pack/elastic-agent/pkg/agent/cmd/enroll_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ import (
"github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/control/proto"
"github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors"
"github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/storage"
"github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/config"
"github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/authority"
"github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/logger"
monitoringConfig "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/monitoring/config"
"github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/process"
"github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/fleetapi"
fleetclient "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/fleetapi/client"
Expand Down Expand Up @@ -62,6 +64,7 @@ type enrollCmd struct {
configStore saver
remoteConfig remote.Config
agentProc *process.Info
configPath string
}

// enrollCmdFleetServerOption define all the supported enrollment options for bootstrapping with Fleet Server.
Expand Down Expand Up @@ -149,13 +152,20 @@ func newEnrollCmdWithStore(
log: log,
options: options,
configStore: store,
configPath: configPath,
}, nil
}

// Execute tries to enroll the agent into Fleet.
func (c *enrollCmd) Execute(ctx context.Context) error {
var err error
defer c.stopAgent() // ensure its stopped no matter what

persistentConfig, err := getPersistentConfig(c.configPath)
if err != nil {
return err
}

if c.options.FleetServer.ConnStr != "" {
token, err := c.fleetServerBootstrap(ctx)
if err != nil {
Expand All @@ -182,7 +192,7 @@ func (c *enrollCmd) Execute(ctx context.Context) error {
errors.M(errors.MetaKeyURI, c.options.URL))
}

err = c.enrollWithBackoff(ctx)
err = c.enrollWithBackoff(ctx, persistentConfig)
if err != nil {
return errors.New(err, "fail to enroll")
}
Expand Down Expand Up @@ -323,10 +333,10 @@ func (c *enrollCmd) daemonReload(ctx context.Context) error {
return daemon.Restart(ctx)
}

func (c *enrollCmd) enrollWithBackoff(ctx context.Context) error {
func (c *enrollCmd) enrollWithBackoff(ctx context.Context, persistentConfig map[string]interface{}) error {
delay(ctx, enrollDelay)

err := c.enroll(ctx)
err := c.enroll(ctx, persistentConfig)
signal := make(chan struct{})
backExp := backoff.NewExpBackoff(signal, 60*time.Second, 10*time.Minute)

Expand All @@ -344,14 +354,14 @@ func (c *enrollCmd) enrollWithBackoff(ctx context.Context) error {
}
backExp.Wait()
c.log.Info("Retrying to enroll...")
err = c.enroll(ctx)
err = c.enroll(ctx, persistentConfig)
}

close(signal)
return err
}

func (c *enrollCmd) enroll(ctx context.Context) error {
func (c *enrollCmd) enroll(ctx context.Context, persistentConfig map[string]interface{}) error {
cmd := fleetapi.NewEnrollCmd(c.client)

metadata, err := info.Metadata()
Expand Down Expand Up @@ -380,15 +390,12 @@ func (c *enrollCmd) enroll(ctx context.Context) error {
if err != nil {
return err
}
agentConfig := map[string]interface{}{
"id": resp.Item.ID,
}
if c.options.Staging != "" {
staging := fmt.Sprintf("https://staging.elastic.co/%s-%s/downloads/", release.Version(), c.options.Staging[:8])
agentConfig["download"] = map[string]interface{}{
"sourceURI": staging,
}

agentConfig, err := c.createAgentConfig(resp.Item.ID, persistentConfig)
if err != nil {
return err
}

if c.options.FleetServer.ConnStr != "" {
serverConfig, err := createFleetServerBootstrapConfig(
c.options.FleetServer.ConnStr, c.options.FleetServer.ServiceToken,
Expand Down Expand Up @@ -751,3 +758,57 @@ func createFleetConfigFromEnroll(accessAPIKey string, cli remote.Config) (*confi
}
return cfg, nil
}

func (c *enrollCmd) createAgentConfig(agentID string, pc map[string]interface{}) (map[string]interface{}, error) {
agentConfig := map[string]interface{}{
"id": agentID,
}

if c.options.Staging != "" {
staging := fmt.Sprintf("https://staging.elastic.co/%s-%s/downloads/", release.Version(), c.options.Staging[:8])
agentConfig["download"] = map[string]interface{}{
"sourceURI": staging,
}
}

for k, v := range pc {
agentConfig[k] = v
}

return agentConfig, nil
}

func getPersistentConfig(pathConfigFile string) (map[string]interface{}, error) {
persistentMap := make(map[string]interface{})
rawConfig, err := config.LoadFile(pathConfigFile)
if os.IsNotExist(err) {
return persistentMap, nil
}
if err != nil {
return nil, errors.New(err,
fmt.Sprintf("could not read configuration file %s", pathConfigFile),
errors.TypeFilesystem,
errors.M(errors.MetaKeyPath, pathConfigFile))
}

pc := &struct {
LogLevel string `json:"agent.logging.level,omitempty" yaml:"agent.logging.level,omitempty" config:"agent.logging.level,omitempty"`
MonitoringHTTP *monitoringConfig.MonitoringHTTPConfig `json:"agent.monitoring.http,omitempty" yaml:"agent.monitoring.http,omitempty" config:"agent.monitoring.http,omitempty"`
}{
MonitoringHTTP: monitoringConfig.DefaultConfig().HTTP,
}

if err := rawConfig.Unpack(&pc); err != nil {
return nil, err
}

if pc.LogLevel != "" {
persistentMap["logging.level"] = pc.LogLevel
}

if pc.MonitoringHTTP != nil {
persistentMap["monitoring.http"] = pc.MonitoringHTTP
}

return persistentMap, nil
}