Skip to content

Commit

Permalink
switch to three layers of collapsibles
Browse files Browse the repository at this point in the history
first it renders all phases, w/ a count of waves
inside each panel it renders a list of resources by group/kind/namespace/name
finally you can expand each resource individually
  • Loading branch information
djeebus committed Apr 8, 2024
1 parent 99fc6c9 commit 3d5f36b
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 47 deletions.
70 changes: 41 additions & 29 deletions pkg/checks/hooks/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ import (
"github.com/zapier/kubechecks/pkg/msg"
)

const triple = "```"

func Check(_ context.Context, request checks.Request) (msg.Result, error) {
grouped := make(groupedSyncWaves)

Expand All @@ -46,37 +44,32 @@ func Check(_ context.Context, request checks.Request) (msg.Result, error) {
phaseNames = append(phaseNames, pw.phase)
}

var renderedResources []string
for _, r := range pw.resources {
data, err := yaml.Marshal(r.Object)
if err != nil {
return msg.Result{}, errors.Wrap(err, "failed to unmarshal yaml")
var waveDetails []string
for _, w := range pw.waves {
var resources []string
for _, r := range w.resources {
data, err := yaml.Marshal(r.Object)
renderedResource := strings.TrimSpace(string(data))
if err != nil {
return msg.Result{}, errors.Wrap(err, "failed to unmarshal yaml")
}

renderedResource = collapsible(
fmt.Sprintf("%s/%s %s/%s", r.GetAPIVersion(), r.GetKind(), r.GetNamespace(), r.GetName()),
code("yaml", renderedResource),
)
resources = append(resources, renderedResource)
}

renderedResources = append(renderedResources, "\n"+string(data))
}

var countFmt string
resourceCount := len(renderedResources)
switch resourceCount {
case 0:
continue
case 1:
countFmt = "%d resource"
default:
countFmt = "%d resources"
sectionName := fmt.Sprintf("wave %d (%s)", w.wave, plural(resources, "resource", "resources"))
waveDetail := collapsible(sectionName, strings.Join(resources, "\n\n"))
waveDetails = append(waveDetails, waveDetail)
}

sectionName := fmt.Sprintf("%s phase, wave %d (%s)", pw.phase, pw.wave, countFmt)
sectionName = fmt.Sprintf(sectionName, len(renderedResources))

phaseDetail := fmt.Sprintf(`<details>
<summary>%s</summary>
`+triple+`yaml%s`+triple+`
</details>`, sectionName, strings.Join(renderedResources, "\n---\n"))

phaseDetail := collapsible(
fmt.Sprintf("%s phase (%s)", pw.phase, plural(waveDetails, "wave", "waves")),
strings.Join(waveDetails, "\n\n"),
)
phaseDetails = append(phaseDetails, phaseDetail)
}

Expand All @@ -88,6 +81,17 @@ func Check(_ context.Context, request checks.Request) (msg.Result, error) {
}, nil
}

func plural[T any](items []T, singular, plural string) string {
var description string
if len(items) == 1 {
description = singular
} else {
description = plural
}

return fmt.Sprintf("%d %s", len(items), description)
}

func toStringSlice(hookTypes []argocdSyncPhase) []string {
result := make([]string, len(hookTypes))
for idx := range hookTypes {
Expand All @@ -101,6 +105,14 @@ type hookInfo struct {
hookWave waveNum
}

func code(format, content string) string {
return fmt.Sprintf("```%s\n%s\n```", format, content)
}

func collapsible(summary, details string) string {
return fmt.Sprintf("<details>\n<summary>%s</summary>\n\n%s\n</details>", summary, details)
}

func phasesAndWaves(obj *unstructured.Unstructured) ([]hookInfo, error) {
var (
syncWave int64
Expand Down
85 changes: 71 additions & 14 deletions pkg/checks/hooks/check_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,43 +123,100 @@ func TestCheck(t *testing.T) {
assert.Equal(t, "<b>Sync Phases: PreSync, PostSync</b>", res.Summary)

expected := `<details>
<summary>PreSync phase, wave 0 (1 resource)</summary>
<summary>PreSync phase (2 waves)</summary>
<details>
<summary>wave 0 (1 resource)</summary>
<details>
<summary>v1/ConfigMap some-namespace/preSyncHookAndDefaultSyncWave</summary>
` + triple + `yaml
` + toYaml(preSyncHookAndDefaultSyncWave) + `
apiVersion: v1
kind: ConfigMap
metadata:
annotations:
argocd.argoproj.io/hook: PreSync
name: preSyncHookAndDefaultSyncWave
namespace: some-namespace
` + triple + `
</details>
</details>
<details>
<summary>PreSync phase, wave 5 (1 resource)</summary>
<summary>wave 5 (1 resource)</summary>
<details>
<summary>v1/ConfigMap some-namespace/preSyncHookAndNonDefaultSyncWave</summary>
` + triple + `yaml
` + toYaml(preSyncHookAndNonDefaultSyncWave) + `
apiVersion: v1
kind: ConfigMap
metadata:
annotations:
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/sync-wave: "5"
name: preSyncHookAndNonDefaultSyncWave
namespace: some-namespace
` + triple + `
</details>
</details>
</details>
<details>
<summary>PostSync phase (2 waves)</summary>
<details>
<summary>PostSync phase, wave 0 (1 resource)</summary>
<summary>wave 0 (1 resource)</summary>
<details>
<summary>v1/ConfigMap other-namespace/helmPostInstallHook</summary>
` + triple + `yaml
` + toYaml(helmPostInstallHook) + `
apiVersion: v1
kind: ConfigMap
metadata:
annotations:
helm.sh/hook: post-install
name: helmPostInstallHook
namespace: other-namespace
` + triple + `
</details>
</details>
<details>
<summary>PostSync phase, wave 5 (2 resources)</summary>
<summary>wave 5 (2 resources)</summary>
<details>
<summary>v1/ConfigMap some-namespace/postSyncHookAndNonDefaultSyncWave</summary>
` + triple + `yaml
` + toYaml(postSyncHookAndNonDefaultSyncWave) + `
apiVersion: v1
kind: ConfigMap
metadata:
annotations:
argocd.argoproj.io/hook: PostSync
argocd.argoproj.io/sync-wave: "5"
name: postSyncHookAndNonDefaultSyncWave
namespace: some-namespace
` + triple + `
</details>
---
<details>
<summary>v1/ConfigMap other-namespace/helmPostInstallHookWithWeight</summary>
` + toYaml(helmPostInstallHookWithWeight) + `
` + triple + `yaml
apiVersion: v1
kind: ConfigMap
metadata:
annotations:
helm.sh/hook: post-install
helm.sh/hook-weight: "5"
name: helmPostInstallHookWithWeight
namespace: other-namespace
` + triple + `
</details>
</details>
</details>`
assert.Equal(t, expected, res.Details)
}
17 changes: 13 additions & 4 deletions pkg/checks/hooks/grouped.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ const (
)

type phaseWaveResources struct {
phase argocdSyncPhase
phase argocdSyncPhase
waves []waveResources
}

type waveResources struct {
wave waveNum
resources []*unstructured.Unstructured
}
Expand All @@ -68,15 +72,20 @@ func (g groupedSyncWaves) getSortedPhasesAndWaves() []phaseWaveResources {
}
sort.Sort(byNum(wavesNums))

pwr := phaseWaveResources{
phase: phase,
}

for _, wave := range wavesNums {
pwr := phaseWaveResources{
phase: phase,
wr := waveResources{
wave: wave,
resources: waves[wave],
}

result = append(result, pwr)
pwr.waves = append(pwr.waves, wr)
}

result = append(result, pwr)
}

return result
Expand Down

0 comments on commit 3d5f36b

Please sign in to comment.