refactor: consolidate AgentFile struct into common package
Created aggregator/pkg/common module with shared AgentFile type. Removed duplicate definitions from migration and services packages. Both agent and server now use common.AgentFile.
This commit is contained in:
@@ -12,6 +12,7 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/Fimeg/RedFlag/aggregator v0.0.0
|
||||||
github.com/Microsoft/go-winio v0.4.21 // indirect
|
github.com/Microsoft/go-winio v0.4.21 // indirect
|
||||||
github.com/containerd/log v0.1.0 // indirect
|
github.com/containerd/log v0.1.0 // indirect
|
||||||
github.com/distribution/reference v0.6.0 // indirect
|
github.com/distribution/reference v0.6.0 // indirect
|
||||||
@@ -36,3 +37,5 @@ require (
|
|||||||
golang.org/x/time v0.5.0 // indirect
|
golang.org/x/time v0.5.0 // indirect
|
||||||
gotest.tools/v3 v3.5.2 // indirect
|
gotest.tools/v3 v3.5.2 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
replace github.com/Fimeg/RedFlag/aggregator => ../aggregator
|
||||||
|
|||||||
@@ -9,29 +9,19 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
|
||||||
|
|
||||||
// AgentFile represents a file associated with the agent
|
"github.com/Fimeg/RedFlag/aggregator/pkg/common"
|
||||||
type AgentFile struct {
|
)
|
||||||
Path string `json:"path"`
|
|
||||||
Size int64 `json:"size"`
|
|
||||||
ModifiedTime time.Time `json:"modified_time"`
|
|
||||||
Version string `json:"version,omitempty"`
|
|
||||||
Checksum string `json:"checksum"`
|
|
||||||
Required bool `json:"required"`
|
|
||||||
Migrate bool `json:"migrate"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// AgentFileInventory represents all files associated with an agent installation
|
// AgentFileInventory represents all files associated with an agent installation
|
||||||
type AgentFileInventory struct {
|
type AgentFileInventory struct {
|
||||||
ConfigFiles []AgentFile `json:"config_files"`
|
ConfigFiles []common.AgentFile `json:"config_files"`
|
||||||
StateFiles []AgentFile `json:"state_files"`
|
StateFiles []common.AgentFile `json:"state_files"`
|
||||||
BinaryFiles []AgentFile `json:"binary_files"`
|
BinaryFiles []common.AgentFile `json:"binary_files"`
|
||||||
LogFiles []AgentFile `json:"log_files"`
|
LogFiles []common.AgentFile `json:"log_files"`
|
||||||
CertificateFiles []AgentFile `json:"certificate_files"`
|
CertificateFiles []common.AgentFile `json:"certificate_files"`
|
||||||
OldDirectoryPaths []string `json:"old_directory_paths"`
|
OldDirectoryPaths []string `json:"old_directory_paths"`
|
||||||
NewDirectoryPaths []string `json:"new_directory_paths"`
|
NewDirectoryPaths []string `json:"new_directory_paths"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MigrationDetection represents the result of migration detection
|
// MigrationDetection represents the result of migration detection
|
||||||
@@ -184,8 +174,8 @@ func scanAgentFiles(config *FileDetectionConfig) (*AgentFileInventory, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// scanDirectory scans a directory for files matching specific patterns
|
// scanDirectory scans a directory for files matching specific patterns
|
||||||
func scanDirectory(dirPath string, patterns map[string][]string) ([]AgentFile, error) {
|
func scanDirectory(dirPath string, patterns map[string][]string) ([]common.AgentFile, error) {
|
||||||
var files []AgentFile
|
var files []common.AgentFile
|
||||||
|
|
||||||
err := filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error {
|
err := filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -203,7 +193,7 @@ func scanDirectory(dirPath string, patterns map[string][]string) ([]AgentFile, e
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
file := AgentFile{
|
file := common.AgentFile{
|
||||||
Path: path,
|
Path: path,
|
||||||
Size: info.Size(),
|
Size: info.Size(),
|
||||||
ModifiedTime: info.ModTime(),
|
ModifiedTime: info.ModTime(),
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/Fimeg/RedFlag/aggregator/pkg/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DockerDetection represents Docker secrets detection results
|
// DockerDetection represents Docker secrets detection results
|
||||||
@@ -23,7 +25,7 @@ type DockerDetection struct {
|
|||||||
RequiredSecrets []string `json:"required_secrets"`
|
RequiredSecrets []string `json:"required_secrets"`
|
||||||
ExistingSecrets []string `json:"existing_secrets"`
|
ExistingSecrets []string `json:"existing_secrets"`
|
||||||
MigrateToSecrets bool `json:"migrate_to_secrets"`
|
MigrateToSecrets bool `json:"migrate_to_secrets"`
|
||||||
SecretFiles []AgentFile `json:"secret_files"`
|
SecretFiles []common.AgentFile `json:"secret_files"`
|
||||||
DetectionTime time.Time `json:"detection_time"`
|
DetectionTime time.Time `json:"detection_time"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,8 +90,8 @@ func DetectDockerSecretsRequirements(config *FileDetectionConfig) (*DockerDetect
|
|||||||
}
|
}
|
||||||
|
|
||||||
// scanSecretFiles scans for files containing sensitive data
|
// scanSecretFiles scans for files containing sensitive data
|
||||||
func scanSecretFiles(config *FileDetectionConfig) ([]AgentFile, error) {
|
func scanSecretFiles(config *FileDetectionConfig) ([]common.AgentFile, error) {
|
||||||
var secretFiles []AgentFile
|
var secretFiles []common.AgentFile
|
||||||
|
|
||||||
// Define sensitive file patterns
|
// Define sensitive file patterns
|
||||||
secretPatterns := []string{
|
secretPatterns := []string{
|
||||||
@@ -116,8 +118,8 @@ func scanSecretFiles(config *FileDetectionConfig) ([]AgentFile, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// scanSecretDirectory scans a directory for files that may contain secrets
|
// scanSecretDirectory scans a directory for files that may contain secrets
|
||||||
func scanSecretDirectory(dirPath string, patterns []string) ([]AgentFile, error) {
|
func scanSecretDirectory(dirPath string, patterns []string) ([]common.AgentFile, error) {
|
||||||
var files []AgentFile
|
var files []common.AgentFile
|
||||||
|
|
||||||
err := filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error {
|
err := filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -146,13 +148,13 @@ func scanSecretDirectory(dirPath string, patterns []string) ([]AgentFile, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// addSecretFile adds a file to the secret files list
|
// addSecretFile adds a file to the secret files list
|
||||||
func addSecretFile(files *[]AgentFile, path string, info os.FileInfo) error {
|
func addSecretFile(files *[]common.AgentFile, path string, info os.FileInfo) error {
|
||||||
checksum, err := calculateFileChecksum(path)
|
checksum, err := calculateFileChecksum(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil // Skip files we can't read
|
return nil // Skip files we can't read
|
||||||
}
|
}
|
||||||
|
|
||||||
file := AgentFile{
|
file := common.AgentFile{
|
||||||
Path: path,
|
Path: path,
|
||||||
Size: info.Size(),
|
Size: info.Size(),
|
||||||
ModifiedTime: info.ModTime(),
|
ModifiedTime: info.ModTime(),
|
||||||
@@ -228,7 +230,7 @@ func containsString(s, substr string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// identifyRequiredSecrets identifies which secrets need to be created
|
// identifyRequiredSecrets identifies which secrets need to be created
|
||||||
func identifyRequiredSecrets(secretFiles []AgentFile) []string {
|
func identifyRequiredSecrets(secretFiles []common.AgentFile) []string {
|
||||||
var secrets []string
|
var secrets []string
|
||||||
for _, file := range secretFiles {
|
for _, file := range secretFiles {
|
||||||
secretName := filepath.Base(file.Path)
|
secretName := filepath.Base(file.Path)
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/Fimeg/RedFlag/aggregator/pkg/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DockerSecretsExecutor handles the execution of Docker secrets migration
|
// DockerSecretsExecutor handles the execution of Docker secrets migration
|
||||||
@@ -96,7 +98,7 @@ func (e *DockerSecretsExecutor) createSecretsBackup() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// migrateSecretFile migrates a single secret file to Docker secrets
|
// migrateSecretFile migrates a single secret file to Docker secrets
|
||||||
func (e *DockerSecretsExecutor) migrateSecretFile(secretFile AgentFile) error {
|
func (e *DockerSecretsExecutor) migrateSecretFile(secretFile common.AgentFile) error {
|
||||||
secretName := filepath.Base(secretFile.Path)
|
secretName := filepath.Base(secretFile.Path)
|
||||||
secretPath := filepath.Join(e.detection.SecretsMountPath, secretName)
|
secretPath := filepath.Join(e.detection.SecretsMountPath, secretName)
|
||||||
|
|
||||||
@@ -120,7 +122,7 @@ func (e *DockerSecretsExecutor) migrateSecretFile(secretFile AgentFile) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// migrateConfigFile handles special migration of config.json with encryption
|
// migrateConfigFile handles special migration of config.json with encryption
|
||||||
func (e *DockerSecretsExecutor) migrateConfigFile(secretFile AgentFile) error {
|
func (e *DockerSecretsExecutor) migrateConfigFile(secretFile common.AgentFile) error {
|
||||||
// Read original config
|
// Read original config
|
||||||
configData, err := os.ReadFile(secretFile.Path)
|
configData, err := os.ReadFile(secretFile.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/Fimeg/RedFlag/aggregator/pkg/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MigrationPlan represents a complete migration plan
|
// MigrationPlan represents a complete migration plan
|
||||||
@@ -239,8 +241,8 @@ func (e *MigrationExecutor) validateMigration() error {
|
|||||||
|
|
||||||
// Helper methods
|
// Helper methods
|
||||||
|
|
||||||
func (e *MigrationExecutor) collectAllFiles() []AgentFile {
|
func (e *MigrationExecutor) collectAllFiles() []common.AgentFile {
|
||||||
var allFiles []AgentFile
|
var allFiles []common.AgentFile
|
||||||
allFiles = append(allFiles, e.plan.Detection.Inventory.ConfigFiles...)
|
allFiles = append(allFiles, e.plan.Detection.Inventory.ConfigFiles...)
|
||||||
allFiles = append(allFiles, e.plan.Detection.Inventory.StateFiles...)
|
allFiles = append(allFiles, e.plan.Detection.Inventory.StateFiles...)
|
||||||
allFiles = append(allFiles, e.plan.Detection.Inventory.BinaryFiles...)
|
allFiles = append(allFiles, e.plan.Detection.Inventory.BinaryFiles...)
|
||||||
@@ -249,7 +251,7 @@ func (e *MigrationExecutor) collectAllFiles() []AgentFile {
|
|||||||
return allFiles
|
return allFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *MigrationExecutor) backupFile(file AgentFile, backupPath string) error {
|
func (e *MigrationExecutor) backupFile(file common.AgentFile, backupPath string) error {
|
||||||
relPath, err := filepath.Rel(e.plan.Config.OldConfigPath, file.Path)
|
relPath, err := filepath.Rel(e.plan.Config.OldConfigPath, file.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Try relative to old state path
|
// Try relative to old state path
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/Fimeg/RedFlag/aggregator v0.0.0
|
||||||
github.com/bytedance/sonic v1.14.0 // indirect
|
github.com/bytedance/sonic v1.14.0 // indirect
|
||||||
github.com/bytedance/sonic/loader v0.3.0 // indirect
|
github.com/bytedance/sonic/loader v0.3.0 // indirect
|
||||||
github.com/cloudwego/base64x v0.1.6 // indirect
|
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||||
@@ -43,3 +44,5 @@ require (
|
|||||||
golang.org/x/tools v0.34.0 // indirect
|
golang.org/x/tools v0.34.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.9 // indirect
|
google.golang.org/protobuf v1.36.9 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
replace github.com/Fimeg/RedFlag/aggregator => ../aggregator
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/Fimeg/RedFlag/aggregator/pkg/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewBuildRequest represents a request for a new agent build
|
// NewBuildRequest represents a request for a new agent build
|
||||||
@@ -57,25 +59,13 @@ type InstallationDetection struct {
|
|||||||
|
|
||||||
// AgentFileInventory represents all files associated with an agent installation
|
// AgentFileInventory represents all files associated with an agent installation
|
||||||
type AgentFileInventory struct {
|
type AgentFileInventory struct {
|
||||||
ConfigFiles []AgentFile `json:"config_files"`
|
ConfigFiles []common.AgentFile `json:"config_files"`
|
||||||
StateFiles []AgentFile `json:"state_files"`
|
StateFiles []common.AgentFile `json:"state_files"`
|
||||||
BinaryFiles []AgentFile `json:"binary_files"`
|
BinaryFiles []common.AgentFile `json:"binary_files"`
|
||||||
LogFiles []AgentFile `json:"log_files"`
|
LogFiles []common.AgentFile `json:"log_files"`
|
||||||
CertificateFiles []AgentFile `json:"certificate_files"`
|
CertificateFiles []common.AgentFile `json:"certificate_files"`
|
||||||
ExistingPaths []string `json:"existing_paths"`
|
ExistingPaths []string `json:"existing_paths"`
|
||||||
MissingPaths []string `json:"missing_paths"`
|
MissingPaths []string `json:"missing_paths"`
|
||||||
}
|
|
||||||
|
|
||||||
// AgentFile represents a file associated with the agent
|
|
||||||
type AgentFile struct {
|
|
||||||
Path string `json:"path"`
|
|
||||||
Size int64 `json:"size"`
|
|
||||||
ModifiedTime string `json:"modified_time"`
|
|
||||||
Version string `json:"version,omitempty"`
|
|
||||||
Checksum string `json:"checksum"`
|
|
||||||
Required bool `json:"required"`
|
|
||||||
Migrate bool `json:"migrate"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MigrationDetection represents migration detection results (from existing migration system)
|
// MigrationDetection represents migration detection results (from existing migration system)
|
||||||
@@ -115,8 +105,8 @@ func (id *InstallationDetector) DetectExistingInstallation(agentID string) (*Ins
|
|||||||
}
|
}
|
||||||
|
|
||||||
// scanDirectory scans a directory for agent-related files
|
// scanDirectory scans a directory for agent-related files
|
||||||
func (id *InstallationDetector) scanDirectory(dirPath string) ([]AgentFile, error) {
|
func (id *InstallationDetector) scanDirectory(dirPath string) ([]common.AgentFile, error) {
|
||||||
var files []AgentFile
|
var files []common.AgentFile
|
||||||
|
|
||||||
entries, err := os.ReadDir(dirPath)
|
entries, err := os.ReadDir(dirPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -143,10 +133,10 @@ func (id *InstallationDetector) scanDirectory(dirPath string) ([]AgentFile, erro
|
|||||||
checksum = ""
|
checksum = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
file := AgentFile{
|
file := common.AgentFile{
|
||||||
Path: fullPath,
|
Path: fullPath,
|
||||||
Size: info.Size(),
|
Size: info.Size(),
|
||||||
ModifiedTime: info.ModTime().Format(time.RFC3339),
|
ModifiedTime: info.ModTime(),
|
||||||
Checksum: checksum,
|
Checksum: checksum,
|
||||||
Required: id.isRequiredFile(entry.Name()),
|
Required: id.isRequiredFile(entry.Name()),
|
||||||
Migrate: id.shouldMigrateFile(entry.Name()),
|
Migrate: id.shouldMigrateFile(entry.Name()),
|
||||||
@@ -160,7 +150,7 @@ func (id *InstallationDetector) scanDirectory(dirPath string) ([]AgentFile, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
// categorizeFile categorizes a file into the appropriate inventory section
|
// categorizeFile categorizes a file into the appropriate inventory section
|
||||||
func (id *InstallationDetector) categorizeFile(file AgentFile, inventory *AgentFileInventory) {
|
func (id *InstallationDetector) categorizeFile(file common.AgentFile, inventory *AgentFileInventory) {
|
||||||
filename := filepath.Base(file.Path)
|
filename := filepath.Base(file.Path)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
|||||||
3
aggregator/go.mod
Normal file
3
aggregator/go.mod
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
module github.com/Fimeg/RedFlag/aggregator
|
||||||
|
|
||||||
|
go 1.23.0
|
||||||
44
aggregator/pkg/common/agentfile.go
Normal file
44
aggregator/pkg/common/agentfile.go
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AgentFile struct {
|
||||||
|
Path string `json:"path"`
|
||||||
|
Size int64 `json:"size"`
|
||||||
|
ModifiedTime time.Time `json:"modified_time"`
|
||||||
|
Version string `json:"version,omitempty"`
|
||||||
|
Checksum string `json:"checksum"`
|
||||||
|
Required bool `json:"required"`
|
||||||
|
Migrate bool `json:"migrate"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CalculateChecksum computes SHA256 checksum of a file
|
||||||
|
func CalculateChecksum(filePath string) (string, error) {
|
||||||
|
data, err := os.ReadFile(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
hash := sha256.Sum256(data)
|
||||||
|
return hex.EncodeToString(hash[:]), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsRequiredFile determines if a file is required for agent operation
|
||||||
|
func IsRequiredFile(path string) bool {
|
||||||
|
requiredFiles := []string{
|
||||||
|
"/etc/redflag/config.json",
|
||||||
|
"/usr/local/bin/redflag-agent",
|
||||||
|
"/etc/systemd/system/redflag-agent.service",
|
||||||
|
}
|
||||||
|
for _, rf := range requiredFiles {
|
||||||
|
if path == rf {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user