|
| 1 | +package cmd |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + "time" |
| 6 | + |
| 7 | + "github.com/fatih/color" |
| 8 | + "github.com/spf13/cobra" |
| 9 | +) |
| 10 | + |
| 11 | +// TASK 12: Monitoring Query Commands |
| 12 | + |
| 13 | +var monitoringCmd = &cobra.Command{ |
| 14 | + Use: "monitoring", |
| 15 | + Short: "Query monitoring data (alerts, DNS changes, certificates)", |
| 16 | + Long: `Access monitoring data stored in the database. |
| 17 | +
|
| 18 | +Available subcommands: |
| 19 | + alerts - List monitoring alerts |
| 20 | + dns-changes - Show DNS record changes for a target |
| 21 | + certificates - Show certificate expiry information |
| 22 | + git-changes - Show Git repository changes |
| 23 | + web-changes - Show website change detection |
| 24 | +
|
| 25 | +Examples: |
| 26 | + shells monitoring alerts |
| 27 | + shells monitoring alerts --target example.com --severity critical |
| 28 | + shells monitoring dns-changes example.com |
| 29 | + shells monitoring certificates expiring --days 30`, |
| 30 | +} |
| 31 | + |
| 32 | +func init() { |
| 33 | + rootCmd.AddCommand(monitoringCmd) |
| 34 | + |
| 35 | + // Add subcommands |
| 36 | + monitoringCmd.AddCommand(monitoringAlertsCmd) |
| 37 | + monitoringCmd.AddCommand(monitoringDNSChangesCmd) |
| 38 | + monitoringCmd.AddCommand(monitoringCertificatesCmd) |
| 39 | + monitoringCmd.AddCommand(monitoringGitChangesCmd) |
| 40 | + monitoringCmd.AddCommand(monitoringWebChangesCmd) |
| 41 | +} |
| 42 | + |
| 43 | +// monitoringAlertsCmd lists monitoring alerts |
| 44 | +var monitoringAlertsCmd = &cobra.Command{ |
| 45 | + Use: "alerts", |
| 46 | + Short: "List monitoring alerts", |
| 47 | + Long: `List all monitoring alerts or filter by target/severity. |
| 48 | +
|
| 49 | +Examples: |
| 50 | + shells monitoring alerts |
| 51 | + shells monitoring alerts --target example.com |
| 52 | + shells monitoring alerts --severity critical |
| 53 | + shells monitoring alerts --since 7d`, |
| 54 | + RunE: func(cmd *cobra.Command, args []string) error { |
| 55 | + target, _ := cmd.Flags().GetString("target") |
| 56 | + severity, _ := cmd.Flags().GetString("severity") |
| 57 | + sinceDuration, _ := cmd.Flags().GetString("since") |
| 58 | + limit, _ := cmd.Flags().GetInt("limit") |
| 59 | + output, _ := cmd.Flags().GetString("output") |
| 60 | + |
| 61 | + store := GetStore() |
| 62 | + if store == nil { |
| 63 | + return fmt.Errorf("database not initialized") |
| 64 | + } |
| 65 | + |
| 66 | + ctx := GetContext() |
| 67 | + |
| 68 | + // Calculate time window |
| 69 | + var since time.Time |
| 70 | + if sinceDuration != "" { |
| 71 | + duration, err := parseDuration(sinceDuration) |
| 72 | + if err != nil { |
| 73 | + return fmt.Errorf("invalid duration: %w", err) |
| 74 | + } |
| 75 | + since = time.Now().Add(-duration) |
| 76 | + } |
| 77 | + |
| 78 | + // Query alerts from database |
| 79 | + // Note: This requires implementing GetMonitoringAlerts in ResultStore interface |
| 80 | + // For now, show a placeholder message |
| 81 | + fmt.Println() |
| 82 | + color.Cyan("═══ Monitoring Alerts ═══") |
| 83 | + |
| 84 | + if target != "" { |
| 85 | + fmt.Printf(" Target: %s\n", target) |
| 86 | + } |
| 87 | + if severity != "" { |
| 88 | + fmt.Printf(" Severity: %s\n", severity) |
| 89 | + } |
| 90 | + if sinceDuration != "" { |
| 91 | + fmt.Printf(" Since: %s (from %s)\n", sinceDuration, since.Format("2006-01-02")) |
| 92 | + } |
| 93 | + fmt.Println() |
| 94 | + |
| 95 | + // TODO: Implement actual database query when monitoring_alerts table is populated |
| 96 | + color.Yellow(" Note: Monitoring alerts table exists but no query method implemented yet.\n") |
| 97 | + color.Yellow(" This feature will be available once monitoring is actively running.\n") |
| 98 | + fmt.Println() |
| 99 | + |
| 100 | + _ = ctx |
| 101 | + _ = limit |
| 102 | + _ = output |
| 103 | + |
| 104 | + return nil |
| 105 | + }, |
| 106 | +} |
| 107 | + |
| 108 | +// monitoringDNSChangesCmd shows DNS changes for a target |
| 109 | +var monitoringDNSChangesCmd = &cobra.Command{ |
| 110 | + Use: "dns-changes <target>", |
| 111 | + Short: "Show DNS record changes for a target", |
| 112 | + Long: `Display DNS record changes detected for a target. |
| 113 | +
|
| 114 | +Examples: |
| 115 | + shells monitoring dns-changes example.com |
| 116 | + shells monitoring dns-changes example.com --since 30d |
| 117 | + shells monitoring dns-changes example.com --record-type A`, |
| 118 | + Args: cobra.ExactArgs(1), |
| 119 | + RunE: func(cmd *cobra.Command, args []string) error { |
| 120 | + target := args[0] |
| 121 | + sinceDuration, _ := cmd.Flags().GetString("since") |
| 122 | + recordType, _ := cmd.Flags().GetString("record-type") |
| 123 | + output, _ := cmd.Flags().GetString("output") |
| 124 | + |
| 125 | + store := GetStore() |
| 126 | + if store == nil { |
| 127 | + return fmt.Errorf("database not initialized") |
| 128 | + } |
| 129 | + |
| 130 | + ctx := GetContext() |
| 131 | + |
| 132 | + var since time.Time |
| 133 | + if sinceDuration != "" { |
| 134 | + duration, err := parseDuration(sinceDuration) |
| 135 | + if err != nil { |
| 136 | + return fmt.Errorf("invalid duration: %w", err) |
| 137 | + } |
| 138 | + since = time.Now().Add(-duration) |
| 139 | + } |
| 140 | + |
| 141 | + fmt.Println() |
| 142 | + color.Cyan("═══ DNS Changes: %s ═══", target) |
| 143 | + |
| 144 | + if sinceDuration != "" { |
| 145 | + fmt.Printf(" Since: %s (from %s)\n", sinceDuration, since.Format("2006-01-02")) |
| 146 | + } |
| 147 | + if recordType != "" { |
| 148 | + fmt.Printf(" Record Type: %s\n", recordType) |
| 149 | + } |
| 150 | + fmt.Println() |
| 151 | + |
| 152 | + // TODO: Implement actual database query |
| 153 | + color.Yellow(" Note: DNS monitoring table exists but no query method implemented yet.\n") |
| 154 | + color.Yellow(" This feature will be available once monitoring is actively running.\n") |
| 155 | + fmt.Println() |
| 156 | + |
| 157 | + _ = ctx |
| 158 | + _ = output |
| 159 | + |
| 160 | + return nil |
| 161 | + }, |
| 162 | +} |
| 163 | + |
| 164 | +// monitoringCertificatesCmd shows certificate expiry information |
| 165 | +var monitoringCertificatesCmd = &cobra.Command{ |
| 166 | + Use: "certificates", |
| 167 | + Short: "Show certificate expiry information", |
| 168 | + Long: `Display SSL/TLS certificates and their expiry status. |
| 169 | +
|
| 170 | +Examples: |
| 171 | + shells monitoring certificates expiring --days 30 |
| 172 | + shells monitoring certificates --domain example.com |
| 173 | + shells monitoring certificates --output json`, |
| 174 | + RunE: func(cmd *cobra.Command, args []string) error { |
| 175 | + domain, _ := cmd.Flags().GetString("domain") |
| 176 | + days, _ := cmd.Flags().GetInt("days") |
| 177 | + expiring, _ := cmd.Flags().GetBool("expiring") |
| 178 | + output, _ := cmd.Flags().GetString("output") |
| 179 | + |
| 180 | + store := GetStore() |
| 181 | + if store == nil { |
| 182 | + return fmt.Errorf("database not initialized") |
| 183 | + } |
| 184 | + |
| 185 | + ctx := GetContext() |
| 186 | + |
| 187 | + fmt.Println() |
| 188 | + color.Cyan("═══ SSL/TLS Certificates ═══") |
| 189 | + |
| 190 | + if domain != "" { |
| 191 | + fmt.Printf(" Domain: %s\n", domain) |
| 192 | + } |
| 193 | + if expiring { |
| 194 | + fmt.Printf(" Expiring within: %d days\n", days) |
| 195 | + } |
| 196 | + fmt.Println() |
| 197 | + |
| 198 | + // TODO: Implement actual database query |
| 199 | + color.Yellow(" Note: Certificate monitoring table exists but no query method implemented yet.\n") |
| 200 | + color.Yellow(" This feature will be available once monitoring is actively running.\n") |
| 201 | + fmt.Println() |
| 202 | + |
| 203 | + _ = ctx |
| 204 | + _ = output |
| 205 | + |
| 206 | + return nil |
| 207 | + }, |
| 208 | +} |
| 209 | + |
| 210 | +// monitoringGitChangesCmd shows Git repository changes |
| 211 | +var monitoringGitChangesCmd = &cobra.Command{ |
| 212 | + Use: "git-changes <repo-url>", |
| 213 | + Short: "Show Git repository changes", |
| 214 | + Long: `Display changes detected in Git repositories. |
| 215 | +
|
| 216 | +Examples: |
| 217 | + shells monitoring git-changes https://github.com/example/repo |
| 218 | + shells monitoring git-changes https://github.com/example/repo --since 7d`, |
| 219 | + Args: cobra.ExactArgs(1), |
| 220 | + RunE: func(cmd *cobra.Command, args []string) error { |
| 221 | + repoURL := args[0] |
| 222 | + sinceDuration, _ := cmd.Flags().GetString("since") |
| 223 | + output, _ := cmd.Flags().GetString("output") |
| 224 | + |
| 225 | + store := GetStore() |
| 226 | + if store == nil { |
| 227 | + return fmt.Errorf("database not initialized") |
| 228 | + } |
| 229 | + |
| 230 | + ctx := GetContext() |
| 231 | + |
| 232 | + var since time.Time |
| 233 | + if sinceDuration != "" { |
| 234 | + duration, err := parseDuration(sinceDuration) |
| 235 | + if err != nil { |
| 236 | + return fmt.Errorf("invalid duration: %w", err) |
| 237 | + } |
| 238 | + since = time.Now().Add(-duration) |
| 239 | + } |
| 240 | + |
| 241 | + fmt.Println() |
| 242 | + color.Cyan("═══ Git Changes: %s ═══", repoURL) |
| 243 | + |
| 244 | + if sinceDuration != "" { |
| 245 | + fmt.Printf(" Since: %s (from %s)\n", sinceDuration, since.Format("2006-01-02")) |
| 246 | + } |
| 247 | + fmt.Println() |
| 248 | + |
| 249 | + // TODO: Implement actual database query |
| 250 | + color.Yellow(" Note: Git monitoring table exists but no query method implemented yet.\n") |
| 251 | + color.Yellow(" This feature will be available once monitoring is actively running.\n") |
| 252 | + fmt.Println() |
| 253 | + |
| 254 | + _ = ctx |
| 255 | + _ = output |
| 256 | + |
| 257 | + return nil |
| 258 | + }, |
| 259 | +} |
| 260 | + |
| 261 | +// monitoringWebChangesCmd shows website change detection |
| 262 | +var monitoringWebChangesCmd = &cobra.Command{ |
| 263 | + Use: "web-changes <url>", |
| 264 | + Short: "Show website change detection", |
| 265 | + Long: `Display changes detected on websites. |
| 266 | +
|
| 267 | +Examples: |
| 268 | + shells monitoring web-changes https://example.com |
| 269 | + shells monitoring web-changes https://example.com --since 7d`, |
| 270 | + Args: cobra.ExactArgs(1), |
| 271 | + RunE: func(cmd *cobra.Command, args []string) error { |
| 272 | + url := args[0] |
| 273 | + sinceDuration, _ := cmd.Flags().GetString("since") |
| 274 | + output, _ := cmd.Flags().GetString("output") |
| 275 | + |
| 276 | + store := GetStore() |
| 277 | + if store == nil { |
| 278 | + return fmt.Errorf("database not initialized") |
| 279 | + } |
| 280 | + |
| 281 | + ctx := GetContext() |
| 282 | + |
| 283 | + var since time.Time |
| 284 | + if sinceDuration != "" { |
| 285 | + duration, err := parseDuration(sinceDuration) |
| 286 | + if err != nil { |
| 287 | + return fmt.Errorf("invalid duration: %w", err) |
| 288 | + } |
| 289 | + since = time.Now().Add(-duration) |
| 290 | + } |
| 291 | + |
| 292 | + fmt.Println() |
| 293 | + color.Cyan("═══ Web Changes: %s ═══", url) |
| 294 | + |
| 295 | + if sinceDuration != "" { |
| 296 | + fmt.Printf(" Since: %s (from %s)\n", sinceDuration, since.Format("2006-01-02")) |
| 297 | + } |
| 298 | + fmt.Println() |
| 299 | + |
| 300 | + // TODO: Implement actual database query |
| 301 | + color.Yellow(" Note: Web monitoring table exists but no query method implemented yet.\n") |
| 302 | + color.Yellow(" This feature will be available once monitoring is actively running.\n") |
| 303 | + fmt.Println() |
| 304 | + |
| 305 | + _ = ctx |
| 306 | + _ = output |
| 307 | + |
| 308 | + return nil |
| 309 | + }, |
| 310 | +} |
| 311 | + |
| 312 | +func init() { |
| 313 | + // Alerts command flags |
| 314 | + monitoringAlertsCmd.Flags().String("target", "", "Filter by target") |
| 315 | + monitoringAlertsCmd.Flags().String("severity", "", "Filter by severity (critical, high, medium, low)") |
| 316 | + monitoringAlertsCmd.Flags().String("since", "", "Show alerts since duration (e.g., 7d, 24h)") |
| 317 | + monitoringAlertsCmd.Flags().Int("limit", 100, "Maximum number of alerts to show") |
| 318 | + monitoringAlertsCmd.Flags().StringP("output", "o", "text", "Output format (text, json)") |
| 319 | + |
| 320 | + // DNS changes command flags |
| 321 | + monitoringDNSChangesCmd.Flags().String("since", "", "Show changes since duration") |
| 322 | + monitoringDNSChangesCmd.Flags().String("record-type", "", "Filter by DNS record type (A, AAAA, MX, TXT, etc.)") |
| 323 | + monitoringDNSChangesCmd.Flags().StringP("output", "o", "text", "Output format (text, json)") |
| 324 | + |
| 325 | + // Certificates command flags |
| 326 | + monitoringCertificatesCmd.Flags().String("domain", "", "Filter by domain") |
| 327 | + monitoringCertificatesCmd.Flags().Bool("expiring", false, "Show only expiring certificates") |
| 328 | + monitoringCertificatesCmd.Flags().Int("days", 30, "Days until expiry (with --expiring)") |
| 329 | + monitoringCertificatesCmd.Flags().StringP("output", "o", "text", "Output format (text, json)") |
| 330 | + |
| 331 | + // Git changes command flags |
| 332 | + monitoringGitChangesCmd.Flags().String("since", "", "Show changes since duration") |
| 333 | + monitoringGitChangesCmd.Flags().StringP("output", "o", "text", "Output format (text, json)") |
| 334 | + |
| 335 | + // Web changes command flags |
| 336 | + monitoringWebChangesCmd.Flags().String("since", "", "Show changes since duration") |
| 337 | + monitoringWebChangesCmd.Flags().StringP("output", "o", "text", "Output format (text, json)") |
| 338 | +} |
0 commit comments