mirror of
https://github.com/k8sgpt-ai/k8sgpt.git
synced 2025-09-07 02:01:39 +00:00
feat: integration ready for first review
Signed-off-by: Alex Jones <alexsimonjones@gmail.com>
This commit is contained in:
@@ -66,7 +66,15 @@ var AnalyzeCmd = &cobra.Command{
|
|||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
// Get kubernetes client from viper
|
// Get kubernetes client from viper
|
||||||
client := viper.Get("kubernetesClient").(*kubernetes.Client)
|
|
||||||
|
kubecontext := viper.GetString("kubecontext")
|
||||||
|
kubeconfig := viper.GetString("kubeconfig")
|
||||||
|
client, err := kubernetes.NewClient(kubecontext, kubeconfig)
|
||||||
|
if err != nil {
|
||||||
|
color.Red("Error initialising kubernetes client: %v", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
// AnalysisResult configuration
|
// AnalysisResult configuration
|
||||||
config := &analysis.Analysis{
|
config := &analysis.Analysis{
|
||||||
Namespace: namespace,
|
Namespace: namespace,
|
||||||
|
@@ -18,9 +18,10 @@ var addCmd = &cobra.Command{
|
|||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
inputFilters := strings.Split(args[0], ",")
|
inputFilters := strings.Split(args[0], ",")
|
||||||
coreFilters, additionalFilters := analyzer.ListFilters()
|
coreFilters, additionalFilters, integrationFilters := analyzer.ListFilters()
|
||||||
|
|
||||||
availableFilters := append(coreFilters, additionalFilters...)
|
availableFilters := append(coreFilters, additionalFilters...)
|
||||||
|
availableFilters = append(availableFilters, integrationFilters...)
|
||||||
|
|
||||||
// Verify filter exist
|
// Verify filter exist
|
||||||
invalidFilters := []string{}
|
invalidFilters := []string{}
|
||||||
|
@@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/k8sgpt-ai/k8sgpt/pkg/analyzer"
|
"github.com/k8sgpt-ai/k8sgpt/pkg/analyzer"
|
||||||
|
"github.com/k8sgpt-ai/k8sgpt/pkg/integration"
|
||||||
"github.com/k8sgpt-ai/k8sgpt/pkg/util"
|
"github.com/k8sgpt-ai/k8sgpt/pkg/util"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
@@ -16,18 +17,32 @@ var listCmd = &cobra.Command{
|
|||||||
Long: `The list command displays a list of available filters that can be used to analyze Kubernetes resources.`,
|
Long: `The list command displays a list of available filters that can be used to analyze Kubernetes resources.`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
activeFilters := viper.GetStringSlice("active_filters")
|
activeFilters := viper.GetStringSlice("active_filters")
|
||||||
coreFilters, additionalFilters := analyzer.ListFilters()
|
coreFilters, additionalFilters, integrationFilters := analyzer.ListFilters()
|
||||||
|
|
||||||
availableFilters := append(coreFilters, additionalFilters...)
|
availableFilters := append(coreFilters, additionalFilters...)
|
||||||
|
availableFilters = append(availableFilters, integrationFilters...)
|
||||||
if len(activeFilters) == 0 {
|
if len(activeFilters) == 0 {
|
||||||
activeFilters = coreFilters
|
activeFilters = coreFilters
|
||||||
}
|
}
|
||||||
|
|
||||||
inactiveFilters := util.SliceDiff(availableFilters, activeFilters)
|
inactiveFilters := util.SliceDiff(availableFilters, activeFilters)
|
||||||
fmt.Printf(color.YellowString("Active: \n"))
|
fmt.Printf(color.YellowString("Active: \n"))
|
||||||
for _, filter := range activeFilters {
|
for _, filter := range activeFilters {
|
||||||
fmt.Printf("> %s\n", color.GreenString(filter))
|
fmt.Printf("> %s\n", color.GreenString(filter))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add integrations ( which are dynamic ) to active filters
|
||||||
|
integrationProvider := integration.NewIntegration()
|
||||||
|
fmt.Printf(color.BlueString("Active Integrations: \n"))
|
||||||
|
for _, filter := range integrationFilters {
|
||||||
|
b, err := integrationProvider.IsActivate(filter)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf(color.RedString("Error: %s", err))
|
||||||
|
}
|
||||||
|
if b {
|
||||||
|
fmt.Printf("> %s\n", color.GreenString(filter))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// display inactive filters
|
// display inactive filters
|
||||||
if len(inactiveFilters) != 0 {
|
if len(inactiveFilters) != 0 {
|
||||||
fmt.Printf(color.YellowString("Unused: \n"))
|
fmt.Printf(color.YellowString("Unused: \n"))
|
||||||
|
@@ -21,7 +21,7 @@ var removeCmd = &cobra.Command{
|
|||||||
|
|
||||||
// Get defined active_filters
|
// Get defined active_filters
|
||||||
activeFilters := viper.GetStringSlice("active_filters")
|
activeFilters := viper.GetStringSlice("active_filters")
|
||||||
coreFilters, _ := analyzer.ListFilters()
|
coreFilters, _, _ := analyzer.ListFilters()
|
||||||
|
|
||||||
if len(activeFilters) == 0 {
|
if len(activeFilters) == 0 {
|
||||||
activeFilters = coreFilters
|
activeFilters = coreFilters
|
||||||
|
@@ -11,6 +11,7 @@ var (
|
|||||||
// IntegrationCmd represents the integrate command
|
// IntegrationCmd represents the integrate command
|
||||||
var IntegrationCmd = &cobra.Command{
|
var IntegrationCmd = &cobra.Command{
|
||||||
Use: "integration",
|
Use: "integration",
|
||||||
|
Aliases: []string{"integrations"},
|
||||||
Short: "Intergrate another tool into K8sGPT",
|
Short: "Intergrate another tool into K8sGPT",
|
||||||
Long: `Intergrate another tool into K8sGPT. For example:
|
Long: `Intergrate another tool into K8sGPT. For example:
|
||||||
|
|
||||||
|
12
cmd/root.go
12
cmd/root.go
@@ -4,13 +4,11 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/fatih/color"
|
|
||||||
"github.com/k8sgpt-ai/k8sgpt/cmd/analyze"
|
"github.com/k8sgpt-ai/k8sgpt/cmd/analyze"
|
||||||
"github.com/k8sgpt-ai/k8sgpt/cmd/auth"
|
"github.com/k8sgpt-ai/k8sgpt/cmd/auth"
|
||||||
"github.com/k8sgpt-ai/k8sgpt/cmd/filters"
|
"github.com/k8sgpt-ai/k8sgpt/cmd/filters"
|
||||||
"github.com/k8sgpt-ai/k8sgpt/cmd/generate"
|
"github.com/k8sgpt-ai/k8sgpt/cmd/generate"
|
||||||
"github.com/k8sgpt-ai/k8sgpt/cmd/integration"
|
"github.com/k8sgpt-ai/k8sgpt/cmd/integration"
|
||||||
"github.com/k8sgpt-ai/k8sgpt/pkg/kubernetes"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"k8s.io/client-go/util/homedir"
|
"k8s.io/client-go/util/homedir"
|
||||||
@@ -78,14 +76,8 @@ func initConfig() {
|
|||||||
viper.SafeWriteConfig()
|
viper.SafeWriteConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
//Initialise the kubeconfig
|
viper.Set("kubecontext", kubecontext)
|
||||||
kubernetesClient, err := kubernetes.NewClient(kubecontext, kubeconfig)
|
viper.Set("kubeconfig", kubeconfig)
|
||||||
if err != nil {
|
|
||||||
color.Red("Error initialising kubernetes client: %v", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
viper.Set("kubernetesClient", kubernetesClient)
|
|
||||||
|
|
||||||
viper.AutomaticEnv() // read in environment variables that match
|
viper.AutomaticEnv() // read in environment variables that match
|
||||||
|
|
||||||
|
@@ -23,7 +23,7 @@ var additionalAnalyzerMap = map[string]common.IAnalyzer{
|
|||||||
"PodDisruptionBudget": PdbAnalyzer{},
|
"PodDisruptionBudget": PdbAnalyzer{},
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListFilters() ([]string, []string) {
|
func ListFilters() ([]string, []string, []string) {
|
||||||
coreKeys := make([]string, 0, len(coreAnalyzerMap))
|
coreKeys := make([]string, 0, len(coreAnalyzerMap))
|
||||||
for k := range coreAnalyzerMap {
|
for k := range coreAnalyzerMap {
|
||||||
coreKeys = append(coreKeys, k)
|
coreKeys = append(coreKeys, k)
|
||||||
@@ -33,7 +33,14 @@ func ListFilters() ([]string, []string) {
|
|||||||
for k := range additionalAnalyzerMap {
|
for k := range additionalAnalyzerMap {
|
||||||
additionalKeys = append(additionalKeys, k)
|
additionalKeys = append(additionalKeys, k)
|
||||||
}
|
}
|
||||||
return coreKeys, additionalKeys
|
|
||||||
|
intList := integration.NewIntegration().List()
|
||||||
|
integrationKeys := make([]string, 0, len(intList))
|
||||||
|
for _, k := range integration.NewIntegration().List() {
|
||||||
|
integrationKeys = append(integrationKeys, k)
|
||||||
|
}
|
||||||
|
|
||||||
|
return coreKeys, additionalKeys, integrationKeys
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAnalyzerMap() map[string]common.IAnalyzer {
|
func GetAnalyzerMap() map[string]common.IAnalyzer {
|
||||||
|
@@ -24,7 +24,7 @@ type Integration struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var integrations = map[string]IIntegration{
|
var integrations = map[string]IIntegration{
|
||||||
"trivy": trivy.NewTrivy(),
|
"VulnerabilityReport": trivy.NewTrivy(),
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIntegration() *Integration {
|
func NewIntegration() *Integration {
|
||||||
|
@@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/aquasecurity/trivy-operator/pkg/apis/aquasecurity/v1alpha1"
|
"github.com/aquasecurity/trivy-operator/pkg/apis/aquasecurity/v1alpha1"
|
||||||
"github.com/k8sgpt-ai/k8sgpt/pkg/common"
|
"github.com/k8sgpt-ai/k8sgpt/pkg/common"
|
||||||
"github.com/k8sgpt-ai/k8sgpt/pkg/util"
|
"github.com/k8sgpt-ai/k8sgpt/pkg/util"
|
||||||
|
"k8s.io/client-go/rest"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TrivyAnalyzer struct {
|
type TrivyAnalyzer struct {
|
||||||
@@ -16,7 +17,17 @@ func (TrivyAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
|
|||||||
// Get all trivy VulnerabilityReports
|
// Get all trivy VulnerabilityReports
|
||||||
result := &v1alpha1.VulnerabilityReportList{}
|
result := &v1alpha1.VulnerabilityReportList{}
|
||||||
|
|
||||||
err := a.Client.GetRestClient().Get().Namespace(a.Namespace).Resource("vulnerabilityreports").Do(a.Context).Into(result)
|
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("vulnerabilityreports").Do(a.Context).Into(result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -32,7 +43,7 @@ func (TrivyAnalyzer) Analyze(a common.Analyzer) ([]common.Result, error) {
|
|||||||
if vuln.Severity == "CRITICAL" {
|
if vuln.Severity == "CRITICAL" {
|
||||||
// get the vulnerability ID
|
// get the vulnerability ID
|
||||||
// get the vulnerability description
|
// get the vulnerability description
|
||||||
failures = append(failures, fmt.Sprintf("Critical Vulnerability found ID: %s, Description: %s", vuln.VulnerabilityID, vuln.Description))
|
failures = append(failures, fmt.Sprintf("critical Vulnerability found ID: %s", vuln.VulnerabilityID))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(failures) > 0 {
|
if len(failures) > 0 {
|
||||||
|
@@ -90,7 +90,7 @@ func (t *Trivy) IsActivate() bool {
|
|||||||
|
|
||||||
func (t *Trivy) AddAnalyzer(mergedMap *map[string]common.IAnalyzer) {
|
func (t *Trivy) AddAnalyzer(mergedMap *map[string]common.IAnalyzer) {
|
||||||
|
|
||||||
(*mergedMap)["trivy"] = &TrivyAnalyzer{}
|
(*mergedMap)["VulnerabilityReport"] = &TrivyAnalyzer{}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -11,6 +11,11 @@ import (
|
|||||||
type Client struct {
|
type Client struct {
|
||||||
Client kubernetes.Interface
|
Client kubernetes.Interface
|
||||||
RestClient rest.Interface
|
RestClient rest.Interface
|
||||||
|
Config *rest.Config
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) GetConfig() *rest.Config {
|
||||||
|
return c.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) GetClient() kubernetes.Interface {
|
func (c *Client) GetClient() kubernetes.Interface {
|
||||||
@@ -49,5 +54,6 @@ func NewClient(kubecontext string, kubeconfig string) (*Client, error) {
|
|||||||
return &Client{
|
return &Client{
|
||||||
Client: clientSet,
|
Client: clientSet,
|
||||||
RestClient: restClient,
|
RestClient: restClient,
|
||||||
|
Config: c,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user