Skip to content

Commit

Permalink
Cloud selection screen (#25)
Browse files Browse the repository at this point in the history
* Add buttons to select between AWS and GCP

* Revert "Add buttons to select between AWS and GCP"

This reverts commit 3659d09.

* Add screen to select between multiple cloud provider

* add feature to go back to cloud selection screen

* Add gcp storage view

* Separate GCP and AWS resource screens

* Add header in gcp

* Add cloud selection flags

* Fix page switching

* Add sub-commands to select aws or gcp

* Fix csv creation for gcp resources

* Seperate gcp and aws commands and validate aws profile and region

* Fix tests

* storge partial commit

* Implement folder view in storage resource

* Add dowloand object functionality to gcp storage bucket

* Add functionality to get pre-signed url

* Change storage_buck_obj file name to storage_bucket_obj

* improve cloud selection ui

* Enable use of localstack with aws sub-command

* Fix region flag in aws sub command

* Remove unused code and add comment

* Fix prompt on gcp screen

* Add cloudlens logo

* aws credentials bug fix

* Refactor getCfg function to handle multiple config methods

* Add test cases for storage resource

---------

Co-authored-by: pratikjethe <pratikjethe93@gmail.com>
Co-authored-by: Ramana Reddy <ramanaredy.manda@gmail.com>
  • Loading branch information
3 people committed Oct 30, 2023
1 parent c6a4d2d commit 70274b4
Show file tree
Hide file tree
Showing 39 changed files with 1,454 additions and 274 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Expand Up @@ -13,3 +13,10 @@ execs
*.out
# Dependency directories (remove the comment below to include it)
# vendor/

#test configs
*.json

#logs
*.log
tmp
34 changes: 34 additions & 0 deletions cmd/aws.go
@@ -0,0 +1,34 @@
package cmd

import (
"github.com/one2nc/cloudlens/internal"
"github.com/spf13/cobra"
)

func awsCommand() *cobra.Command {

command := cobra.Command{
Use: "aws",
Short: "Select aws",
Long: "Selects aws as default cloud",
Run: func(cmd *cobra.Command, args []string) {
selectAWS()
},
}

command.Flags().StringVarP(&profile, "profile", "p", "default", "Read aws profile")

command.Flags().StringVarP(&region, "region", "r", "", "Read aws region")
command.Flags().BoolVarP(&useLocalStack, "localstack", "l", false, "Use localsatck instead of AWS")

return &command
}

func selectAWS() {
cloudConfig.SelectedCloud = internal.AWS
cloudConfig.AWSConfig.Profile = profile
cloudConfig.AWSConfig.Region = region
cloudConfig.AWSConfig.UseLocalStack = useLocalStack

initView()
}
32 changes: 32 additions & 0 deletions cmd/gcp.go
@@ -0,0 +1,32 @@
package cmd

import (
"os"

"github.com/one2nc/cloudlens/internal"
"github.com/spf13/cobra"
)

func gcpCommand() *cobra.Command {

command := cobra.Command{
Use: "gcp",
Short: "Select gcp (set GOOGLE_APPLICATION_CREDENTIALS env variable or use \"gcp\" sub-command )",
Long: "Selects gcp as default cloud",
Run: func(cmd *cobra.Command, args []string) {
selectGCP()
},
}

command.Flags().StringVarP(&gcpCredFilePath, "cf", "", "", "Read GCP credential file")
command.MarkFlagRequired("cf")
return &command
}

func selectGCP() {
cloudConfig.SelectedCloud = internal.GCP
os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", gcpCredFilePath)
cloudConfig.CredFilePath = gcpCredFilePath

initView()
}
126 changes: 32 additions & 94 deletions cmd/root.go
@@ -1,16 +1,10 @@
package cmd

import (
"context"
"fmt"
"os"

cfg "github.com/aws/aws-sdk-go-v2/config"
awsS "github.com/aws/aws-sdk-go/aws"
"github.com/mattn/go-colorable"
"github.com/one2nc/cloudlens/internal"
"github.com/one2nc/cloudlens/internal/aws"
"github.com/one2nc/cloudlens/internal/color"
"github.com/one2nc/cloudlens/internal/config"
"github.com/one2nc/cloudlens/internal/view"
"github.com/rs/zerolog"
Expand All @@ -19,119 +13,63 @@ import (
)

var (
profile, region string
version = "dev"
commit = "dev"
date = "today"
rootCmd = &cobra.Command{
profile, region, gcpCredFilePath string
useLocalStack bool
version = "dev"
commit = "dev"
date = "today"
rootCmd = &cobra.Command{
Use: `cloudlens`,
Short: `cli for aws services`,
Long: `cli for aws services[s3, ec2, security-groups, iam]`,
Short: `cli for cloud services`,
Long: `cli for cloud services[aws,gcp]`,
Run: run,
}
out = colorable.NewColorableStdout()
cloudConfig config.CloudConfig
out = colorable.NewColorableStdout()
)

func init() {
rootCmd.AddCommand(versionCmd(), updateCmd())
rootCmd.PersistentFlags().StringVarP(&profile, "profile", "p", "default", "Read aws profile")
rootCmd.PersistentFlags().StringVarP(&region, "region", "r", "", "Read aws region")
rootCmd.AddCommand(versionCmd(), updateCmd(), awsCommand(), gcpCommand())

}

func Execute() {
file := ensureLogging()
defer func() {
if file != nil {
_ = file.Close()
}
}()

err := rootCmd.Execute()
if err != nil {
os.Exit(1)
}
}

func run(cmd *cobra.Command, args []string) {
mod := os.O_CREATE | os.O_APPEND | os.O_WRONLY
file, err := os.OpenFile("./cloudlens.log", mod, 0644)
if err != nil {
log.Printf("Could not open cloudlens.log. Writing logs to stdout instead.")
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout})
}
defer func() {
if file != nil {
_ = file.Close()
}
}()
if err == nil {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: file})
}
//TODO profiles and regions should under aws
//var sess *session.Session
var regions []string
initView()
}
func initView() {
app := view.NewApp()
profiles, err := readAndValidateProfile()
if len(profiles) > 0 {
if profiles[0] == "default" && len(region) == 0 {
region = getDefaultAWSRegion()
} else if len(region) == 0 {
region = "ap-south-1"
}

regions = readAndValidateRegion()
//sess, err = aws.GetSession(profiles[0], regions[0])
app.Init(version, cloudConfig)

cfg, err := aws.GetCfg(profiles[0], regions[0])
if err != nil {
panic(fmt.Sprintf("aws session init failed -- %v", err))
}

ctx := context.WithValue(context.Background(), internal.KeySession, cfg)
// TODO pass the AWS session instead of profiles and regions
if err := app.Init(ctx, profiles, regions, version); err != nil {
panic(fmt.Sprintf("app init failed -- %v", err))
}
} else {
profile := awsS.String(os.Getenv(AWS_PROFILE))
profiles := []string{*profile}
region := awsS.String(os.Getenv(AWS_DEFAULT_REGION))
regions := []string{*region}
cfg, err := aws.GetCfgUsingEnvVariables(profiles[0], regions[0])
if err != nil {
panic(fmt.Sprintf("aws session init failed -- %v", err))
}
ctx := context.WithValue(context.Background(), internal.KeySession, cfg)
if err := app.Init(ctx, profiles, regions, version); err != nil {
panic(fmt.Sprintf("app init failed -- %v", err))
}
}
if err := app.Run(); err != nil {
panic(fmt.Sprintf("app run failed %v", err))
}
}

