Skip to content

Commit

Permalink
feat: aws integration (#967)
Browse files Browse the repository at this point in the history
* chore: updated deps

Signed-off-by: Alex Jones <alexsimonjones@gmail.com>

* chore: adding aws types

Signed-off-by: Alex Jones <alexsimonjones@gmail.com>

* chore: first cut

Signed-off-by: Alex Jones <alexsimonjones@gmail.com>

* chore: first pass at aws integration with EKS

Signed-off-by: Alex Jones <alexsimonjones@gmail.com>

* chore: fixed linting

Signed-off-by: Alex Jones <alexsimonjones@gmail.com>

* chore: updated wording based on PR

Signed-off-by: Alex Jones <alexsimonjones@gmail.com>

* chore: improved the kubeconfig

Signed-off-by: Alex Jones <alexsimonjones@gmail.com>

---------

Signed-off-by: Alex Jones <alexsimonjones@gmail.com>
  • Loading branch information
AlexsJones authored Feb 26, 2024
1 parent 6103c96 commit a81377f
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 4 deletions.
5 changes: 1 addition & 4 deletions cmd/integration/activate.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ import (
"github.com/spf13/viper"
)

var (
skipInstall bool
)
var skipInstall bool

// activateCmd represents the activate command
var activateCmd = &cobra.Command{
Expand Down Expand Up @@ -56,5 +54,4 @@ var activateCmd = &cobra.Command{
func init() {
IntegrationCmd.AddCommand(activateCmd)
activateCmd.Flags().BoolVarP(&skipInstall, "no-install", "s", false, "Only activate the integration filter without installing the filter (for example, if that filter plugin is already deployed in cluster, we do not need to re-install it again)")

}
85 changes: 85 additions & 0 deletions pkg/integration/aws/aws.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package aws

import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/k8sgpt-ai/k8sgpt/pkg/common"
"github.com/spf13/viper"
"os"
)

type AWS struct {
sess *session.Session
}

func (a *AWS) Deploy(namespace string) error {

return nil
}

func (a *AWS) UnDeploy(namespace string) error {
a.sess = nil
return nil
}

func (a *AWS) AddAnalyzer(mergedMap *map[string]common.IAnalyzer) {
// Check for AWS credentials in the environment
// https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html
if os.Getenv("AWS_ACCESS_KEY_ID") == "" || os.Getenv("AWS_SECRET_ACCESS_KEY") == "" {
panic("AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY must be set in the environment")
}

sess := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
Config: aws.Config{},
}))
a.sess = sess
(*mergedMap)["EKS"] = &EKSAnalyzer{
session: a.sess,
}
}

func (a *AWS) GetAnalyzerName() []string {

return []string{"EKS"}
}

func (a *AWS) GetNamespace() (string, error) {

return "", nil
}

func (a *AWS) OwnsAnalyzer(s string) bool {
for _, az := range a.GetAnalyzerName() {
if s == az {
return true
}
}
return false
}

func (a *AWS) isFilterActive() bool {
activeFilters := viper.GetStringSlice("active_filters")

for _, filter := range a.GetAnalyzerName() {
for _, af := range activeFilters {
if af == filter {
return true
}
}
}

return false
}

func (a *AWS) IsActivate() bool {
if a.isFilterActive() {
return true
} else {
return false
}
}

func NewAWS() *AWS {
return &AWS{}
}
80 changes: 80 additions & 0 deletions pkg/integration/aws/eks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package aws

import (
"errors"
"github.com/spf13/viper"
"os"
"path/filepath"
"strings"

"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/eks"
"github.com/k8sgpt-ai/k8sgpt/pkg/common"
"k8s.io/client-go/tools/clientcmd"
)

type EKSAnalyzer struct {
session *session.Session
}

func (e *EKSAnalyzer) Analyze(analysis common.Analyzer) ([]common.Result, error) {
var cr []common.Result = []common.Result{}
_ = map[string]common.PreAnalysis{}
svc := eks.New(e.session)
// Get the name of the current cluster
var kubeconfig string
kubeconfigFromPath := viper.GetString("kubeconfig")
if kubeconfigFromPath != "" {
kubeconfig = kubeconfigFromPath
} else {
kubeconfig = filepath.Join(os.Getenv("HOME"), ".kube", "config")
}
config, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
&clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfig},
&clientcmd.ConfigOverrides{
CurrentContext: "",
}).RawConfig()
if err != nil {
return cr, err
}
currentConfig := config.CurrentContext

if !strings.Contains(currentConfig, "eks") {
return cr, errors.New("EKS cluster was not detected")
}

input := &eks.ListClustersInput{}
result, err := svc.ListClusters(input)
if err != nil {
return cr, err
}
for _, cluster := range result.Clusters {
// describe the cluster
if !strings.Contains(currentConfig, *cluster) {
continue
}
input := &eks.DescribeClusterInput{
Name: cluster,
}
result, err := svc.DescribeCluster(input)
if err != nil {
return cr, err
}
if len(result.Cluster.Health.Issues) > 0 {
for _, issue := range result.Cluster.Health.Issues {
err := make([]common.Failure, 0)
err = append(err, common.Failure{
Text: issue.String(),
KubernetesDoc: "",
Sensitive: nil,
})
cr = append(cr, common.Result{
Kind: "EKS",
Name: "AWS/EKS",
Error: err,
})
}
}
}
return cr, nil
}
2 changes: 2 additions & 0 deletions pkg/integration/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package integration
import (
"errors"
"fmt"
"github.com/k8sgpt-ai/k8sgpt/pkg/integration/aws"

"github.com/k8sgpt-ai/k8sgpt/pkg/common"
"github.com/k8sgpt-ai/k8sgpt/pkg/integration/prometheus"
Expand Down Expand Up @@ -47,6 +48,7 @@ type Integration struct {
var integrations = map[string]IIntegration{
"trivy": trivy.NewTrivy(),
"prometheus": prometheus.NewPrometheus(),
"aws": aws.NewAWS(),
}

func NewIntegration() *Integration {
Expand Down

0 comments on commit a81377f

Please sign in to comment.