mirror of
https://github.com/k8sgpt-ai/k8sgpt.git
synced 2025-09-12 13:27:06 +00:00
feat: configauditreport (#609)
* feat: adding config audit report Signed-off-by: Alex Jones <alex@alexs-mbp.tailddc26.ts.net> * feat: adding config audit report Signed-off-by: Alex Jones <alex@alexs-mbp.tailddc26.ts.net> * feat: adding config audit report analyzer mechnics Signed-off-by: Alex Jones <alexsimonjones@gmail.com> Signed-off-by: Alex Jones <alex@alexs-mbp.tailddc26.ts.net> * feat: adding config audit report analyzer mechnics Signed-off-by: Alex Jones <alexsimonjones@gmail.com> Signed-off-by: Alex Jones <alex@alexs-mbp.tailddc26.ts.net> * chore: updated naming Signed-off-by: Alex Jones <alex@alexs-mbp.tailddc26.ts.net> * chore: updated naming Signed-off-by: Alex Jones <alex@alexs-mbp.tailddc26.ts.net> * chore: updated var names Signed-off-by: Alex Jones <alex@alexs-mbp.tailddc26.ts.net> --------- Signed-off-by: Alex Jones <alex@alexs-mbp.tailddc26.ts.net> Signed-off-by: Alex Jones <alexsimonjones@gmail.com> Co-authored-by: Alex Jones <alex@alexs-mbp.tailddc26.ts.net>
This commit is contained in:
@@ -61,7 +61,7 @@ func ListFilters() ([]string, []string, []string) {
|
|||||||
for k := range additionalAnalyzerMap {
|
for k := range additionalAnalyzerMap {
|
||||||
additionalKeys = append(additionalKeys, k)
|
additionalKeys = append(additionalKeys, k)
|
||||||
}
|
}
|
||||||
|
// Current analyzer
|
||||||
integrationProvider := integration.NewIntegration()
|
integrationProvider := integration.NewIntegration()
|
||||||
var integrationAnalyzers []string
|
var integrationAnalyzers []string
|
||||||
|
|
||||||
@@ -73,7 +73,10 @@ func ListFilters() ([]string, []string, []string) {
|
|||||||
fmt.Println(color.RedString(err.Error()))
|
fmt.Println(color.RedString(err.Error()))
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
integrationAnalyzers = append(integrationAnalyzers, in.GetAnalyzerName())
|
for _, analyzers := range in.GetAnalyzerName() {
|
||||||
|
|
||||||
|
integrationAnalyzers = append(integrationAnalyzers, analyzers)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -59,6 +59,7 @@ type PreAnalysis struct {
|
|||||||
MutatingWebhook regv1.MutatingWebhookConfiguration
|
MutatingWebhook regv1.MutatingWebhookConfiguration
|
||||||
// Integrations
|
// Integrations
|
||||||
TrivyVulnerabilityReport trivy.VulnerabilityReport
|
TrivyVulnerabilityReport trivy.VulnerabilityReport
|
||||||
|
TrivyConfigAuditReport trivy.ConfigAuditReport
|
||||||
}
|
}
|
||||||
|
|
||||||
type Result struct {
|
type Result struct {
|
||||||
|
@@ -35,7 +35,7 @@ type IIntegration interface {
|
|||||||
// RemoveAnalyzer removes an analyzer from the cluster
|
// RemoveAnalyzer removes an analyzer from the cluster
|
||||||
RemoveAnalyzer() error
|
RemoveAnalyzer() error
|
||||||
|
|
||||||
GetAnalyzerName() string
|
GetAnalyzerName() []string
|
||||||
|
|
||||||
IsActivate() bool
|
IsActivate() bool
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,11 @@ func (*Integration) Activate(name string, namespace string, activeFilters []stri
|
|||||||
return errors.New("integration not found")
|
return errors.New("integration not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
mergedFilters := append(activeFilters, integrations[name].GetAnalyzerName())
|
mergedFilters := activeFilters
|
||||||
|
|
||||||
|
for _, integrationAnalyzer := range integrations[name].GetAnalyzerName() {
|
||||||
|
mergedFilters = append(mergedFilters, integrationAnalyzer)
|
||||||
|
}
|
||||||
|
|
||||||
uniqueFilters, dupplicatedFilters := util.RemoveDuplicates(mergedFilters)
|
uniqueFilters, dupplicatedFilters := util.RemoveDuplicates(mergedFilters)
|
||||||
|
|
||||||
@@ -108,12 +112,16 @@ func (*Integration) Deactivate(name string, namespace string) error {
|
|||||||
// This might be a bad idea, but we cannot reference analyzer here
|
// This might be a bad idea, but we cannot reference analyzer here
|
||||||
foundFilter := false
|
foundFilter := false
|
||||||
for i, v := range activeFilters {
|
for i, v := range activeFilters {
|
||||||
if v == integrations[name].GetAnalyzerName() {
|
|
||||||
|
for _, intanal := range integrations[name].GetAnalyzerName() {
|
||||||
|
if v == intanal {
|
||||||
foundFilter = true
|
foundFilter = true
|
||||||
activeFilters = append(activeFilters[:i], activeFilters[i+1:]...)
|
activeFilters = append(activeFilters[:i], activeFilters[i+1:]...)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
if !foundFilter {
|
if !foundFilter {
|
||||||
color.Red("Ingregation %s does not exist in configuration file. Please use k8sgpt integration add.", name)
|
color.Red("Ingregation %s does not exist in configuration file. Please use k8sgpt integration add.", name)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@@ -23,10 +23,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type TrivyAnalyzer struct {
|
type TrivyAnalyzer struct {
|
||||||
|
vulernabilityReportAnalysis bool
|
||||||
|
configAuditReportAnalysis bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (TrivyAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
|
func (TrivyAnalyzer) analyzeVulnerabilityReports(a common.Analyzer) ([]common.Result, error) {
|
||||||
|
|
||||||
// Get all trivy VulnerabilityReports
|
// Get all trivy VulnerabilityReports
|
||||||
result := &v1alpha1.VulnerabilityReportList{}
|
result := &v1alpha1.VulnerabilityReportList{}
|
||||||
|
|
||||||
@@ -84,4 +85,85 @@ func (TrivyAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return a.Results, nil
|
return a.Results, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t TrivyAnalyzer) analyzeConfigAuditReports(a common.Analyzer) ([]common.Result, error) {
|
||||||
|
// Get all trivy VulnerabilityReports
|
||||||
|
result := &v1alpha1.ConfigAuditReportList{}
|
||||||
|
|
||||||
|
config := a.Client.GetConfig()
|
||||||
|
// Add group version to sceheme
|
||||||
|
config.ContentConfig.GroupVersion = &v1alpha1.SchemeGroupVersion
|
||||||
|
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||||
|
config.APIPath = "/apis"
|
||||||
|
|
||||||
|
restClient, err := rest.UnversionedRESTClientFor(config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = restClient.Get().Resource("configauditreports").Do(a.Context).Into(result)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find criticals and get CVE
|
||||||
|
var preAnalysis = map[string]common.PreAnalysis{}
|
||||||
|
|
||||||
|
for _, report := range result.Items {
|
||||||
|
|
||||||
|
var failures []common.Failure
|
||||||
|
if report.Report.Summary.HighCount > 0 {
|
||||||
|
|
||||||
|
failures = append(failures, common.Failure{
|
||||||
|
Text: fmt.Sprintf("Config audit report %s detected at least one high issue", report.Name),
|
||||||
|
Sensitive: []common.Sensitive{},
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
if len(failures) > 0 {
|
||||||
|
preAnalysis[fmt.Sprintf("%s/%s", report.Labels["trivy-operator.resource.namespace"],
|
||||||
|
report.Labels["trivy-operator.resource.name"])] = common.PreAnalysis{
|
||||||
|
TrivyConfigAuditReport: report,
|
||||||
|
FailureDetails: failures,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value := range preAnalysis {
|
||||||
|
var currentAnalysis = common.Result{
|
||||||
|
Kind: "ConfigAuditReport",
|
||||||
|
Name: key,
|
||||||
|
Error: value.FailureDetails,
|
||||||
|
}
|
||||||
|
|
||||||
|
parent, _ := util.GetParent(a.Client, value.TrivyConfigAuditReport.ObjectMeta)
|
||||||
|
currentAnalysis.ParentObject = parent
|
||||||
|
a.Results = append(a.Results, currentAnalysis)
|
||||||
|
}
|
||||||
|
|
||||||
|
return a.Results, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t TrivyAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
|
||||||
|
|
||||||
|
if t.vulernabilityReportAnalysis {
|
||||||
|
common := make([]common.Result, 0)
|
||||||
|
vresult, err := t.analyzeVulnerabilityReports(a)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
common = append(common, vresult...)
|
||||||
|
return common, nil
|
||||||
|
}
|
||||||
|
if t.configAuditReportAnalysis {
|
||||||
|
common := make([]common.Result, 0)
|
||||||
|
cresult, err := t.analyzeConfigAuditReports(a)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
common = append(common, cresult...)
|
||||||
|
return common, nil
|
||||||
|
}
|
||||||
|
return make([]common.Result, 0), nil
|
||||||
}
|
}
|
||||||
|
@@ -44,8 +44,11 @@ func NewTrivy() *Trivy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Trivy) GetAnalyzerName() string {
|
func (t *Trivy) GetAnalyzerName() []string {
|
||||||
return "VulnerabilityReport"
|
return []string{
|
||||||
|
"VulnerabilityReport",
|
||||||
|
"ConfigAuditReport",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Trivy) Deploy(namespace string) error {
|
func (t *Trivy) Deploy(namespace string) error {
|
||||||
@@ -107,10 +110,16 @@ func (t *Trivy) IsActivate() bool {
|
|||||||
|
|
||||||
func (t *Trivy) AddAnalyzer(mergedMap *map[string]common.IAnalyzer) {
|
func (t *Trivy) AddAnalyzer(mergedMap *map[string]common.IAnalyzer) {
|
||||||
|
|
||||||
(*mergedMap)["VulnerabilityReport"] = &TrivyAnalyzer{}
|
(*mergedMap)["VulnerabilityReport"] = &TrivyAnalyzer{
|
||||||
|
vulernabilityReportAnalysis: true,
|
||||||
|
}
|
||||||
|
(*mergedMap)["ConfigAuditReport"] = &TrivyAnalyzer{
|
||||||
|
configAuditReportAnalysis: true,
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Trivy) RemoveAnalyzer() error {
|
func (t *Trivy) RemoveAnalyzer() error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user