func readAndValidateProfile() ([]string, error) {
profiles, err := aws.GetProfiles()
func ensureLogging() *os.File {
filename := "cloudlens.log"
mod := os.O_CREATE | os.O_APPEND | os.O_WRONLY
file, err := os.OpenFile(filename, mod, 0644)
if err != nil {
fmt.Sprintf("failed to read profiles -- %v", err)
return nil, err
}
profiles, isSwapped := config.SwapFirstIndexWithValue(profiles, profile)
if !isSwapped {
fmt.Printf("Profile '%v' not found, using profile '%v'... ", color.Colorize(profile, color.Red), color.Colorize(profiles[0], color.Green))
log.Printf("Could not open cloudlens.log. Writing logs to stdout instead.")
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout})
}
return profiles, nil
}

func readAndValidateRegion() []string {
regions := aws.GetAllRegions()
regions, isSwapped := config.SwapFirstIndexWithValue(regions, region)
if !isSwapped {
fmt.Printf("Region '%v' not found, using %v..", color.Colorize(region, color.Red), color.Colorize(regions[0], color.Green))
if err == nil {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: file})
}
return regions
}

func getDefaultAWSRegion() string {
cfg, err := cfg.LoadDefaultConfig(context.TODO())
if err != nil {
fmt.Fprintf(os.Stderr, "failed to load AWS SDK config: %v\n", err)
os.Exit(1)
}
region := cfg.Region
return region
return file
}
38 changes: 29 additions & 9 deletions go.mod
Expand Up @@ -15,18 +15,27 @@ require (
)

require (
cloud.google.com/go/resourcemanager v1.9.1
cloud.google.com/go/storage v1.33.0
github.com/Masterminds/semver v1.5.0
github.com/adrg/xdg v0.4.0
github.com/atotto/clipboard v0.1.4
github.com/charmbracelet/glamour v0.6.0
github.com/cheggaaa/pb/v3 v3.1.2
github.com/google/go-github/v50 v50.2.0
github.com/minio/selfupdate v0.6.0
github.com/stretchr/testify v1.8.2
google.golang.org/api v0.132.0
gopkg.in/ini.v1 v1.67.0
)

require (
aead.dev/minisign v0.2.0 // indirect
cloud.google.com/go v0.110.4 // indirect
cloud.google.com/go/compute v1.20.1 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v1.1.0 // indirect
cloud.google.com/go/longrunning v0.5.1 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect
github.com/VividCortex/ewma v1.2.0 // indirect
github.com/alecthomas/chroma v0.10.0 // indirect
Expand All @@ -41,23 +50,34 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/fatih/color v1.14.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/s2a-go v0.1.4 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/gorilla/css v1.0.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/microcosm-cc/bluemonday v1.0.21 // indirect
github.com/muesli/reflow v0.3.0 // indirect
github.com/muesli/termenv v0.13.0 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.8.2 // indirect
github.com/yuin/goldmark v1.5.2 // indirect
github.com/yuin/goldmark-emoji v1.0.1 // indirect
golang.org/x/crypto v0.7.0 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/oauth2 v0.6.0 // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/crypto v0.11.0 // indirect
golang.org/x/net v0.12.0 // indirect
golang.org/x/oauth2 v0.10.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.28.0 // indirect
google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
google.golang.org/grpc v1.56.2 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

Expand Down Expand Up @@ -90,8 +110,8 @@ require (
github.com/rivo/uniseg v0.2.0 // indirect
github.com/sahilm/fuzzy v0.1.0
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/term v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/term v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
gopkg.in/yaml.v2 v2.4.0
)

0 comments on commit 70274b4

Please sign in to comment.