Skip to content

Commit d6c930b

Browse files
authored
2906 list custom attestation types (#430)
* Add code for list attestation-types command * Add tests for list attestation-types command * Don't use goldenFile for list attestation-types as results seem to be formatted differently in the CI
1 parent 7cc52b1 commit d6c930b

File tree

3 files changed

+169
-0
lines changed

3 files changed

+169
-0
lines changed

cmd/kosli/list.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ func newListCmd(out io.Writer) *cobra.Command {
4242
newListSnapshotsCmd(out),
4343
newListTrailsCmd(out),
4444
newListPoliciesCmd(out),
45+
newListAttestationTypesCmd(out),
4546
)
4647

4748
return cmd

cmd/kosli/listAttestationTypes.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"io"
7+
"net/http"
8+
9+
"github.com/kosli-dev/cli/internal/output"
10+
"github.com/kosli-dev/cli/internal/requests"
11+
"github.com/spf13/cobra"
12+
)
13+
14+
const listAttestationTypesDesc = `List all Kosli attestation types for an org.`
15+
16+
type listAttestationTypesOptions struct {
17+
output string
18+
}
19+
20+
func newListAttestationTypesCmd(out io.Writer) *cobra.Command {
21+
o := new(listAttestationTypesOptions)
22+
cmd := &cobra.Command{
23+
Use: "attestation-types",
24+
Short: listAttestationTypesDesc,
25+
Long: listAttestationTypesDesc,
26+
Args: cobra.NoArgs,
27+
PreRunE: func(cmd *cobra.Command, args []string) error {
28+
err := RequireGlobalFlags(global, []string{"Org", "ApiToken"})
29+
if err != nil {
30+
return ErrorBeforePrintingUsage(cmd, err.Error())
31+
}
32+
return nil
33+
},
34+
RunE: func(cmd *cobra.Command, args []string) error {
35+
return o.run(out, args)
36+
},
37+
}
38+
39+
cmd.Flags().StringVarP(&o.output, "output", "o", "table", outputFlag)
40+
41+
return cmd
42+
}
43+
44+
func (o *listAttestationTypesOptions) run(out io.Writer, args []string) error {
45+
url := fmt.Sprintf("%s/api/v2/custom-attestation-types/%s", global.Host, global.Org)
46+
47+
reqParams := &requests.RequestParams{
48+
Method: http.MethodGet,
49+
URL: url,
50+
Token: global.ApiToken,
51+
}
52+
response, err := kosliClient.Do(reqParams)
53+
if err != nil {
54+
return err
55+
}
56+
57+
return output.FormattedPrint(response.Body, o.output, out, 0,
58+
map[string]output.FormatOutputFunc{
59+
"table": printAttestationTypesListAsTable,
60+
"json": output.PrintJson,
61+
})
62+
}
63+
64+
func printAttestationTypesListAsTable(raw string, out io.Writer, page int) error {
65+
var attestationTypes []map[string]interface{}
66+
err := json.Unmarshal([]byte(raw), &attestationTypes)
67+
if err != nil {
68+
return err
69+
}
70+
71+
if len(attestationTypes) == 0 {
72+
logger.Info("No attestation types were found.")
73+
return nil
74+
}
75+
76+
header := []string{"NAME", "DESCRIPTION", "LATEST VERSION"}
77+
rows := []string{}
78+
79+
for _, attestationType := range attestationTypes {
80+
description := attestationType["description"]
81+
if description == nil {
82+
description = ""
83+
}
84+
latestVersion := len(attestationType["versions"].([]interface{}))
85+
86+
rows = append(rows, fmt.Sprintf("%s\t%s\t%d", attestationType["name"], description, latestVersion))
87+
}
88+
89+
tabFormattedPrint(out, header, rows)
90+
return nil
91+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/stretchr/testify/suite"
8+
)
9+
10+
// Define the suite, and absorb the built-in basic suite
11+
// functionality from testify - including a T() method which
12+
// returns the current testing context
13+
type ListAttestationTypesCommandTestSuite struct {
14+
suite.Suite
15+
defaultKosliArguments string
16+
acmeOrgKosliArguments string
17+
attestationName1 string
18+
attestationName2 string
19+
}
20+
21+
func (suite *ListAttestationTypesCommandTestSuite) SetupTest() {
22+
suite.attestationName1 = "custom-attestation-type-1"
23+
suite.attestationName2 = "custom-attestation-type-2"
24+
global = &GlobalOpts{
25+
ApiToken: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6ImNkNzg4OTg5In0.e8i_lA_QrEhFncb05Xw6E_tkCHU9QfcY4OLTVUCHffY",
26+
Org: "docs-cmd-test-user",
27+
Host: "http://localhost:8001",
28+
}
29+
suite.defaultKosliArguments = fmt.Sprintf(" --host %s --org %s --api-token %s", global.Host, global.Org, global.ApiToken)
30+
CreateCustomAttestationType(suite.attestationName1, "testdata/person-schema.json", []string{".age > 21"}, suite.T())
31+
CreateCustomAttestationType(suite.attestationName2, "testdata/person-schema.json", []string{".age < 25"}, suite.T())
32+
CreateCustomAttestationType(suite.attestationName1, "testdata/person-schema.json", []string{".age > 21", ".age < 85"}, suite.T()) //Make a second version
33+
34+
global.Org = "acme-org"
35+
global.ApiToken = "v3OWZiYWu9G2IMQStYg9BcPQUQ88lJNNnTJTNq8jfvmkR1C5wVpHSs7F00JcB5i6OGeUzrKt3CwRq7ndcN4TTfMeo8ASVJ5NdHpZT7DkfRfiFvm8s7GbsIHh2PtiQJYs2UoN13T8DblV5C4oKb6-yWH73h67OhotPlKfVKazR-c"
36+
suite.acmeOrgKosliArguments = fmt.Sprintf(" --host %s --org %s --api-token %s", global.Host, global.Org, global.ApiToken)
37+
38+
}
39+
40+
func (suite *ListAttestationTypesCommandTestSuite) TestListFlowsCmd() {
41+
tests := []cmdTestCase{
42+
{
43+
name: "listing custom attestation types works when some exist",
44+
cmd: fmt.Sprintf(`list attestation-types %s`, suite.defaultKosliArguments),
45+
golden: "",
46+
},
47+
{
48+
name: "listing custom attestation types works when there are none",
49+
cmd: fmt.Sprintf(`list attestation-types %s`, suite.acmeOrgKosliArguments),
50+
golden: "No attestation types were found.\n",
51+
},
52+
{
53+
name: "listing custom attestation types with --output json works when some exist",
54+
cmd: fmt.Sprintf(`list attestation-types --output json %s`, suite.defaultKosliArguments),
55+
golden: "",
56+
},
57+
{
58+
name: "listing custom attestation types with --output json works when there are none",
59+
cmd: fmt.Sprintf(`list attestation-types --output json %s`, suite.acmeOrgKosliArguments),
60+
golden: "[]\n",
61+
},
62+
{
63+
wantError: true,
64+
name: "providing an argument causes an error",
65+
cmd: fmt.Sprintf(`list attestation-types xxx %s`, suite.defaultKosliArguments),
66+
golden: "Error: unknown command \"xxx\" for \"kosli list attestation-types\"\n",
67+
},
68+
}
69+
70+
runTestCmd(suite.T(), tests)
71+
}
72+
73+
// In order for 'go test' to run this suite, we need to create
74+
// a normal test function and pass our suite to suite.Run
75+
func TestListAttestationTypesCommandTestSuite(t *testing.T) {
76+
suite.Run(t, new(ListAttestationTypesCommandTestSuite))
77+
}

0 commit comments

Comments
 (0)