diff --git a/internal/aws/ec2.go b/internal/aws/ec2.go index 670bf96..70be116 100644 --- a/internal/aws/ec2.go +++ b/internal/aws/ec2.go @@ -196,14 +196,25 @@ func GetSingleAMI(sess session.Session, amiId string) *ec2.Image { return result.Images[0] } -func GetVPCs(sess session.Session) []*ec2.Vpc { +func GetVPCs(sess session.Session) []VpcResp { ec2Serv := *ec2.New(&sess) result, err := ec2Serv.DescribeVpcs(&ec2.DescribeVpcsInput{}) if err != nil { fmt.Println("Error in fetching VPCs: ", " err: ", err) return nil } - return result.Vpcs + var vpcs []VpcResp + for _, v := range result.Vpcs { + vpc := VpcResp{ + VpcId: *v.VpcId, + OwnerId: *v.OwnerId, + CidrBlock: *v.CidrBlock, + InstanceTenancy: *v.InstanceTenancy, + State: *v.State, + } + vpcs = append(vpcs, vpc) + } + return vpcs } func GetSingleVPC(sess session.Session, vpcId string) *ec2.Vpc { diff --git a/internal/aws/types.go b/internal/aws/types.go index 6b70a6a..ee58270 100644 --- a/internal/aws/types.go +++ b/internal/aws/types.go @@ -98,3 +98,11 @@ type ImageResp struct { Name string ImageType string } + +type VpcResp struct { + VpcId string + OwnerId string + CidrBlock string + InstanceTenancy string + State string +} diff --git a/internal/config/alias.go b/internal/config/alias.go index 91071eb..8df195c 100644 --- a/internal/config/alias.go +++ b/internal/config/alias.go @@ -138,6 +138,7 @@ func (a *Aliases) loadDefaultAliases() { a.declare("iam:r", "IAM:R") a.declare("ec2:s", "EC2:S") a.declare("ec2:i", "EC2:I") + a.declare("vpc", "VPC") a.declare("help", "h", "?") a.declare("quit", "q", "q!", "Q") diff --git a/internal/dao/vpc.go b/internal/dao/vpc.go new file mode 100644 index 0000000..7114576 --- /dev/null +++ b/internal/dao/vpc.go @@ -0,0 +1,37 @@ +package dao + +import ( + "context" + "fmt" + + "github.com/aws/aws-sdk-go/aws/session" + "github.com/one2nc/cloud-lens/internal" + "github.com/one2nc/cloud-lens/internal/aws" + "github.com/rs/zerolog/log" +) + +type VPC struct { + Accessor + ctx context.Context +} + +func (v *VPC) Init(ctx context.Context) { + v.ctx = ctx +} + +func (v *VPC) List(ctx context.Context) ([]Object, error) { + sess, ok := ctx.Value(internal.KeySession).(*session.Session) + if !ok { + log.Err(fmt.Errorf("conversion err: Expected session.session but got %v", sess)) + } + vpcs := aws.GetVPCs(*sess) + objs := make([]Object, len(vpcs)) + for i, obj := range vpcs { + objs[i] = obj + } + return objs, nil +} + +func (ei *VPC) Get(ctx context.Context, path string) (Object, error) { + return nil, nil +} diff --git a/internal/model/registry.go b/internal/model/registry.go index adac433..1cc04d3 100644 --- a/internal/model/registry.go +++ b/internal/model/registry.go @@ -62,4 +62,8 @@ var Registry = map[string]ResourceMeta{ DAO: &dao.EC2I{}, Renderer: &render.EC2I{}, }, + "vpc": { + DAO: &dao.VPC{}, + Renderer: &render.VPC{}, + }, } diff --git a/internal/render/vpc.go b/internal/render/vpc.go new file mode 100644 index 0000000..8b73dfc --- /dev/null +++ b/internal/render/vpc.go @@ -0,0 +1,38 @@ +package render + +import ( + "fmt" + + "github.com/derailed/tview" + "github.com/one2nc/cloud-lens/internal/aws" +) + +type VPC struct { +} + +func (v VPC) Header() Header { + return Header{ + HeaderColumn{Name: "VPC-Id", SortIndicatorIdx: 4, Align: tview.AlignLeft, Hide: false, Wide: false, MX: false, Time: false}, + HeaderColumn{Name: "Owner-Id", SortIndicatorIdx: -1, Align: tview.AlignLeft, Hide: false, Wide: false, MX: false, Time: false}, + HeaderColumn{Name: "Cidr Block", SortIndicatorIdx: -1, Align: tview.AlignLeft, Hide: false, Wide: false, MX: false, Time: false}, + HeaderColumn{Name: "Instance Tenancy", SortIndicatorIdx: -1, Align: tview.AlignLeft, Hide: false, Wide: false, MX: false, Time: false}, + HeaderColumn{Name: "VPC-State", SortIndicatorIdx: 4, Align: tview.AlignLeft, Hide: false, Wide: false, MX: false, Time: false}, + } +} + +func (v VPC) Render(o interface{}, ns string, row *Row) error { + vpcResp, ok := o.(aws.VpcResp) + if !ok { + return fmt.Errorf("expected vpc, but got %T", o) + } + + row.ID = ns + row.Fields = Fields{ + vpcResp.VpcId, + vpcResp.OwnerId, + vpcResp.CidrBlock, + vpcResp.InstanceTenancy, + vpcResp.State, + } + return nil +} diff --git a/internal/view/registrar.go b/internal/view/registrar.go index beae8c0..73caded 100644 --- a/internal/view/registrar.go +++ b/internal/view/registrar.go @@ -35,4 +35,7 @@ func coreViewers(vv MetaViewers) { vv["ec2:i"] = MetaViewer{ viewerFn: NewEC2I, } + vv["vpc"] = MetaViewer{ + viewerFn: NewVPC, + } } diff --git a/internal/view/vpc.go b/internal/view/vpc.go new file mode 100644 index 0000000..e022cc0 --- /dev/null +++ b/internal/view/vpc.go @@ -0,0 +1,26 @@ +package view + +import ( + "github.com/gdamore/tcell/v2" + "github.com/one2nc/cloud-lens/internal/ui" +) + +type VPC struct { + ResourceViewer +} + +// NewPod returns a new viewer. +func NewVPC(resource string) ResourceViewer { + var v VPC + v.ResourceViewer = NewBrowser(resource) + v.AddBindKeysFn(v.bindKeys) + return &v +} + +func (v *VPC) bindKeys(aa ui.KeyActions) { + aa.Add(ui.KeyActions{ + ui.KeyShiftI: ui.NewKeyAction("Sort VPC-Id", v.GetTable().SortColCmd("VPC-Id", true), true), + ui.KeyShiftS: ui.NewKeyAction("Sort VPC-State", v.GetTable().SortColCmd("VPC-State", true), true), + tcell.KeyEscape: ui.NewKeyAction("Back", v.App().PrevCmd, false), + }) +}