@@ -6,6 +6,11 @@ package application
66
77import (
88 "context"
9+ "fmt"
10+
11+ "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors"
12+ "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/storage"
13+ "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/status"
914
1015 "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/info"
1116 "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/upgrade"
@@ -31,7 +36,7 @@ type upgraderControl interface {
3136}
3237
3338// New creates a new Agent and bootstrap the required subsystem.
34- func New (log * logger.Logger , pathConfigFile string , reexec reexecManager , uc upgraderControl , agentInfo * info.AgentInfo ) (Application , error ) {
39+ func New (log * logger.Logger , pathConfigFile string , reexec reexecManager , statusCtrl status. Controller , uc upgraderControl , agentInfo * info.AgentInfo ) (Application , error ) {
3540 // Load configuration from disk to understand in which mode of operation
3641 // we must start the elastic-agent, the mode of operation cannot be changed without restarting the
3742 // elastic-agent.
@@ -44,14 +49,15 @@ func New(log *logger.Logger, pathConfigFile string, reexec reexecManager, uc upg
4449 return nil , err
4550 }
4651
47- return createApplication (log , pathConfigFile , rawConfig , reexec , uc , agentInfo )
52+ return createApplication (log , pathConfigFile , rawConfig , reexec , statusCtrl , uc , agentInfo )
4853}
4954
5055func createApplication (
5156 log * logger.Logger ,
5257 pathConfigFile string ,
5358 rawConfig * config.Config ,
5459 reexec reexecManager ,
60+ statusCtrl status.Controller ,
5561 uc upgraderControl ,
5662 agentInfo * info.AgentInfo ,
5763) (Application , error ) {
@@ -66,14 +72,72 @@ func createApplication(
6672
6773 if IsStandalone (cfg .Fleet ) {
6874 log .Info ("Agent is managed locally" )
69- return newLocal (ctx , log , pathConfigFile , rawConfig , reexec , uc , agentInfo )
75+ return newLocal (ctx , log , pathConfigFile , rawConfig , reexec , statusCtrl , uc , agentInfo )
76+ }
77+
78+ // not in standalone; both modes require reading the fleet.yml configuration file
79+ var store storage.Store
80+ store , cfg , err = mergeFleetConfig (rawConfig )
81+
82+ if IsFleetServerBootstrap (cfg .Fleet ) {
83+ log .Info ("Agent is in Fleet Server bootstrap mode" )
84+ return newFleetServerBootstrap (ctx , log , pathConfigFile , rawConfig , statusCtrl , agentInfo )
7085 }
7186
7287 log .Info ("Agent is managed by Fleet" )
73- return newManaged (ctx , log , rawConfig , reexec , agentInfo )
88+ return newManaged (ctx , log , store , cfg , rawConfig , reexec , statusCtrl , agentInfo )
7489}
7590
7691// IsStandalone decides based on missing of fleet.enabled: true or fleet.{access_token,kibana} will place Elastic Agent into standalone mode.
7792func IsStandalone (cfg * configuration.FleetAgentConfig ) bool {
7893 return cfg == nil || ! cfg .Enabled
7994}
95+
96+ // IsFleetServerBootstrap decides if Elastic Agent is started in bootstrap mode.
97+ func IsFleetServerBootstrap (cfg * configuration.FleetAgentConfig ) bool {
98+ return cfg != nil && cfg .Server != nil && cfg .Server .Bootstrap
99+ }
100+
101+ func mergeFleetConfig (rawConfig * config.Config ) (storage.Store , * configuration.Configuration , error ) {
102+ path := info .AgentConfigFile ()
103+ store := storage .NewDiskStore (path )
104+ reader , err := store .Load ()
105+ if err != nil {
106+ return store , nil , errors .New (err , "could not initialize config store" ,
107+ errors .TypeFilesystem ,
108+ errors .M (errors .MetaKeyPath , path ))
109+ }
110+ config , err := config .NewConfigFrom (reader )
111+ if err != nil {
112+ return store , nil , errors .New (err ,
113+ fmt .Sprintf ("fail to read configuration %s for the elastic-agent" , path ),
114+ errors .TypeFilesystem ,
115+ errors .M (errors .MetaKeyPath , path ))
116+ }
117+
118+ // merge local configuration and configuration persisted from fleet.
119+ err = rawConfig .Merge (config )
120+ if err != nil {
121+ return store , nil , errors .New (err ,
122+ fmt .Sprintf ("fail to merge configuration with %s for the elastic-agent" , path ),
123+ errors .TypeConfig ,
124+ errors .M (errors .MetaKeyPath , path ))
125+ }
126+
127+ cfg , err := configuration .NewFromConfig (rawConfig )
128+ if err != nil {
129+ return store , nil , errors .New (err ,
130+ fmt .Sprintf ("fail to unpack configuration from %s" , path ),
131+ errors .TypeFilesystem ,
132+ errors .M (errors .MetaKeyPath , path ))
133+ }
134+
135+ if err := cfg .Fleet .Valid (); err != nil {
136+ return store , nil , errors .New (err ,
137+ "fleet configuration is invalid" ,
138+ errors .TypeFilesystem ,
139+ errors .M (errors .MetaKeyPath , path ))
140+ }
141+
142+ return store , cfg , nil
143+ }
0 commit comments