@@ -40,6 +40,7 @@ type NginxAppProtectInstanceWatcher struct {
4040 watcher * fsnotify.Watcher
4141 instancesChannel chan <- InstanceUpdatesMessage
4242 nginxAppProtectInstance * mpi.Instance
43+ filesBeingWatcher map [string ]bool
4344 version string
4445 release string
4546 attackSignatureVersion string
@@ -49,7 +50,8 @@ type NginxAppProtectInstanceWatcher struct {
4950
5051func NewNginxAppProtectInstanceWatcher (agentConfig * config.Config ) * NginxAppProtectInstanceWatcher {
5152 return & NginxAppProtectInstanceWatcher {
52- agentConfig : agentConfig ,
53+ agentConfig : agentConfig ,
54+ filesBeingWatcher : make (map [string ]bool ),
5355 }
5456}
5557
@@ -85,6 +87,8 @@ func (w *NginxAppProtectInstanceWatcher) Watch(ctx context.Context, instancesCha
8587
8688 return
8789 case <- instanceWatcherTicker .C :
90+ // Need to keep watching directories in case NAP gets installed a while after NGINX Agent is started
91+ w .watchDirectories (ctx )
8892 w .checkForUpdates (ctx )
8993 case event := <- w .watcher .Events :
9094 w .handleEvent (ctx , event )
@@ -96,29 +100,52 @@ func (w *NginxAppProtectInstanceWatcher) Watch(ctx context.Context, instancesCha
96100
97101func (w * NginxAppProtectInstanceWatcher ) watchDirectories (ctx context.Context ) {
98102 for _ , versionFile := range versionFiles {
99- if err := w .watcher .Add (versionFile ); err != nil {
103+ if ! w .filesBeingWatcher [versionFile ] {
104+ if _ , fileOs := os .Stat (versionFile ); fileOs != nil && ! os .IsNotExist (fileOs ) {
105+ w .filesBeingWatcher [versionFile ] = false
106+ continue
107+ }
108+
109+ w .addWatcher (ctx , versionFile )
110+ w .filesBeingWatcher [versionFile ] = true
111+
112+ // On startup we need to read the files initially if they are discovered for the first time
113+ w .readVersionFile (ctx , versionFile )
114+ }
115+ }
116+ }
117+
118+ func (w * NginxAppProtectInstanceWatcher ) addWatcher (ctx context.Context , versionFile string ) {
119+ if err := w .watcher .Add (versionFile ); err != nil {
120+ slog .ErrorContext (
121+ ctx ,
122+ "Failed to add NGINX App Protect file watcher" ,
123+ "file" , versionFile , "error" , err ,
124+ )
125+ removeError := w .watcher .Remove (versionFile )
126+ if removeError != nil {
100127 slog .ErrorContext (
101128 ctx ,
102- "Failed to add NGINX App Protect file watcher" ,
103- "file" , versionFile , "error" , err ,
129+ "Failed to remove NGINX App Protect file watcher" ,
130+ "file" , versionFile , "error" , removeError ,
104131 )
105- removeError := w .watcher .Remove (versionFile )
106- if removeError != nil {
107- slog .ErrorContext (
108- ctx ,
109- "Failed to remove NGINX App Protect file watcher" ,
110- "file" , versionFile , "error" , removeError ,
111- )
112- }
113132 }
114133 }
134+ }
115135
116- // Check if files exists on startup
117- w .version = w .readFile (ctx , versionFilePath )
118- w .release = w .readFile (ctx , releaseFilePath )
119- w .attackSignatureVersion = w .readFile (ctx , attackSignatureVersionFilePath )
120- w .threatCampaignVersion = w .readFile (ctx , threatCampaignVersionFilePath )
121- w .enforcerEngineVersion = w .readFile (ctx , enforcerEngineVersionFilePath )
136+ func (w * NginxAppProtectInstanceWatcher ) readVersionFile (ctx context.Context , versionFile string ) {
137+ switch {
138+ case versionFile == versionFilePath :
139+ w .version = w .readFile (ctx , versionFilePath )
140+ case versionFile == releaseFilePath :
141+ w .release = w .readFile (ctx , releaseFilePath )
142+ case versionFile == threatCampaignVersionFilePath :
143+ w .threatCampaignVersion = w .readFile (ctx , threatCampaignVersionFilePath )
144+ case versionFile == enforcerEngineVersionFilePath :
145+ w .enforcerEngineVersion = w .readFile (ctx , enforcerEngineVersionFilePath )
146+ case versionFile == attackSignatureVersionFilePath :
147+ w .attackSignatureVersion = w .readFile (ctx , attackSignatureVersionFilePath )
148+ }
122149}
123150
124151func (w * NginxAppProtectInstanceWatcher ) handleEvent (ctx context.Context , event fsnotify.Event ) {
0 commit comments