Skip to content

Commit

Permalink
Use new credhub package in application package
Browse files Browse the repository at this point in the history
  • Loading branch information
rkoster committed Feb 18, 2021
1 parent 12cfae2 commit b9e19e1
Show file tree
Hide file tree
Showing 10 changed files with 319 additions and 311 deletions.
13 changes: 13 additions & 0 deletions app/app_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package app_test

import (
"testing"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

func TestApp(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "App Suite")
}
5 changes: 4 additions & 1 deletion app/application.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app

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

"github.com/gdamore/tcell/v2"
Expand All @@ -11,6 +12,7 @@ import (
type Application struct {
*tview.Application
store *store.Store
credhub credhub.CredHub
layout *Layout
keyBindings map[tcell.Key]func()
selectedID string
Expand All @@ -22,11 +24,12 @@ type Layout struct {
details *tview.Flex
}

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

Expand Down
54 changes: 27 additions & 27 deletions app/details.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ func (a *Application) actionShowDetails(ref interface{}) {
a.layout.details.Clear().AddItem(a.renderDetailsFor(ref), 0, 1, false)
}

func (a *Application) actionToggleTransitional(cv *store.CertVersion) {
func (a *Application) actionToggleTransitional(cred *store.Credential) {
modal := tview.NewModal().
SetText(fmt.Sprintf("Toggle Transitional for %s", cv.Id)).
AddButtons([]string{"Continue", "Cancel"})
SetText(fmt.Sprintf("Set transitional=%s for %s@%s",
strconv.FormatBool(!cred.Transitional),
cred.Name, cred.ID)).AddButtons([]string{"Continue", "Cancel"})
modal.SetDoneFunc(func(buttonIndex int, buttonLabel string) {
if buttonLabel == "Continue" {
a.statusModal("Updating Transitional...")
err := a.store.ToggleTransitional(cv)
err := a.credhub.UpdateTransitional(cred.Credential)
if err != nil {
panic(err)
}
Expand All @@ -52,24 +53,23 @@ func (a *Application) actionToggleTransitional(cv *store.CertVersion) {

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

func (a *Application) renderCertDetail(c *store.Cert) tview.Primitive {
func (a *Application) renderPathDetail(p *store.Path) tview.Primitive {
t := tview.NewTable()
t.SetBorder(true)
t.SetTitle("Credhub & BOSH")

addSimpleRow(t, "ID", c.Id)
addSimpleRow(t, "Name", c.Name)
addSimpleRow(t, "Name", p.Name)

variableDef, err := yaml.Marshal(c.VariableDefinition)
variableDef, err := yaml.Marshal(p.VariableDefinition)
if err != nil {
panic(err)
}
Expand All @@ -85,27 +85,27 @@ func (a *Application) renderCertDetail(c *store.Cert) tview.Primitive {

return tview.NewFlex().
SetDirection(tview.FlexRow).
AddItem(t, 8, 1, false).
AddItem(a.renderCertActions(c), 1, 1, false).
AddItem(t, 3, 1, false).
AddItem(a.renderPathActions(p), 1, 1, false).
AddItem(info, 0, 1, true)
}

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

addSimpleRow(t, "ID", cv.Id)
addSimpleRow(t, "ID", cred.ID)
addSimpleRow(t, "Expiry", fmt.Sprintf("%s (%s)",
cv.Expiry.Format(time.RFC3339),
humanize.RelTime(cv.Expiry, time.Now(), "ago", "from now")))
addSimpleRow(t, "Transitional", strconv.FormatBool(cv.Transitional))
addSimpleRow(t, "Certificate Authority", strconv.FormatBool(cv.CertificateAuthority))
addSimpleRow(t, "Self Signed", strconv.FormatBool(cv.SelfSigned))
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, "Deployments", renderDeployments(cv.Deployments))
addSimpleRow(t, "Deployments", renderDeployments(cred.Deployments))

i, err := certinfo.CertificateText(cv.Certificate)
i, err := certinfo.CertificateText(cred.Certificate)
if err != nil {
panic(err)
}
Expand All @@ -123,11 +123,11 @@ func (a *Application) renderCertVersionDetail(cv *store.CertVersion) tview.Primi
return tview.NewFlex().
SetDirection(tview.FlexRow).
AddItem(t, 8, 1, false).
AddItem(a.renderCertVersionActions(cv), 1, 1, false).
AddItem(a.renderCredentialActions(cred), 1, 1, false).
AddItem(info, 0, 1, true)
}

func (a *Application) renderCertVersionActions(cv *store.CertVersion) tview.Primitive {
func (a *Application) renderCredentialActions(cred *store.Credential) tview.Primitive {
actions := []string{
"Toggle Transitional",
"Delete",
Expand All @@ -140,15 +140,15 @@ func (a *Application) renderCertVersionActions(cv *store.CertVersion) tview.Prim
}

a.keyBindings[tcell.KeyCtrlT] = func() {
a.actionToggleTransitional(cv)
a.actionToggleTransitional(cred)
}

return tview.NewTextView().
SetDynamicColors(true).
SetText(" " + strings.Join(out, " "))
}

func (a *Application) renderCertActions(c *store.Cert) tview.Primitive {
func (a *Application) renderPathActions(p *store.Path) tview.Primitive {
actions := []string{
"Regenerate",
"Delete",
Expand Down
45 changes: 23 additions & 22 deletions app/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ func (a *Application) viewTree() *tview.TreeView {

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

var currentNode *tview.TreeNode
Expand Down Expand Up @@ -57,43 +57,44 @@ func (a *Application) renderTree() {

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

func addToTree(certVersions []*store.CertVersion) []*tview.TreeNode {
func addToTree(creds []*store.Credential) []*tview.TreeNode {
out := make([]*tview.TreeNode, 0)
for _, certVersion := range certVersions {
certNode := tview.NewTreeNode(certVersion.Cert.Name).
SetReference(certVersion.Cert)
for _, cred := range creds {
pathNode := tview.NewTreeNode(cred.Path.Name).
SetReference(cred.Path)

var exists bool
for _, n := range out {
if n.GetText() == certVersion.Cert.Name {
if refToID(n.GetReference()) == refToID(cred.Path) {
exists = true
certNode = n
pathNode = n
}
}
lbl := fmt.Sprintf("%s (%s)", certVersion.Id, certVersion.Status())
if certVersion.Transitional {

lbl := fmt.Sprintf("%s (%s)", cred.ID, cred.Status())
if cred.Transitional {
lbl = lbl + " (transitional)"
}
certVersionNode := tview.NewTreeNode(lbl).SetReference(certVersion)
switch certVersion.Status() {
credNode := tview.NewTreeNode(lbl).SetReference(cred)
switch cred.Status() {
case "unused":
certVersionNode.SetColor(tcell.Color102)
credNode.SetColor(tcell.Color102)
case "notice":
certVersionNode.SetColor(tcell.ColorDarkGoldenrod)
credNode.SetColor(tcell.ColorDarkGoldenrod)
}
certNode.AddChild(certVersionNode)
certVersionNode.SetChildren(addToTree(certVersion.Signs))
pathNode.AddChild(credNode)
credNode.SetChildren(addToTree(cred.Signs))
if !exists {
out = append(out, certNode)
out = append(out, pathNode)
}
}
return out
Expand Down
42 changes: 27 additions & 15 deletions credhub/credhub.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
type CredHub interface {
FindAll() ([]*Credential, error)
ReGenerate(*Credential) error
UpdateTransitional(*Credential, bool) error
UpdateTransitional(*Credential) error
}

func NewCredHub(ch *chcli.CredHub) CredHub {
Expand Down Expand Up @@ -60,19 +60,32 @@ func (ch *credhub) ReGenerate(*Credential) error {
return nil
}

func (ch *credhub) UpdateTransitional(*Credential, bool) error {
func (ch *credhub) UpdateTransitional(c *Credential) error {
certMeta, err := ch.client.GetCertificateMetadataByName(c.Name)
if err != nil {
return fmt.Errorf("failed to get certificate meta for: %s got: %s", c.Name, err)
}

path := fmt.Sprintf("/api/v1/certificates/%s/update_transitional_version", certMeta.Id)
body := map[string]interface{}{"version": c.ID}
if c.Transitional {
body["version"] = nil
}
resp, err := ch.client.Request(http.MethodPut, path, nil, body, true)
defer resp.Body.Close()
if err != nil {
return fmt.Errorf("failed request: %s with body: %s got: %s", path, body, err)
}
return nil
}

func (ch *credhub) getAllVersions(path string) ([]*Credential, error) {
u, _ := url.Parse("/api/v1/data")
q := u.Query()
q.Add("name", path)
u.RawQuery = q.Encode()
resp, err := ch.client.Request(http.MethodGet, "/api/v1/data",
url.Values{"name": []string{path}}, nil, true)
defer resp.Body.Close()

resp, err := ch.client.Request(http.MethodGet, u.String(), nil, nil, true)
if err != nil {
return nil, fmt.Errorf("failed request: %s got: %s", u, err)
return nil, fmt.Errorf("failed request got: %s", err)
}

result := struct {
Expand Down Expand Up @@ -104,11 +117,12 @@ func (ch *credhub) getAllVersionsForAllPaths(paths []string) ([]*Credential, err
}(pathChannel, errorChannel, resultChannel, &waitGroup)
}

for _, path := range paths {
pathChannel <- path
}

close(pathChannel)
go func() {
for _, path := range paths {
pathChannel <- path
}
close(pathChannel)
}()

go func() {
waitGroup.Wait()
Expand All @@ -135,6 +149,4 @@ func (ch *credhub) getAllVersionsForAllPaths(paths []string) ([]*Credential, err
}
}
}

return results, nil
}
15 changes: 9 additions & 6 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import (
"log"
"os"

"code.cloudfoundry.org/credhub-cli/credhub"
credhubcli "code.cloudfoundry.org/credhub-cli/credhub"
"code.cloudfoundry.org/credhub-cli/credhub/auth"
"github.com/starkandwayne/carousel/app"
"github.com/starkandwayne/carousel/credhub"
"github.com/starkandwayne/carousel/store"

boshdir "github.com/cloudfoundry/bosh-cli/director"
Expand All @@ -21,16 +22,16 @@ func main() {
logger.Fatalf("failed to load environment configuration: %s", err)
}

ch, err := credhub.New(
chcli, err := credhubcli.New(
cfg.Credhub.Server,
credhub.SkipTLSValidation(true), // TODO use CA
credhub.Auth(auth.UaaClientCredentials(cfg.Credhub.Client, cfg.Credhub.Secret)),
credhubcli.SkipTLSValidation(true), // TODO use CA
credhubcli.Auth(auth.UaaClientCredentials(cfg.Credhub.Client, cfg.Credhub.Secret)),
)
if err != nil {
logger.Fatalf("failed to connect to Credhub: %s", err)
}

authURL, err := ch.AuthURL()
authURL, err := chcli.AuthURL()
if err != nil {
logger.Fatalf("failed to lookup auth url: %s", err)
}
Expand All @@ -45,13 +46,15 @@ func main() {
logger.Fatalf("failed to initialize bosh director client: %s", err)
}

ch := credhub.NewCredHub(chcli)

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

app := app.NewApplication(s).Init()
app := app.NewApplication(s, ch).Init()

if err := app.Run(); err != nil {
panic(err)
Expand Down
Loading

0 comments on commit b9e19e1

Please sign in to comment.