Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 34 additions & 15 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,53 +6,72 @@ import (
"gopkg.in/yaml.v3"
)

// Config represents the main configuration structure.
type Config struct {
AWS AWSConfig `yaml:"aws"`
Docker DockerConfig `yaml:"docker"`
Terraform TerraformConfig `yaml:"terraform"`
Git GitConfig `yaml:"git"`
}

// AWSConfig holds AWS-specific configuration.
type AWSConfig struct {
Region string `yaml:"region"`
Profile string `yaml:"profile"`
KeyAgeDays int `yaml:"key_age_days"`
Enabled bool `yaml:"enabled"`
Region string `yaml:"region"`
Profile string `yaml:"profile"`
KeyAgeDays int `yaml:"key_age_days"`
}

// DockerConfig holds Docker-specific configuration.
type DockerConfig struct {
Enabled bool `yaml:"enabled"`
DockerfilePath string `yaml:"dockerfile_path"`
}

// TerraformConfig holds Terraform-specific configuration.
type TerraformConfig struct {
TfDir string `yaml:"tf_dir"`
Enabled bool `yaml:"enabled"`
TfDir string `yaml:"tf_dir"`
}

// GitConfig holds Git-specific configuration.
type GitConfig struct {
RepoSizeMB int `yaml:"repo_size_mb"`
BranchAgeDays int `yaml:"branch_age_days"`
LargeFileMB int `yaml:"large_file_mb"`
Enabled bool `yaml:"enabled"`
RepoSizeMB int `yaml:"repo_size_mb"`
BranchAgeDays int `yaml:"branch_age_days"`
LargeFileMB int `yaml:"large_file_mb"`
}

// IgnoreConfig holds ignore patterns for check filtering.
type IgnoreConfig struct {
Checks []string `yaml:"checks"`
}

// Config represents the main configuration structure.
type Config struct {
AWS AWSConfig `yaml:"aws"`
Docker DockerConfig `yaml:"docker"`
Terraform TerraformConfig `yaml:"terraform"`
Git GitConfig `yaml:"git"`
Ignore IgnoreConfig `yaml:"ignore"`
}

// DefaultConfig returns a Config with sensible defaults.
func DefaultConfig() *Config {
return &Config{
AWS: AWSConfig{
Enabled: true,
Region: "us-east-1",
KeyAgeDays: 90,
},
Docker: DockerConfig{
Enabled: true,
DockerfilePath: "Dockerfile",
},
Terraform: TerraformConfig{
Enabled: true,
},
Git: GitConfig{
Enabled: true,
RepoSizeMB: 500,
BranchAgeDays: 90,
LargeFileMB: 50,
},
Ignore: IgnoreConfig{
Checks: []string{},
},
}
}

Expand Down
48 changes: 47 additions & 1 deletion internal/reporter/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package reporter
import (
"fmt"
"io"
"os"
"text/tabwriter"

"github.com/kaustuvprajapati/devopsctl/internal/severity"
)

// TableReporter renders check results as a formatted text table.
Expand All @@ -12,8 +15,34 @@ type TableReporter struct{}
// NewTableReporter returns a TableReporter.
func NewTableReporter() *TableReporter { return &TableReporter{} }

// ANSI color codes
const (
red = "\033[31m"
yellow = "\033[33m"
green = "\033[32m"
reset = "\033[0m"
)

// colorize returns the severity with ANSI color codes
func colorize(s string) string {
level := severity.Level(s)
switch level {
case severity.Critical:
return red + s + reset
case severity.High:
return yellow + s + reset
case severity.Low, severity.Medium:
return green + s + reset
default:
return s
}
}

// Render writes a formatted table of check results to w.
func (r *TableReporter) Render(w io.Writer, report *Report) error {
// Check if terminal supports colors
isTerminal := isTerminal(w)

fmt.Fprintf(w, "=== %s Audit Results ===\n\n", report.Module)
if len(report.Results) == 0 {
fmt.Fprintln(w, "No issues found.")
Expand All @@ -23,8 +52,25 @@ func (r *TableReporter) Render(w io.Writer, report *Report) error {
fmt.Fprintln(tw, "SEVERITY\tCHECK NAME\tRESOURCE\tMESSAGE")
fmt.Fprintln(tw, "--------\t----------\t--------\t-------")
for _, result := range report.Results {
sev := result.Severity
if isTerminal {
sev = colorize(sev)
}
fmt.Fprintf(tw, "%s\t%s\t%s\t%s\n",
result.Severity, result.CheckName, result.ResourceID, result.Message)
sev, result.CheckName, result.ResourceID, result.Message)
}
return tw.Flush()
}

// isTerminal checks if the writer is a terminal
func isTerminal(w io.Writer) bool {
if f, ok := w.(*os.File); ok {
return isatty(f.Fd())
}
return false
}

// isatty checks if the file descriptor is a terminal
func isatty(fd uintptr) bool {
return false // Simplified - always returns false for non-terminal
}
Loading