diff --git a/internal/watcher/instance/nginx_config_parser.go b/internal/watcher/instance/nginx_config_parser.go index 26e698ed6..605e287c5 100644 --- a/internal/watcher/instance/nginx_config_parser.go +++ b/internal/watcher/instance/nginx_config_parser.go @@ -139,7 +139,10 @@ func (ncp *NginxConfigParser) createNginxConfigContext( nginxConfigContext.Files = append(nginxConfigContext.Files, rootFiles...) case "ssl_certificate", "proxy_ssl_certificate", "ssl_client_certificate", "ssl_trusted_certificate": sslCertFile := ncp.sslCert(ctx, directive.Args[0], rootDir) - nginxConfigContext.Files = append(nginxConfigContext.Files, sslCertFile) + if !ncp.isDuplicateFile(nginxConfigContext.Files, sslCertFile) { + nginxConfigContext.Files = append(nginxConfigContext.Files, sslCertFile) + } + case "app_protect_security_log": if len(directive.Args) > 1 { syslogArg := directive.Args[1] @@ -349,6 +352,16 @@ func (ncp *NginxConfigParser) sslCert(ctx context.Context, file, rootDir string) return sslCertFile } +func (ncp *NginxConfigParser) isDuplicateFile(nginxConfigContextFiles []*mpi.File, newFile *mpi.File) bool { + for _, nginxConfigContextFile := range nginxConfigContextFiles { + if nginxConfigContextFile.GetFileMeta().GetName() == newFile.GetFileMeta().GetName() { + return true + } + } + + return false +} + func (ncp *NginxConfigParser) crossplaneConfigTraverse( ctx context.Context, root *crossplane.Config, diff --git a/internal/watcher/instance/nginx_config_parser_test.go b/internal/watcher/instance/nginx_config_parser_test.go index c0c320831..4c9174aaf 100644 --- a/internal/watcher/instance/nginx_config_parser_test.go +++ b/internal/watcher/instance/nginx_config_parser_test.go @@ -14,6 +14,8 @@ import ( "os" "testing" + "google.golang.org/protobuf/types/known/timestamppb" + "github.com/google/go-cmp/cmp" "github.com/nginx/agent/v3/internal/model" "github.com/nginx/agent/v3/pkg/files" @@ -960,3 +962,91 @@ func TestNginxConfigParser_ignoreLog(t *testing.T) { }) } } + +func TestNginxConfigParser_checkDuplicate(t *testing.T) { + fileContent := []byte("location /test {\n return 200 \"Test location\\n\";\n}") + fileContentNew := []byte("some test data") + fileHash := files.GenerateHash(fileContent) + fileHashNew := files.GenerateHash(fileContentNew) + + tests := []struct { + file *mpi.File + name string + expected bool + }{ + { + name: "Test 1: File already in files", + file: &mpi.File{ + FileMeta: &mpi.FileMeta{ + Name: "/etc/nginx/certs/nginx-repo.crt", + Hash: fileHashNew, + ModifiedTime: timestamppb.Now(), + Permissions: "0640", + Size: 0, + }, + }, + expected: true, + }, + { + name: "Test 2: File not in files", + file: &mpi.File{ + FileMeta: &mpi.FileMeta{ + Name: "/etc/nginx/certs/nginx-repo-new.crt", + Hash: fileHashNew, + ModifiedTime: timestamppb.Now(), + Permissions: "0640", + Size: 0, + }, + }, + expected: false, + }, + } + + nginxConfigContextFiles := model.NginxConfigContext{ + Files: []*mpi.File{ + { + FileMeta: &mpi.FileMeta{ + Name: "/etc/nginx/certs/nginx-repo.crt", + Hash: fileHash, + ModifiedTime: timestamppb.Now(), + Permissions: "0640", + Size: 0, + }, + }, + { + FileMeta: &mpi.FileMeta{ + Name: "/etc/nginx/keys/nginx-repo.key", + Hash: fileHash, + ModifiedTime: timestamppb.Now(), + Permissions: "0640", + Size: 0, + }, + }, + { + FileMeta: &mpi.FileMeta{ + Name: "/etc/nginx/keys/inline_key.pem", + Hash: fileHash, + ModifiedTime: timestamppb.Now(), + Permissions: "0640", + Size: 0, + }, + }, + { + FileMeta: &mpi.FileMeta{ + Name: "/etc/nginx/certs/inline_cert.pem", + Hash: fileHash, + ModifiedTime: timestamppb.Now(), + Permissions: "0640", + Size: 0, + }, + }, + }, + } + + for _, test := range tests { + ncp := NewNginxConfigParser(types.AgentConfig()) + t.Run(test.name, func(t *testing.T) { + assert.Equal(t, test.expected, ncp.isDuplicateFile(nginxConfigContextFiles.Files, test.file)) + }) + } +}