| 135 | } |
| 136 | |
| 137 | func downloadRules(ctx context.Context, opts *core.Options) { |
| 138 | log.Info().Msg("downloading secret rules") |
| 139 | |
| 140 | // Check if rules already exist |
| 141 | rulesFile := filepath.Join(*opts.RulesPath, secretRuleFile) |
| 142 | if _, err := os.Stat(rulesFile); err == nil { |
| 143 | log.Info().Str("file", rulesFile).Msg("rules file already exists, skipping download") |
| 144 | return |
| 145 | } |
| 146 | |
| 147 | // Make sure output rules directory exists |
| 148 | os.MkdirAll(*opts.RulesPath, fs.ModePerm) |
| 149 | |
| 150 | // Download rules from versioned URL |
| 151 | rulesURL := threatintel.SecretRulesURL(version) |
| 152 | log.Info().Str("url", rulesURL).Msg("downloading rules") |
| 153 | |
| 154 | content, err := threatintel.DownloadFile(ctx, rulesURL) |
| 155 | if err != nil { |
| 156 | log.Error().Err(err).Msg("failed to download rules, continuing with bundled rules if available") |
| 157 | return |
| 158 | } |
| 159 | |
| 160 | log.Info().Int("bytes", content.Len()).Msg("rules file size") |
| 161 | |
| 162 | // Process and write rules file |
| 163 | outRuleFile := filepath.Join(*opts.RulesPath, secretRuleFile) |
| 164 | err = threatintel.ProcessTarGz(content.Bytes(), sourceRuleFile, outRuleFile, processSecretRules) |
| 165 | if err != nil { |
| 166 | log.Error().Err(err).Msg("failed to process rules") |
| 167 | } |
| 168 | } |
| 169 | |
| 170 | func processSecretRules(header *tar.Header, reader io.Reader, outPath string) error { |
| 171 | var fb threatintel.FeedsBundle |