Skip to content

Commit

Permalink
Use new state package in ui cmd
Browse files Browse the repository at this point in the history
  • Loading branch information
rkoster committed Feb 21, 2021
1 parent c93e8a6 commit 67ea31a
Show file tree
Hide file tree
Showing 13 changed files with 137 additions and 481 deletions.
10 changes: 6 additions & 4 deletions app/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package app

import (
"github.com/starkandwayne/carousel/credhub"
"github.com/starkandwayne/carousel/store"
"github.com/starkandwayne/carousel/state"

"github.com/gdamore/tcell/v2"

Expand All @@ -11,11 +11,12 @@ import (

type Application struct {
*tview.Application
store *store.Store
state state.State
credhub credhub.CredHub
layout *Layout
keyBindings map[tcell.Key]func()
selectedID string
refresh func()
}

type Layout struct {
Expand All @@ -24,12 +25,13 @@ type Layout struct {
details *tview.Flex
}

func NewApplication(store *store.Store, ch credhub.CredHub) *Application {
func NewApplication(state state.State, ch credhub.CredHub, refresh func()) *Application {
return &Application{
Application: tview.NewApplication(),
store: store,
state: state,
keyBindings: make(map[tcell.Key]func(), 0),
credhub: ch,
refresh: refresh,
}
}

Expand Down
69 changes: 43 additions & 26 deletions app/details.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import (

"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
"github.com/starkandwayne/carousel/store"
"github.com/starkandwayne/carousel/credhub"
"github.com/starkandwayne/carousel/state"
"gopkg.in/yaml.v2"

"github.com/grantae/certinfo"
Expand All @@ -24,7 +25,7 @@ func (a *Application) actionShowDetails(ref interface{}) {
a.layout.details.Clear().AddItem(a.renderDetailsFor(ref), 0, 1, false)
}

func (a *Application) actionToggleTransitional(cred *store.Credential) {
func (a *Application) actionToggleTransitional(cred *state.Credential) {
modal := tview.NewModal().
SetText(fmt.Sprintf("Set transitional=%s for %s@%s",
strconv.FormatBool(!cred.Transitional),
Expand All @@ -37,7 +38,7 @@ func (a *Application) actionToggleTransitional(cred *store.Credential) {
panic(err)
}
a.statusModal("Refreshing State...")
err = a.store.Refresh()
a.refresh()
if err != nil {
panic(err)
}
Expand All @@ -53,16 +54,16 @@ func (a *Application) actionToggleTransitional(cred *store.Credential) {

func (a *Application) renderDetailsFor(ref interface{}) tview.Primitive {
switch v := ref.(type) {
case *store.Path:
case *state.Path:
return a.renderPathDetail(v)
case *store.Credential:
case *state.Credential:
return a.renderCredentialDetail(v)
default:
return a.renderWelcome()
}
}

func (a *Application) renderPathDetail(p *store.Path) tview.Primitive {
func (a *Application) renderPathDetail(p *state.Path) tview.Primitive {
t := tview.NewTable()
t.SetBorder(true)
t.SetTitle("Credhub & BOSH")
Expand Down Expand Up @@ -90,44 +91,60 @@ func (a *Application) renderPathDetail(p *store.Path) tview.Primitive {
AddItem(info, 0, 1, true)
}

func (a *Application) renderCredentialDetail(cred *store.Credential) tview.Primitive {
func (a *Application) renderCredentialDetail(cred *state.Credential) tview.Primitive {
t := tview.NewTable()
t.SetBorder(true)
t.SetTitle("Credhub & BOSH")

addSimpleRow(t, "ID", cred.ID)
addSimpleRow(t, "Expiry", fmt.Sprintf("%s (%s)",
cred.ExpiryDate.Format(time.RFC3339),
humanize.RelTime(*cred.ExpiryDate, time.Now(), "ago", "from now")))
addSimpleRow(t, "Transitional", strconv.FormatBool(cred.Transitional))
addSimpleRow(t, "Certificate Authority", strconv.FormatBool(cred.CertificateAuthority))
addSimpleRow(t, "Self Signed", strconv.FormatBool(cred.SelfSigned))

addSimpleRow(t, "Created At", fmt.Sprintf("%s (%s)",
cred.VersionCreatedAt.Format(time.RFC3339),
humanize.RelTime(*cred.VersionCreatedAt, time.Now(), "ago", "from now")))
addSimpleRow(t, "Deployments", renderDeployments(cred.Deployments))
addSimpleRow(t, "Latest", strconv.FormatBool(cred.Latest))

i, err := certinfo.CertificateText(cred.Certificate)
if err != nil {
panic(err)
}
var info *tview.TextView
detailRows := 4 + 2 // 2 for top and bottom border

info := tview.NewTextView().SetText(i).
SetTextColor(tcell.Color102)
switch cred.Type {
case credhub.Certificate:
addSimpleRow(t, "Expiry", fmt.Sprintf("%s (%s)",
cred.ExpiryDate.Format(time.RFC3339),
humanize.RelTime(*cred.ExpiryDate, time.Now(), "ago", "from now")))
addSimpleRow(t, "Transitional", strconv.FormatBool(cred.Transitional))
addSimpleRow(t, "Certificate Authority", strconv.FormatBool(cred.CertificateAuthority))
addSimpleRow(t, "Self Signed", strconv.FormatBool(cred.SelfSigned))

info.SetBorder(true)
info.SetTitle("Raw Certificate")
detailRows = detailRows + 4

i, err := certinfo.CertificateText(cred.Certificate)
if err != nil {
panic(err)
}

info = tview.NewTextView().SetText(i).
SetTextColor(tcell.Color102)
info.SetBorder(true)
info.SetTitle("Raw Certificate")
default:
info = tview.NewTextView().SetText("TODO").
SetTextColor(tcell.Color102)
info.SetBorder(true)
info.SetTitle("Info")
}

a.layout.tree.SetInputCapture(a.nextFocusInputCaptureHandler(t))
t.SetInputCapture(a.nextFocusInputCaptureHandler(info))
info.SetInputCapture(a.nextFocusInputCaptureHandler(a.layout.tree))

return tview.NewFlex().
SetDirection(tview.FlexRow).
AddItem(t, 8, 1, false).
AddItem(t, detailRows, 1, false).
AddItem(a.renderCredentialActions(cred), 1, 1, false).
AddItem(info, 0, 1, true)
}

func (a *Application) renderCredentialActions(cred *store.Credential) tview.Primitive {
func (a *Application) renderCredentialActions(cred *state.Credential) tview.Primitive {
actions := []string{
"Toggle Transitional",
"Delete",
Expand All @@ -148,7 +165,7 @@ func (a *Application) renderCredentialActions(cred *store.Credential) tview.Prim
SetText(" " + strings.Join(out, " "))
}

func (a *Application) renderPathActions(p *store.Path) tview.Primitive {
func (a *Application) renderPathActions(p *state.Path) tview.Primitive {
actions := []string{
"Regenerate",
"Delete",
Expand Down Expand Up @@ -186,7 +203,7 @@ func addSimpleRow(t *tview.Table, lbl, val string) {
t.SetCellSimple(row, 1, val)
}

func renderDeployments(deployments []*store.Deployment) string {
func renderDeployments(deployments []*state.Deployment) string {
tmp := make([]string, 0)
for _, d := range deployments {
tmp = append(tmp, d.Name)
Expand Down
21 changes: 21 additions & 0 deletions app/helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package app

import (
"time"

"github.com/starkandwayne/carousel/state"
)

func toStatus(c *state.Credential) string {
status := "active"
if c.ExpiryDate != nil && c.ExpiryDate.Sub(time.Now()) < time.Hour*24*30 {
status = "notice"
}
if c.VersionCreatedAt.Sub(time.Now()) > time.Hour*24*365 {
status = "notice"
}
if len(c.Deployments) == 0 {
status = "unused"
}
return status
}
37 changes: 25 additions & 12 deletions app/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import (
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"

"github.com/starkandwayne/carousel/store"
"github.com/starkandwayne/carousel/credhub"
"github.com/starkandwayne/carousel/state"
)

const treePanel = "TreePanel"
Expand All @@ -17,13 +18,24 @@ func (a *Application) viewTree() *tview.TreeView {

func (a *Application) renderTree() {
root := tview.NewTreeNode("∎")
a.store.EachPath(func(path *store.Path) {
// only interested in top level certVersions
if len(path.Versions) != 0 && path.Versions[0].SignedBy != nil {
return

for _, credType := range credhub.CredentialTypes {
credentials := a.state.Credentials(
state.TypeFilter(credType),
state.SelfSignedFilter(),
state.LatestFilter())

if len(credentials) == 0 {
continue
}
root.SetChildren(append(root.GetChildren(), addToTree(path.Versions)...))
})

typeNode := tview.NewTreeNode(string(credType)).Collapse()
root.AddChild(typeNode)

for _, credential := range credentials {
typeNode.SetChildren(append(typeNode.GetChildren(), addToTree(credential.Path.Versions)...))
}
}

var currentNode *tview.TreeNode

Expand All @@ -37,6 +49,7 @@ func (a *Application) renderTree() {
}
if refToID(node.GetReference()) == a.selectedID {
currentNode = node
root.ExpandAll()
a.actionShowDetails(currentNode.GetReference())
return false
}
Expand All @@ -57,16 +70,16 @@ func (a *Application) renderTree() {

func refToID(ref interface{}) string {
switch v := ref.(type) {
case *store.Credential:
case *state.Credential:
return v.ID
case *store.Path:
case *state.Path:
return v.Name
default:
return ""
}
}

func addToTree(creds []*store.Credential) []*tview.TreeNode {
func addToTree(creds []*state.Credential) []*tview.TreeNode {
out := make([]*tview.TreeNode, 0)
for _, cred := range creds {
pathNode := tview.NewTreeNode(cred.Path.Name).
Expand All @@ -80,12 +93,12 @@ func addToTree(creds []*store.Credential) []*tview.TreeNode {
}
}

lbl := fmt.Sprintf("%s (%s)", cred.ID, cred.Status())
lbl := fmt.Sprintf("%s (%s)", cred.ID, toStatus(cred))
if cred.Transitional {
lbl = lbl + " (transitional)"
}
credNode := tview.NewTreeNode(lbl).SetReference(cred)
switch cred.Status() {
switch toStatus(cred) {
case "unused":
credNode.SetColor(tcell.Color102)
case "notice":
Expand Down
6 changes: 3 additions & 3 deletions store/store_suite_test.go → cmd/cmd_suite_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package store_test
package cmd_test

import (
"testing"
Expand All @@ -7,7 +7,7 @@ import (
. "github.com/onsi/gomega"
)

func TestStore(t *testing.T) {
func TestCmd(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Store Suite")
RunSpecs(t, "Cmd Suite")
}
8 changes: 2 additions & 6 deletions cmd/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,9 @@ This application is a tool to generate the needed files
to quickly create a Cobra application.`,
Run: func(cmd *cobra.Command, args []string) {
initialize()
refresh()

err := store.Refresh()
if err != nil {
logger.Fatalf("failed to load data: %s", err)
}

app := app.NewApplication(store, credhub).Init()
app := app.NewApplication(state, credhub, refresh).Init()

if err := app.Run(); err != nil {
logger.Fatalf("the ui encountered an error: %s", err)
Expand Down
4 changes: 4 additions & 0 deletions credhub/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ const (
"ssh", "rsa", "password", "user", "value", "json"
)

var CredentialTypes = []CredentialType{
Certificate, SSH, RSA, Password, User, Value, JSON,
}

type Credential struct {
ID string `json:"id"`
Metadata Metadata `json:"metadata,omitempty"`
Expand Down
16 changes: 1 addition & 15 deletions state/credentials.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,6 @@
package state

import "github.com/starkandwayne/carousel/credhub"

func TypeFilter(types ...credhub.CredentialType) Filter {
return func(c *Credential) bool {
match := false
for _, t := range types {
if c.Type == t {
match = true
}
}
return match
}
}

func (s *state) Credentials(filters ...Filter) []*Credential {
func (s *state) Credentials(filters ...filter) []*Credential {
certs := s.credentials.Select(func(_, v interface{}) bool {
for _, fn := range filters {
if !fn(v.(*Credential)) {
Expand Down
31 changes: 31 additions & 0 deletions state/filters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package state

import (
"github.com/starkandwayne/carousel/credhub"
)

type filter func(*Credential) bool

func SelfSignedFilter() filter {
return func(c *Credential) bool {
return c.SignedBy == nil
}
}

func LatestFilter() filter {
return func(c *Credential) bool {
return c.Latest
}
}

func TypeFilter(types ...credhub.CredentialType) filter {
return func(c *Credential) bool {
match := false
for _, t := range types {
if c.Type == t {
match = true
}
}
return match
}
}
4 changes: 1 addition & 3 deletions state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ import (
"github.com/starkandwayne/carousel/credhub"
)

type Filter func(*Credential) bool

type State interface {
Update([]*credhub.Credential, []*bosh.Variable) error
Credentials(...Filter) []*Credential
Credentials(...filter) []*Credential
}

func NewState() State {
Expand Down
Loading

0 comments on commit 67ea31a

Please sign in to comment.