From 4690225c1e0576b53be7f6cd48a163b2c773e33c Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Mon, 26 Apr 2021 19:38:55 -0500 Subject: [PATCH] Update delete action behavior and JSON format output (#1155) This PR changes delete behavior: * On success, a 204 is returned rather than a 200 with an empty JSON object * The CLI now passes through the 404 error if encountered instead of swallowing it It also updates formatting for JSON to use the response body, which means that the item (or items) in the JSON format are actually the format across the wire, instead of being reinterpreted by unmarshaling into the Go SDK and then remarshaling. --- CHANGELOG.md | 22 +++++++ api/accounts/account.gen.go | 5 ++ api/authmethods/authmethods.gen.go | 5 ++ api/authtokens/authtokens.gen.go | 5 ++ api/groups/group.gen.go | 5 ++ api/hostcatalogs/host_catalog.gen.go | 5 ++ api/hosts/host.gen.go | 5 ++ api/hostsets/host_set.gen.go | 5 ++ api/response.go | 3 + api/roles/role.gen.go | 5 ++ api/scopes/scope.gen.go | 5 ++ api/sessions/session.gen.go | 5 ++ api/targets/target.gen.go | 5 ++ api/users/user.gen.go | 5 ++ internal/api/genapi/templates.go | 5 ++ internal/cmd/base/format.go | 57 +++++++++++++------ .../cmd/commands/accountscmd/accounts.gen.go | 43 ++++---------- .../commands/accountscmd/oidc_accounts.gen.go | 4 +- .../accountscmd/password_accounts.gen.go | 4 +- internal/cmd/commands/authenticate/funcs.go | 2 +- .../authmethodscmd/authmethods.gen.go | 43 ++++---------- .../authmethodscmd/oidc_authmethods.gen.go | 4 +- .../password_authmethods.gen.go | 4 +- .../commands/authtokenscmd/authtokens.gen.go | 43 ++++---------- internal/cmd/commands/groupscmd/groups.gen.go | 43 ++++---------- .../hostcatalogscmd/hostcatalogs.gen.go | 43 ++++---------- .../static_hostcatalogs.gen.go | 4 +- internal/cmd/commands/hostscmd/hosts.gen.go | 43 ++++---------- .../cmd/commands/hostscmd/static_hosts.gen.go | 4 +- .../cmd/commands/hostsetscmd/hostsets.gen.go | 43 ++++---------- .../hostsetscmd/static_hostsets.gen.go | 4 +- internal/cmd/commands/rolescmd/roles.gen.go | 43 ++++---------- internal/cmd/commands/scopescmd/scopes.gen.go | 43 ++++---------- .../cmd/commands/sessionscmd/sessions.gen.go | 21 ++----- internal/cmd/commands/targetscmd/funcs.go | 2 +- .../cmd/commands/targetscmd/targets.gen.go | 43 ++++---------- .../commands/targetscmd/tcp_targets.gen.go | 4 +- internal/cmd/commands/userscmd/users.gen.go | 43 ++++---------- internal/cmd/gencli/templates.go | 43 ++++---------- .../handlers/accounts/account_service.go | 2 +- .../handlers/accounts/account_service_test.go | 2 - .../authmethods/authmethod_service.go | 2 +- .../authmethods/authmethod_service_test.go | 2 - .../handlers/authtokens/authtoken_service.go | 2 +- .../authtokens/authtoken_service_test.go | 1 - .../handlers/groups/group_service.go | 2 +- .../handlers/groups/group_service_test.go | 2 - .../host_catalogs/host_catalog_service.go | 2 +- .../host_catalog_service_test.go | 1 - .../handlers/host_sets/host_set_service.go | 2 +- .../host_sets/host_set_service_test.go | 1 - .../controller/handlers/hosts/host_service.go | 2 +- .../handlers/hosts/host_service_test.go | 1 - .../controller/handlers/roles/role_service.go | 2 +- .../handlers/roles/role_service_test.go | 2 - .../handlers/scopes/scope_service.go | 2 +- .../handlers/scopes/scope_service_test.go | 2 - .../handlers/targets/target_service.go | 2 +- .../handlers/targets/target_service_test.go | 1 - website/content/docs/api-clients/api.mdx | 2 +- 60 files changed, 283 insertions(+), 474 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cc0a0aaa..e3d633ffc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,24 @@ Canonical reference for changes, improvements, and bugfixes for Boundary. ### Deprecations/Changes +* API `delete` actions now result in a `204` status code and no body when + successful. This was not the case previously due to a technical limitation + which has now been solved. +* When using a `delete` command we now either show success or treat the `404` + error the same as any other `404` error, that is, it results in a non-zero + status code and an error message. This makes `delete` actions behave the same + as other commands, all of which pass through errors to the CLI. Given `-format + json` capability, it's relatively easy to perform a check to see whether an + error was `404` or something else from within scripts, in conjunction with + checking that the returned status code matches the API error status code + (`1`). +* When outputting from the CLI in JSON format, the resource information under + `item` or `items` (depending on the action) now exactly matches the JSON sent + across the wire by the controller, as opposed to matching the Go SDK + representation which could result in some extra fields being shown or fields + having Go-specific types. This includes `delete` actions which previously + would show an object indicating existence, but now show no `item` on success + or the API's `404` error. * Permissions in new scope default roles have been updated to include support for `list`, `read:self`, and `delete:self` on `auth-token` resources. This allows a user to list and manage their own authentication tokens. (As is the @@ -16,6 +34,10 @@ Canonical reference for changes, improvements, and bugfixes for Boundary. ### New and Improved +* cli: Match JSON format output with the across-the-wire API JSON format + ([PR](https://github.com/hashicorp/boundary/pull/1155)) +* api: Return `204` instead of an empty object on successful `delete` operations + ([PR](https://github.com/hashicorp/boundary/pull/1155)) * actions: The new `no-op` action allows a grant to be given to a principals without conveying any actionable result. Since resources do not appear in list results if the principal has no actions granted on that resource, this can be diff --git a/api/accounts/account.gen.go b/api/accounts/account.gen.go index 41eb13686..47e70bd0b 100644 --- a/api/accounts/account.gen.go +++ b/api/accounts/account.gen.go @@ -50,6 +50,11 @@ type AccountDeleteResult struct { response *api.Response } +// GetItem will always be nil for AccountDeleteResult +func (n AccountDeleteResult) GetItem() interface{} { + return nil +} + func (n AccountDeleteResult) GetResponse() *api.Response { return n.response } diff --git a/api/authmethods/authmethods.gen.go b/api/authmethods/authmethods.gen.go index 9c57afd74..839bc2c34 100644 --- a/api/authmethods/authmethods.gen.go +++ b/api/authmethods/authmethods.gen.go @@ -52,6 +52,11 @@ type AuthMethodDeleteResult struct { response *api.Response } +// GetItem will always be nil for AuthMethodDeleteResult +func (n AuthMethodDeleteResult) GetItem() interface{} { + return nil +} + func (n AuthMethodDeleteResult) GetResponse() *api.Response { return n.response } diff --git a/api/authtokens/authtokens.gen.go b/api/authtokens/authtokens.gen.go index 09acb6878..1e178bcbc 100644 --- a/api/authtokens/authtokens.gen.go +++ b/api/authtokens/authtokens.gen.go @@ -50,6 +50,11 @@ type AuthTokenDeleteResult struct { response *api.Response } +// GetItem will always be nil for AuthTokenDeleteResult +func (n AuthTokenDeleteResult) GetItem() interface{} { + return nil +} + func (n AuthTokenDeleteResult) GetResponse() *api.Response { return n.response } diff --git a/api/groups/group.gen.go b/api/groups/group.gen.go index 6d83396ba..e36662236 100644 --- a/api/groups/group.gen.go +++ b/api/groups/group.gen.go @@ -50,6 +50,11 @@ type GroupDeleteResult struct { response *api.Response } +// GetItem will always be nil for GroupDeleteResult +func (n GroupDeleteResult) GetItem() interface{} { + return nil +} + func (n GroupDeleteResult) GetResponse() *api.Response { return n.response } diff --git a/api/hostcatalogs/host_catalog.gen.go b/api/hostcatalogs/host_catalog.gen.go index f9238a4e8..f047e62f8 100644 --- a/api/hostcatalogs/host_catalog.gen.go +++ b/api/hostcatalogs/host_catalog.gen.go @@ -51,6 +51,11 @@ type HostCatalogDeleteResult struct { response *api.Response } +// GetItem will always be nil for HostCatalogDeleteResult +func (n HostCatalogDeleteResult) GetItem() interface{} { + return nil +} + func (n HostCatalogDeleteResult) GetResponse() *api.Response { return n.response } diff --git a/api/hosts/host.gen.go b/api/hosts/host.gen.go index f94233355..d0545890c 100644 --- a/api/hosts/host.gen.go +++ b/api/hosts/host.gen.go @@ -51,6 +51,11 @@ type HostDeleteResult struct { response *api.Response } +// GetItem will always be nil for HostDeleteResult +func (n HostDeleteResult) GetItem() interface{} { + return nil +} + func (n HostDeleteResult) GetResponse() *api.Response { return n.response } diff --git a/api/hostsets/host_set.gen.go b/api/hostsets/host_set.gen.go index a1278da72..96184941f 100644 --- a/api/hostsets/host_set.gen.go +++ b/api/hostsets/host_set.gen.go @@ -51,6 +51,11 @@ type HostSetDeleteResult struct { response *api.Response } +// GetItem will always be nil for HostSetDeleteResult +func (n HostSetDeleteResult) GetItem() interface{} { + return nil +} + func (n HostSetDeleteResult) GetResponse() *api.Response { return n.response } diff --git a/api/response.go b/api/response.go index 189343e06..43be56709 100644 --- a/api/response.go +++ b/api/response.go @@ -33,6 +33,9 @@ func (r *Response) Decode(inStruct interface{}) (*Error, error) { } defer r.resp.Body.Close() + // Always allocate this buffer. It's okay if the bytes return `nil`. + r.Body = new(bytes.Buffer) + if r.resp.StatusCode == 204 { // Do nothing. return nil, nil diff --git a/api/roles/role.gen.go b/api/roles/role.gen.go index af6d28856..486e01ac7 100644 --- a/api/roles/role.gen.go +++ b/api/roles/role.gen.go @@ -53,6 +53,11 @@ type RoleDeleteResult struct { response *api.Response } +// GetItem will always be nil for RoleDeleteResult +func (n RoleDeleteResult) GetItem() interface{} { + return nil +} + func (n RoleDeleteResult) GetResponse() *api.Response { return n.response } diff --git a/api/scopes/scope.gen.go b/api/scopes/scope.gen.go index e87b45d22..1f34be548 100644 --- a/api/scopes/scope.gen.go +++ b/api/scopes/scope.gen.go @@ -50,6 +50,11 @@ type ScopeDeleteResult struct { response *api.Response } +// GetItem will always be nil for ScopeDeleteResult +func (n ScopeDeleteResult) GetItem() interface{} { + return nil +} + func (n ScopeDeleteResult) GetResponse() *api.Response { return n.response } diff --git a/api/sessions/session.gen.go b/api/sessions/session.gen.go index 2d68a6b95..59e4e7abc 100644 --- a/api/sessions/session.gen.go +++ b/api/sessions/session.gen.go @@ -58,6 +58,11 @@ type SessionDeleteResult struct { response *api.Response } +// GetItem will always be nil for SessionDeleteResult +func (n SessionDeleteResult) GetItem() interface{} { + return nil +} + func (n SessionDeleteResult) GetResponse() *api.Response { return n.response } diff --git a/api/targets/target.gen.go b/api/targets/target.gen.go index 4f9c528e1..6acf813a7 100644 --- a/api/targets/target.gen.go +++ b/api/targets/target.gen.go @@ -55,6 +55,11 @@ type TargetDeleteResult struct { response *api.Response } +// GetItem will always be nil for TargetDeleteResult +func (n TargetDeleteResult) GetItem() interface{} { + return nil +} + func (n TargetDeleteResult) GetResponse() *api.Response { return n.response } diff --git a/api/users/user.gen.go b/api/users/user.gen.go index 7473b817d..1ab9ace25 100644 --- a/api/users/user.gen.go +++ b/api/users/user.gen.go @@ -54,6 +54,11 @@ type UserDeleteResult struct { response *api.Response } +// GetItem will always be nil for UserDeleteResult +func (n UserDeleteResult) GetItem() interface{} { + return nil +} + func (n UserDeleteResult) GetResponse() *api.Response { return n.response } diff --git a/internal/api/genapi/templates.go b/internal/api/genapi/templates.go index cd743da58..104854728 100644 --- a/internal/api/genapi/templates.go +++ b/internal/api/genapi/templates.go @@ -569,6 +569,11 @@ type {{ .Name }}DeleteResult struct { response *api.Response } +// GetItem will always be nil for {{ .Name }}DeleteResult +func (n {{ .Name }}DeleteResult) GetItem() interface{} { + return nil +} + func (n {{ .Name }}DeleteResult) GetResponse() *api.Response { return n.response } diff --git a/internal/cmd/base/format.go b/internal/cmd/base/format.go index d520b5a1a..6280fd980 100644 --- a/internal/cmd/base/format.go +++ b/internal/cmd/base/format.go @@ -13,6 +13,7 @@ import ( "github.com/hashicorp/boundary/api/scopes" "github.com/mitchellh/cli" "github.com/mitchellh/go-wordwrap" + "github.com/pkg/errors" ) // This is adapted from the code in the strings package for TrimSpace @@ -229,19 +230,22 @@ func (c *Command) PrintCliError(err error) { } // PrintJsonItem prints the given item to the UI in JSON format -func (c *Command) PrintJsonItem(result api.GenericResult, item interface{}) bool { - output := struct { - StatusCode int `json:"status_code"` - Item interface{} `json:"item"` - }{ - Item: item, +func (c *Command) PrintJsonItem(result api.GenericResult) bool { + resp := result.GetResponse() + if resp == nil { + c.PrintCliError(errors.New("Error formatting as JSON: no response given to item formatter")) + return false } - if result.GetResponse() != nil && result.GetResponse().HttpResponse() != nil { - output.StatusCode = result.GetResponse().HttpResponse().StatusCode + output := struct { + StatusCode int `json:"status_code"` + Item json.RawMessage `json:"item,omitempty"` + }{ + StatusCode: resp.HttpResponse().StatusCode, + Item: resp.Body.Bytes(), } b, err := JsonFormatter{}.Format(output) if err != nil { - c.PrintCliError(err) + c.PrintCliError(fmt.Errorf("Error formatting as JSON: %w", err)) return false } c.UI.Output(string(b)) @@ -249,19 +253,36 @@ func (c *Command) PrintJsonItem(result api.GenericResult, item interface{}) bool } // PrintJsonItems prints the given items to the UI in JSON format -func (c *Command) PrintJsonItems(result api.GenericListResult, items []interface{}) bool { - output := struct { - StatusCode int `json:"status_code"` - Items []interface{} `json:"items"` - }{ - Items: items, +func (c *Command) PrintJsonItems(result api.GenericListResult) bool { + resp := result.GetResponse() + if resp == nil { + c.PrintCliError(errors.New("Error formatting as JSON: no response given to items formatter")) + return false } - if result.GetResponse() != nil && result.GetResponse().HttpResponse() != nil { - output.StatusCode = result.GetResponse().HttpResponse().StatusCode + // First we need to grab the items out. The reason is that if we simply + // embed the raw message as with PrintJsonItem above, it will have {"items": + // {"items": []}}. However, we decode into a RawMessage which makes it much + // more efficient on both the decoding and encoding side. + type inMsg struct { + Items json.RawMessage `json:"items"` + } + var input inMsg + if resp.Body.Bytes() != nil { + if err := json.Unmarshal(resp.Body.Bytes(), &input); err != nil { + c.PrintCliError(fmt.Errorf("Error unmarshaling response body at format time: %w", err)) + return false + } + } + output := struct { + StatusCode int `json:"status_code"` + Items json.RawMessage `json:"items"` + }{ + StatusCode: resp.HttpResponse().StatusCode, + Items: input.Items, } b, err := JsonFormatter{}.Format(output) if err != nil { - c.PrintCliError(err) + c.PrintCliError(fmt.Errorf("Error formatting as JSON: %w", err)) return false } c.UI.Output(string(b)) diff --git a/internal/cmd/commands/accountscmd/accounts.gen.go b/internal/cmd/commands/accountscmd/accounts.gen.go index 4640e84c4..e75f879b0 100644 --- a/internal/cmd/commands/accountscmd/accounts.gen.go +++ b/internal/cmd/commands/accountscmd/accounts.gen.go @@ -4,7 +4,6 @@ package accountscmd import ( "errors" "fmt" - "net/http" "sync" "github.com/hashicorp/boundary/api" @@ -206,8 +205,6 @@ func (c *Command) Run(args []string) int { return base.CommandUserError } - existed := true - var result api.GenericResult var listResult api.GenericListResult @@ -218,11 +215,7 @@ func (c *Command) Run(args []string) int { result, err = accountsClient.Read(c.Context, c.FlagId, opts...) case "delete": - _, err = accountsClient.Delete(c.Context, c.FlagId, opts...) - if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound { - existed = false - err = nil - } + result, err = accountsClient.Delete(c.Context, c.FlagId, opts...) case "list": listResult, err = accountsClient.List(c.Context, c.FlagAuthMethodId, opts...) @@ -254,41 +247,25 @@ func (c *Command) Run(args []string) int { case "delete": switch base.Format(c.UI) { case "json": - c.UI.Output(fmt.Sprintf("{ \"existed\": %t }", existed)) + if ok := c.PrintJsonItem(result); !ok { + return base.CommandCliError + } case "table": - output := "The delete operation completed successfully" - switch existed { - case true: - output += "." - default: - output += ", however the resource did not exist at the time." - } - c.UI.Output(output) + c.UI.Output("The delete operation completed successfully.") } return base.CommandSuccess case "list": - listedItems := listResult.GetItems().([]*accounts.Account) switch base.Format(c.UI) { case "json": - switch { - - case len(listedItems) == 0: - c.UI.Output("null") - - default: - items := make([]interface{}, len(listedItems)) - for i, v := range listedItems { - items[i] = v - } - if ok := c.PrintJsonItems(listResult, items); !ok { - return base.CommandCliError - } + if ok := c.PrintJsonItems(listResult); !ok { + return base.CommandCliError } case "table": + listedItems := listResult.GetItems().([]*accounts.Account) c.UI.Output(c.printListTable(listedItems)) } @@ -296,13 +273,13 @@ func (c *Command) Run(args []string) int { } - item := result.GetItem().(*accounts.Account) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*accounts.Account) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/cmd/commands/accountscmd/oidc_accounts.gen.go b/internal/cmd/commands/accountscmd/oidc_accounts.gen.go index 672c5aa34..aa8724eb2 100644 --- a/internal/cmd/commands/accountscmd/oidc_accounts.gen.go +++ b/internal/cmd/commands/accountscmd/oidc_accounts.gen.go @@ -214,13 +214,13 @@ func (c *OidcCommand) Run(args []string) int { switch c.Func { } - item := result.GetItem().(*accounts.Account) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*accounts.Account) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/cmd/commands/accountscmd/password_accounts.gen.go b/internal/cmd/commands/accountscmd/password_accounts.gen.go index 9077f5dff..c5ceb8f09 100644 --- a/internal/cmd/commands/accountscmd/password_accounts.gen.go +++ b/internal/cmd/commands/accountscmd/password_accounts.gen.go @@ -214,13 +214,13 @@ func (c *PasswordCommand) Run(args []string) int { switch c.Func { } - item := result.GetItem().(*accounts.Account) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*accounts.Account) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/cmd/commands/authenticate/funcs.go b/internal/cmd/commands/authenticate/funcs.go index ffd3f808a..4dcf15cbd 100644 --- a/internal/cmd/commands/authenticate/funcs.go +++ b/internal/cmd/commands/authenticate/funcs.go @@ -35,7 +35,7 @@ func saveAndOrPrintToken(c *base.Command, result *authmethods.AuthenticateResult if ok := c.PrintJsonItem(&dummyGenericResponse{ item: token, response: result.GetResponse(), - }, token); !ok { + }); !ok { return base.CommandCliError } return base.CommandSuccess diff --git a/internal/cmd/commands/authmethodscmd/authmethods.gen.go b/internal/cmd/commands/authmethodscmd/authmethods.gen.go index 427582169..6ce403e35 100644 --- a/internal/cmd/commands/authmethodscmd/authmethods.gen.go +++ b/internal/cmd/commands/authmethodscmd/authmethods.gen.go @@ -4,7 +4,6 @@ package authmethodscmd import ( "errors" "fmt" - "net/http" "sync" "github.com/hashicorp/boundary/api" @@ -173,8 +172,6 @@ func (c *Command) Run(args []string) int { return base.CommandUserError } - existed := true - var result api.GenericResult var listResult api.GenericListResult @@ -185,11 +182,7 @@ func (c *Command) Run(args []string) int { result, err = authmethodsClient.Read(c.Context, c.FlagId, opts...) case "delete": - _, err = authmethodsClient.Delete(c.Context, c.FlagId, opts...) - if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound { - existed = false - err = nil - } + result, err = authmethodsClient.Delete(c.Context, c.FlagId, opts...) case "list": listResult, err = authmethodsClient.List(c.Context, c.FlagScopeId, opts...) @@ -221,41 +214,25 @@ func (c *Command) Run(args []string) int { case "delete": switch base.Format(c.UI) { case "json": - c.UI.Output(fmt.Sprintf("{ \"existed\": %t }", existed)) + if ok := c.PrintJsonItem(result); !ok { + return base.CommandCliError + } case "table": - output := "The delete operation completed successfully" - switch existed { - case true: - output += "." - default: - output += ", however the resource did not exist at the time." - } - c.UI.Output(output) + c.UI.Output("The delete operation completed successfully.") } return base.CommandSuccess case "list": - listedItems := listResult.GetItems().([]*authmethods.AuthMethod) switch base.Format(c.UI) { case "json": - switch { - - case len(listedItems) == 0: - c.UI.Output("null") - - default: - items := make([]interface{}, len(listedItems)) - for i, v := range listedItems { - items[i] = v - } - if ok := c.PrintJsonItems(listResult, items); !ok { - return base.CommandCliError - } + if ok := c.PrintJsonItems(listResult); !ok { + return base.CommandCliError } case "table": + listedItems := listResult.GetItems().([]*authmethods.AuthMethod) c.UI.Output(c.printListTable(listedItems)) } @@ -263,13 +240,13 @@ func (c *Command) Run(args []string) int { } - item := result.GetItem().(*authmethods.AuthMethod) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*authmethods.AuthMethod) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/cmd/commands/authmethodscmd/oidc_authmethods.gen.go b/internal/cmd/commands/authmethodscmd/oidc_authmethods.gen.go index bf6963daa..1adc3e08f 100644 --- a/internal/cmd/commands/authmethodscmd/oidc_authmethods.gen.go +++ b/internal/cmd/commands/authmethodscmd/oidc_authmethods.gen.go @@ -229,13 +229,13 @@ func (c *OidcCommand) Run(args []string) int { switch c.Func { } - item := result.GetItem().(*authmethods.AuthMethod) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*authmethods.AuthMethod) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/cmd/commands/authmethodscmd/password_authmethods.gen.go b/internal/cmd/commands/authmethodscmd/password_authmethods.gen.go index 1e7d448c0..83b2d72ab 100644 --- a/internal/cmd/commands/authmethodscmd/password_authmethods.gen.go +++ b/internal/cmd/commands/authmethodscmd/password_authmethods.gen.go @@ -219,13 +219,13 @@ func (c *PasswordCommand) Run(args []string) int { switch c.Func { } - item := result.GetItem().(*authmethods.AuthMethod) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*authmethods.AuthMethod) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/cmd/commands/authtokenscmd/authtokens.gen.go b/internal/cmd/commands/authtokenscmd/authtokens.gen.go index 4e7923207..1f30377f3 100644 --- a/internal/cmd/commands/authtokenscmd/authtokens.gen.go +++ b/internal/cmd/commands/authtokenscmd/authtokens.gen.go @@ -4,7 +4,6 @@ package authtokenscmd import ( "errors" "fmt" - "net/http" "sync" "github.com/hashicorp/boundary/api" @@ -164,8 +163,6 @@ func (c *Command) Run(args []string) int { return base.CommandUserError } - existed := true - var result api.GenericResult var listResult api.GenericListResult @@ -176,11 +173,7 @@ func (c *Command) Run(args []string) int { result, err = authtokensClient.Read(c.Context, c.FlagId, opts...) case "delete": - _, err = authtokensClient.Delete(c.Context, c.FlagId, opts...) - if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound { - existed = false - err = nil - } + result, err = authtokensClient.Delete(c.Context, c.FlagId, opts...) case "list": listResult, err = authtokensClient.List(c.Context, c.FlagScopeId, opts...) @@ -212,41 +205,25 @@ func (c *Command) Run(args []string) int { case "delete": switch base.Format(c.UI) { case "json": - c.UI.Output(fmt.Sprintf("{ \"existed\": %t }", existed)) + if ok := c.PrintJsonItem(result); !ok { + return base.CommandCliError + } case "table": - output := "The delete operation completed successfully" - switch existed { - case true: - output += "." - default: - output += ", however the resource did not exist at the time." - } - c.UI.Output(output) + c.UI.Output("The delete operation completed successfully.") } return base.CommandSuccess case "list": - listedItems := listResult.GetItems().([]*authtokens.AuthToken) switch base.Format(c.UI) { case "json": - switch { - - case len(listedItems) == 0: - c.UI.Output("null") - - default: - items := make([]interface{}, len(listedItems)) - for i, v := range listedItems { - items[i] = v - } - if ok := c.PrintJsonItems(listResult, items); !ok { - return base.CommandCliError - } + if ok := c.PrintJsonItems(listResult); !ok { + return base.CommandCliError } case "table": + listedItems := listResult.GetItems().([]*authtokens.AuthToken) c.UI.Output(c.printListTable(listedItems)) } @@ -254,13 +231,13 @@ func (c *Command) Run(args []string) int { } - item := result.GetItem().(*authtokens.AuthToken) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*authtokens.AuthToken) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/cmd/commands/groupscmd/groups.gen.go b/internal/cmd/commands/groupscmd/groups.gen.go index 0d3b3e110..10e5252ae 100644 --- a/internal/cmd/commands/groupscmd/groups.gen.go +++ b/internal/cmd/commands/groupscmd/groups.gen.go @@ -4,7 +4,6 @@ package groupscmd import ( "errors" "fmt" - "net/http" "sync" "github.com/hashicorp/boundary/api" @@ -241,8 +240,6 @@ func (c *Command) Run(args []string) int { return base.CommandUserError } - existed := true - var result api.GenericResult var listResult api.GenericListResult @@ -259,11 +256,7 @@ func (c *Command) Run(args []string) int { result, err = groupsClient.Update(c.Context, c.FlagId, version, opts...) case "delete": - _, err = groupsClient.Delete(c.Context, c.FlagId, opts...) - if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound { - existed = false - err = nil - } + result, err = groupsClient.Delete(c.Context, c.FlagId, opts...) case "list": listResult, err = groupsClient.List(c.Context, c.FlagScopeId, opts...) @@ -295,41 +288,25 @@ func (c *Command) Run(args []string) int { case "delete": switch base.Format(c.UI) { case "json": - c.UI.Output(fmt.Sprintf("{ \"existed\": %t }", existed)) + if ok := c.PrintJsonItem(result); !ok { + return base.CommandCliError + } case "table": - output := "The delete operation completed successfully" - switch existed { - case true: - output += "." - default: - output += ", however the resource did not exist at the time." - } - c.UI.Output(output) + c.UI.Output("The delete operation completed successfully.") } return base.CommandSuccess case "list": - listedItems := listResult.GetItems().([]*groups.Group) switch base.Format(c.UI) { case "json": - switch { - - case len(listedItems) == 0: - c.UI.Output("null") - - default: - items := make([]interface{}, len(listedItems)) - for i, v := range listedItems { - items[i] = v - } - if ok := c.PrintJsonItems(listResult, items); !ok { - return base.CommandCliError - } + if ok := c.PrintJsonItems(listResult); !ok { + return base.CommandCliError } case "table": + listedItems := listResult.GetItems().([]*groups.Group) c.UI.Output(c.printListTable(listedItems)) } @@ -337,13 +314,13 @@ func (c *Command) Run(args []string) int { } - item := result.GetItem().(*groups.Group) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*groups.Group) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/cmd/commands/hostcatalogscmd/hostcatalogs.gen.go b/internal/cmd/commands/hostcatalogscmd/hostcatalogs.gen.go index 5ba1cbeb4..96b348c35 100644 --- a/internal/cmd/commands/hostcatalogscmd/hostcatalogs.gen.go +++ b/internal/cmd/commands/hostcatalogscmd/hostcatalogs.gen.go @@ -4,7 +4,6 @@ package hostcatalogscmd import ( "errors" "fmt" - "net/http" "sync" "github.com/hashicorp/boundary/api" @@ -173,8 +172,6 @@ func (c *Command) Run(args []string) int { return base.CommandUserError } - existed := true - var result api.GenericResult var listResult api.GenericListResult @@ -185,11 +182,7 @@ func (c *Command) Run(args []string) int { result, err = hostcatalogsClient.Read(c.Context, c.FlagId, opts...) case "delete": - _, err = hostcatalogsClient.Delete(c.Context, c.FlagId, opts...) - if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound { - existed = false - err = nil - } + result, err = hostcatalogsClient.Delete(c.Context, c.FlagId, opts...) case "list": listResult, err = hostcatalogsClient.List(c.Context, c.FlagScopeId, opts...) @@ -221,41 +214,25 @@ func (c *Command) Run(args []string) int { case "delete": switch base.Format(c.UI) { case "json": - c.UI.Output(fmt.Sprintf("{ \"existed\": %t }", existed)) + if ok := c.PrintJsonItem(result); !ok { + return base.CommandCliError + } case "table": - output := "The delete operation completed successfully" - switch existed { - case true: - output += "." - default: - output += ", however the resource did not exist at the time." - } - c.UI.Output(output) + c.UI.Output("The delete operation completed successfully.") } return base.CommandSuccess case "list": - listedItems := listResult.GetItems().([]*hostcatalogs.HostCatalog) switch base.Format(c.UI) { case "json": - switch { - - case len(listedItems) == 0: - c.UI.Output("null") - - default: - items := make([]interface{}, len(listedItems)) - for i, v := range listedItems { - items[i] = v - } - if ok := c.PrintJsonItems(listResult, items); !ok { - return base.CommandCliError - } + if ok := c.PrintJsonItems(listResult); !ok { + return base.CommandCliError } case "table": + listedItems := listResult.GetItems().([]*hostcatalogs.HostCatalog) c.UI.Output(c.printListTable(listedItems)) } @@ -263,13 +240,13 @@ func (c *Command) Run(args []string) int { } - item := result.GetItem().(*hostcatalogs.HostCatalog) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*hostcatalogs.HostCatalog) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/cmd/commands/hostcatalogscmd/static_hostcatalogs.gen.go b/internal/cmd/commands/hostcatalogscmd/static_hostcatalogs.gen.go index 12faa906f..f5d4edd9c 100644 --- a/internal/cmd/commands/hostcatalogscmd/static_hostcatalogs.gen.go +++ b/internal/cmd/commands/hostcatalogscmd/static_hostcatalogs.gen.go @@ -217,13 +217,13 @@ func (c *StaticCommand) Run(args []string) int { switch c.Func { } - item := result.GetItem().(*hostcatalogs.HostCatalog) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*hostcatalogs.HostCatalog) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/cmd/commands/hostscmd/hosts.gen.go b/internal/cmd/commands/hostscmd/hosts.gen.go index 27f8e7c27..ace10fff0 100644 --- a/internal/cmd/commands/hostscmd/hosts.gen.go +++ b/internal/cmd/commands/hostscmd/hosts.gen.go @@ -4,7 +4,6 @@ package hostscmd import ( "errors" "fmt" - "net/http" "sync" "github.com/hashicorp/boundary/api" @@ -184,8 +183,6 @@ func (c *Command) Run(args []string) int { return base.CommandUserError } - existed := true - var result api.GenericResult var listResult api.GenericListResult @@ -196,11 +193,7 @@ func (c *Command) Run(args []string) int { result, err = hostsClient.Read(c.Context, c.FlagId, opts...) case "delete": - _, err = hostsClient.Delete(c.Context, c.FlagId, opts...) - if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound { - existed = false - err = nil - } + result, err = hostsClient.Delete(c.Context, c.FlagId, opts...) case "list": listResult, err = hostsClient.List(c.Context, c.FlagHostCatalogId, opts...) @@ -232,41 +225,25 @@ func (c *Command) Run(args []string) int { case "delete": switch base.Format(c.UI) { case "json": - c.UI.Output(fmt.Sprintf("{ \"existed\": %t }", existed)) + if ok := c.PrintJsonItem(result); !ok { + return base.CommandCliError + } case "table": - output := "The delete operation completed successfully" - switch existed { - case true: - output += "." - default: - output += ", however the resource did not exist at the time." - } - c.UI.Output(output) + c.UI.Output("The delete operation completed successfully.") } return base.CommandSuccess case "list": - listedItems := listResult.GetItems().([]*hosts.Host) switch base.Format(c.UI) { case "json": - switch { - - case len(listedItems) == 0: - c.UI.Output("null") - - default: - items := make([]interface{}, len(listedItems)) - for i, v := range listedItems { - items[i] = v - } - if ok := c.PrintJsonItems(listResult, items); !ok { - return base.CommandCliError - } + if ok := c.PrintJsonItems(listResult); !ok { + return base.CommandCliError } case "table": + listedItems := listResult.GetItems().([]*hosts.Host) c.UI.Output(c.printListTable(listedItems)) } @@ -274,13 +251,13 @@ func (c *Command) Run(args []string) int { } - item := result.GetItem().(*hosts.Host) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*hosts.Host) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/cmd/commands/hostscmd/static_hosts.gen.go b/internal/cmd/commands/hostscmd/static_hosts.gen.go index 0c53acedb..0332c0f58 100644 --- a/internal/cmd/commands/hostscmd/static_hosts.gen.go +++ b/internal/cmd/commands/hostscmd/static_hosts.gen.go @@ -214,13 +214,13 @@ func (c *StaticCommand) Run(args []string) int { switch c.Func { } - item := result.GetItem().(*hosts.Host) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*hosts.Host) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/cmd/commands/hostsetscmd/hostsets.gen.go b/internal/cmd/commands/hostsetscmd/hostsets.gen.go index 5a19c07bf..b7c630ecc 100644 --- a/internal/cmd/commands/hostsetscmd/hostsets.gen.go +++ b/internal/cmd/commands/hostsetscmd/hostsets.gen.go @@ -4,7 +4,6 @@ package hostsetscmd import ( "errors" "fmt" - "net/http" "sync" "github.com/hashicorp/boundary/api" @@ -214,8 +213,6 @@ func (c *Command) Run(args []string) int { return base.CommandUserError } - existed := true - var result api.GenericResult var listResult api.GenericListResult @@ -226,11 +223,7 @@ func (c *Command) Run(args []string) int { result, err = hostsetsClient.Read(c.Context, c.FlagId, opts...) case "delete": - _, err = hostsetsClient.Delete(c.Context, c.FlagId, opts...) - if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound { - existed = false - err = nil - } + result, err = hostsetsClient.Delete(c.Context, c.FlagId, opts...) case "list": listResult, err = hostsetsClient.List(c.Context, c.FlagHostCatalogId, opts...) @@ -262,41 +255,25 @@ func (c *Command) Run(args []string) int { case "delete": switch base.Format(c.UI) { case "json": - c.UI.Output(fmt.Sprintf("{ \"existed\": %t }", existed)) + if ok := c.PrintJsonItem(result); !ok { + return base.CommandCliError + } case "table": - output := "The delete operation completed successfully" - switch existed { - case true: - output += "." - default: - output += ", however the resource did not exist at the time." - } - c.UI.Output(output) + c.UI.Output("The delete operation completed successfully.") } return base.CommandSuccess case "list": - listedItems := listResult.GetItems().([]*hostsets.HostSet) switch base.Format(c.UI) { case "json": - switch { - - case len(listedItems) == 0: - c.UI.Output("null") - - default: - items := make([]interface{}, len(listedItems)) - for i, v := range listedItems { - items[i] = v - } - if ok := c.PrintJsonItems(listResult, items); !ok { - return base.CommandCliError - } + if ok := c.PrintJsonItems(listResult); !ok { + return base.CommandCliError } case "table": + listedItems := listResult.GetItems().([]*hostsets.HostSet) c.UI.Output(c.printListTable(listedItems)) } @@ -304,13 +281,13 @@ func (c *Command) Run(args []string) int { } - item := result.GetItem().(*hostsets.HostSet) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*hostsets.HostSet) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/cmd/commands/hostsetscmd/static_hostsets.gen.go b/internal/cmd/commands/hostsetscmd/static_hostsets.gen.go index 6a2c382f4..19c5eaed9 100644 --- a/internal/cmd/commands/hostsetscmd/static_hostsets.gen.go +++ b/internal/cmd/commands/hostsetscmd/static_hostsets.gen.go @@ -212,13 +212,13 @@ func (c *StaticCommand) Run(args []string) int { switch c.Func { } - item := result.GetItem().(*hostsets.HostSet) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*hostsets.HostSet) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/cmd/commands/rolescmd/roles.gen.go b/internal/cmd/commands/rolescmd/roles.gen.go index 4d240ff9f..4cb779638 100644 --- a/internal/cmd/commands/rolescmd/roles.gen.go +++ b/internal/cmd/commands/rolescmd/roles.gen.go @@ -4,7 +4,6 @@ package rolescmd import ( "errors" "fmt" - "net/http" "sync" "github.com/hashicorp/boundary/api" @@ -265,8 +264,6 @@ func (c *Command) Run(args []string) int { return base.CommandUserError } - existed := true - var result api.GenericResult var listResult api.GenericListResult @@ -283,11 +280,7 @@ func (c *Command) Run(args []string) int { result, err = rolesClient.Update(c.Context, c.FlagId, version, opts...) case "delete": - _, err = rolesClient.Delete(c.Context, c.FlagId, opts...) - if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound { - existed = false - err = nil - } + result, err = rolesClient.Delete(c.Context, c.FlagId, opts...) case "list": listResult, err = rolesClient.List(c.Context, c.FlagScopeId, opts...) @@ -319,41 +312,25 @@ func (c *Command) Run(args []string) int { case "delete": switch base.Format(c.UI) { case "json": - c.UI.Output(fmt.Sprintf("{ \"existed\": %t }", existed)) + if ok := c.PrintJsonItem(result); !ok { + return base.CommandCliError + } case "table": - output := "The delete operation completed successfully" - switch existed { - case true: - output += "." - default: - output += ", however the resource did not exist at the time." - } - c.UI.Output(output) + c.UI.Output("The delete operation completed successfully.") } return base.CommandSuccess case "list": - listedItems := listResult.GetItems().([]*roles.Role) switch base.Format(c.UI) { case "json": - switch { - - case len(listedItems) == 0: - c.UI.Output("null") - - default: - items := make([]interface{}, len(listedItems)) - for i, v := range listedItems { - items[i] = v - } - if ok := c.PrintJsonItems(listResult, items); !ok { - return base.CommandCliError - } + if ok := c.PrintJsonItems(listResult); !ok { + return base.CommandCliError } case "table": + listedItems := listResult.GetItems().([]*roles.Role) c.UI.Output(c.printListTable(listedItems)) } @@ -361,13 +338,13 @@ func (c *Command) Run(args []string) int { } - item := result.GetItem().(*roles.Role) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*roles.Role) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/cmd/commands/scopescmd/scopes.gen.go b/internal/cmd/commands/scopescmd/scopes.gen.go index 0d15fb770..68b832aa5 100644 --- a/internal/cmd/commands/scopescmd/scopes.gen.go +++ b/internal/cmd/commands/scopescmd/scopes.gen.go @@ -4,7 +4,6 @@ package scopescmd import ( "errors" "fmt" - "net/http" "sync" "github.com/hashicorp/boundary/api" @@ -215,8 +214,6 @@ func (c *Command) Run(args []string) int { return base.CommandUserError } - existed := true - var result api.GenericResult var listResult api.GenericListResult @@ -233,11 +230,7 @@ func (c *Command) Run(args []string) int { result, err = scopesClient.Update(c.Context, c.FlagId, version, opts...) case "delete": - _, err = scopesClient.Delete(c.Context, c.FlagId, opts...) - if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound { - existed = false - err = nil - } + result, err = scopesClient.Delete(c.Context, c.FlagId, opts...) case "list": listResult, err = scopesClient.List(c.Context, c.FlagScopeId, opts...) @@ -269,41 +262,25 @@ func (c *Command) Run(args []string) int { case "delete": switch base.Format(c.UI) { case "json": - c.UI.Output(fmt.Sprintf("{ \"existed\": %t }", existed)) + if ok := c.PrintJsonItem(result); !ok { + return base.CommandCliError + } case "table": - output := "The delete operation completed successfully" - switch existed { - case true: - output += "." - default: - output += ", however the resource did not exist at the time." - } - c.UI.Output(output) + c.UI.Output("The delete operation completed successfully.") } return base.CommandSuccess case "list": - listedItems := listResult.GetItems().([]*scopes.Scope) switch base.Format(c.UI) { case "json": - switch { - - case len(listedItems) == 0: - c.UI.Output("null") - - default: - items := make([]interface{}, len(listedItems)) - for i, v := range listedItems { - items[i] = v - } - if ok := c.PrintJsonItems(listResult, items); !ok { - return base.CommandCliError - } + if ok := c.PrintJsonItems(listResult); !ok { + return base.CommandCliError } case "table": + listedItems := listResult.GetItems().([]*scopes.Scope) c.UI.Output(c.printListTable(listedItems)) } @@ -311,13 +288,13 @@ func (c *Command) Run(args []string) int { } - item := result.GetItem().(*scopes.Scope) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*scopes.Scope) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/cmd/commands/sessionscmd/sessions.gen.go b/internal/cmd/commands/sessionscmd/sessions.gen.go index ca6fec876..a0fe32fa6 100644 --- a/internal/cmd/commands/sessionscmd/sessions.gen.go +++ b/internal/cmd/commands/sessionscmd/sessions.gen.go @@ -209,38 +209,27 @@ func (c *Command) Run(args []string) int { switch c.Func { case "list": - listedItems := listResult.GetItems().([]*sessions.Session) switch base.Format(c.UI) { case "json": - switch { - - case len(listedItems) == 0: - c.UI.Output("null") - - default: - items := make([]interface{}, len(listedItems)) - for i, v := range listedItems { - items[i] = v - } - if ok := c.PrintJsonItems(listResult, items); !ok { - return base.CommandCliError - } + if ok := c.PrintJsonItems(listResult); !ok { + return base.CommandCliError } case "table": + listedItems := listResult.GetItems().([]*sessions.Session) c.UI.Output(c.printListTable(listedItems)) } return base.CommandSuccess } - item := result.GetItem().(*sessions.Session) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*sessions.Session) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/cmd/commands/targetscmd/funcs.go b/internal/cmd/commands/targetscmd/funcs.go index 34af0aeb6..0813f7a57 100644 --- a/internal/cmd/commands/targetscmd/funcs.go +++ b/internal/cmd/commands/targetscmd/funcs.go @@ -444,7 +444,7 @@ func printCustomActionOutputImpl(c *Command) (bool, error) { return true, nil case "json": - if ok := c.PrintJsonItem(c.sar, item); !ok { + if ok := c.PrintJsonItem(c.sar); !ok { return false, fmt.Errorf("Error formatting as JSON") } return true, nil diff --git a/internal/cmd/commands/targetscmd/targets.gen.go b/internal/cmd/commands/targetscmd/targets.gen.go index 880a35238..f4fc9a1ed 100644 --- a/internal/cmd/commands/targetscmd/targets.gen.go +++ b/internal/cmd/commands/targetscmd/targets.gen.go @@ -4,7 +4,6 @@ package targetscmd import ( "errors" "fmt" - "net/http" "os" "sync" @@ -220,8 +219,6 @@ func (c *Command) Run(args []string) int { return base.CommandUserError } - existed := true - var result api.GenericResult var listResult api.GenericListResult @@ -232,11 +229,7 @@ func (c *Command) Run(args []string) int { result, err = targetsClient.Read(c.Context, c.FlagId, opts...) case "delete": - _, err = targetsClient.Delete(c.Context, c.FlagId, opts...) - if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound { - existed = false - err = nil - } + result, err = targetsClient.Delete(c.Context, c.FlagId, opts...) case "list": listResult, err = targetsClient.List(c.Context, c.FlagScopeId, opts...) @@ -268,41 +261,25 @@ func (c *Command) Run(args []string) int { case "delete": switch base.Format(c.UI) { case "json": - c.UI.Output(fmt.Sprintf("{ \"existed\": %t }", existed)) + if ok := c.PrintJsonItem(result); !ok { + return base.CommandCliError + } case "table": - output := "The delete operation completed successfully" - switch existed { - case true: - output += "." - default: - output += ", however the resource did not exist at the time." - } - c.UI.Output(output) + c.UI.Output("The delete operation completed successfully.") } return base.CommandSuccess case "list": - listedItems := listResult.GetItems().([]*targets.Target) switch base.Format(c.UI) { case "json": - switch { - - case len(listedItems) == 0: - c.UI.Output("null") - - default: - items := make([]interface{}, len(listedItems)) - for i, v := range listedItems { - items[i] = v - } - if ok := c.PrintJsonItems(listResult, items); !ok { - return base.CommandCliError - } + if ok := c.PrintJsonItems(listResult); !ok { + return base.CommandCliError } case "table": + listedItems := listResult.GetItems().([]*targets.Target) c.UI.Output(c.printListTable(listedItems)) } @@ -310,13 +287,13 @@ func (c *Command) Run(args []string) int { } - item := result.GetItem().(*targets.Target) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*targets.Target) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/cmd/commands/targetscmd/tcp_targets.gen.go b/internal/cmd/commands/targetscmd/tcp_targets.gen.go index a8ba7237d..aa0ebf382 100644 --- a/internal/cmd/commands/targetscmd/tcp_targets.gen.go +++ b/internal/cmd/commands/targetscmd/tcp_targets.gen.go @@ -219,13 +219,13 @@ func (c *TcpCommand) Run(args []string) int { switch c.Func { } - item := result.GetItem().(*targets.Target) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*targets.Target) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/cmd/commands/userscmd/users.gen.go b/internal/cmd/commands/userscmd/users.gen.go index f0bf6c42c..5b93677d3 100644 --- a/internal/cmd/commands/userscmd/users.gen.go +++ b/internal/cmd/commands/userscmd/users.gen.go @@ -4,7 +4,6 @@ package userscmd import ( "errors" "fmt" - "net/http" "sync" "github.com/hashicorp/boundary/api" @@ -241,8 +240,6 @@ func (c *Command) Run(args []string) int { return base.CommandUserError } - existed := true - var result api.GenericResult var listResult api.GenericListResult @@ -259,11 +256,7 @@ func (c *Command) Run(args []string) int { result, err = usersClient.Update(c.Context, c.FlagId, version, opts...) case "delete": - _, err = usersClient.Delete(c.Context, c.FlagId, opts...) - if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound { - existed = false - err = nil - } + result, err = usersClient.Delete(c.Context, c.FlagId, opts...) case "list": listResult, err = usersClient.List(c.Context, c.FlagScopeId, opts...) @@ -295,41 +288,25 @@ func (c *Command) Run(args []string) int { case "delete": switch base.Format(c.UI) { case "json": - c.UI.Output(fmt.Sprintf("{ \"existed\": %t }", existed)) + if ok := c.PrintJsonItem(result); !ok { + return base.CommandCliError + } case "table": - output := "The delete operation completed successfully" - switch existed { - case true: - output += "." - default: - output += ", however the resource did not exist at the time." - } - c.UI.Output(output) + c.UI.Output("The delete operation completed successfully.") } return base.CommandSuccess case "list": - listedItems := listResult.GetItems().([]*users.User) switch base.Format(c.UI) { case "json": - switch { - - case len(listedItems) == 0: - c.UI.Output("null") - - default: - items := make([]interface{}, len(listedItems)) - for i, v := range listedItems { - items[i] = v - } - if ok := c.PrintJsonItems(listResult, items); !ok { - return base.CommandCliError - } + if ok := c.PrintJsonItems(listResult); !ok { + return base.CommandCliError } case "table": + listedItems := listResult.GetItems().([]*users.User) c.UI.Output(c.printListTable(listedItems)) } @@ -337,13 +314,13 @@ func (c *Command) Run(args []string) int { } - item := result.GetItem().(*users.User) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*users.User) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/cmd/gencli/templates.go b/internal/cmd/gencli/templates.go index 29df4bf3f..c72e6ac22 100644 --- a/internal/cmd/gencli/templates.go +++ b/internal/cmd/gencli/templates.go @@ -327,9 +327,6 @@ func (c *{{ camelCase .SubActionPrefix }}Command) Run(args []string) int { return base.CommandUserError } - {{ if hasAction .StdActions "delete" }} - existed := true - {{ end }} var result api.GenericResult {{ if hasAction .StdActions "list" }} var listResult api.GenericListResult @@ -351,11 +348,7 @@ func (c *{{ camelCase .SubActionPrefix }}Command) Run(args []string) int { {{ end }} {{ if eq $action "delete" }} case "delete": - _, err = {{ $input.Pkg}}Client.Delete(c.Context, c.FlagId, opts...) - if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Response().StatusCode() == http.StatusNotFound { - existed = false - err = nil - } + result, err = {{ $input.Pkg }}Client.Delete(c.Context, c.FlagId, opts...) {{ end }} {{ if eq $action "list" }} case "list": @@ -390,42 +383,26 @@ func (c *{{ camelCase .SubActionPrefix }}Command) Run(args []string) int { case "delete": switch base.Format(c.UI) { case "json": - c.UI.Output(fmt.Sprintf("{ \"existed\": %t }", existed)) + if ok := c.PrintJsonItem(result); !ok { + return base.CommandCliError + } case "table": - output := "The delete operation completed successfully" - switch existed { - case true: - output += "." - default: - output += ", however the resource did not exist at the time." - } - c.UI.Output(output) + c.UI.Output("The delete operation completed successfully.") } return base.CommandSuccess {{ end }} {{ if eq $action "list" }} case "list": - listedItems := listResult.GetItems().([]*{{ $input.Pkg }}.{{ camelCase $input.ResourceType }}) switch base.Format(c.UI) { case "json": - switch { - - case len(listedItems) == 0: - c.UI.Output("null") - - default: - items := make([]interface{}, len(listedItems)) - for i, v := range listedItems { - items[i] = v - } - if ok := c.PrintJsonItems(listResult, items); !ok { - return base.CommandCliError - } + if ok := c.PrintJsonItems(listResult); !ok { + return base.CommandCliError } case "table": + listedItems := listResult.GetItems().([]*{{ $input.Pkg }}.{{ camelCase $input.ResourceType }}) c.UI.Output(c.printListTable(listedItems)) } @@ -434,13 +411,13 @@ func (c *{{ camelCase .SubActionPrefix }}Command) Run(args []string) int { {{ end }} } - item := result.GetItem().(*{{ .Pkg }}.{{ camelCase .ResourceType }}) switch base.Format(c.UI) { case "table": + item := result.GetItem().(*{{ .Pkg }}.{{ camelCase .ResourceType }}) c.UI.Output(printItemTable(item)) case "json": - if ok := c.PrintJsonItem(result, item); !ok { + if ok := c.PrintJsonItem(result); !ok { return base.CommandCliError } } diff --git a/internal/servers/controller/handlers/accounts/account_service.go b/internal/servers/controller/handlers/accounts/account_service.go index 8f0444e90..2d228faf3 100644 --- a/internal/servers/controller/handlers/accounts/account_service.go +++ b/internal/servers/controller/handlers/accounts/account_service.go @@ -210,7 +210,7 @@ func (s Service) DeleteAccount(ctx context.Context, req *pbs.DeleteAccountReques if err != nil { return nil, err } - return &pbs.DeleteAccountResponse{}, nil + return nil, nil } // ChangePassword implements the interface pbs.AccountServiceServer. diff --git a/internal/servers/controller/handlers/accounts/account_service_test.go b/internal/servers/controller/handlers/accounts/account_service_test.go index 2c1221f3a..444d77808 100644 --- a/internal/servers/controller/handlers/accounts/account_service_test.go +++ b/internal/servers/controller/handlers/accounts/account_service_test.go @@ -517,14 +517,12 @@ func TestDelete(t *testing.T) { req: &pbs.DeleteAccountRequest{ Id: ac.GetPublicId(), }, - res: &pbs.DeleteAccountResponse{}, }, { name: "Delete an existing oidc account", req: &pbs.DeleteAccountRequest{ Id: oidcA.GetPublicId(), }, - res: &pbs.DeleteAccountResponse{}, }, { name: "Delete bad pw account id", diff --git a/internal/servers/controller/handlers/authmethods/authmethod_service.go b/internal/servers/controller/handlers/authmethods/authmethod_service.go index cc17f0ce0..95723aa3c 100644 --- a/internal/servers/controller/handlers/authmethods/authmethod_service.go +++ b/internal/servers/controller/handlers/authmethods/authmethod_service.go @@ -293,7 +293,7 @@ func (s Service) DeleteAuthMethod(ctx context.Context, req *pbs.DeleteAuthMethod if err != nil { return nil, err } - return &pbs.DeleteAuthMethodResponse{}, nil + return nil, nil } // Authenticate implements the interface pbs.AuthenticationServiceServer. diff --git a/internal/servers/controller/handlers/authmethods/authmethod_service_test.go b/internal/servers/controller/handlers/authmethods/authmethod_service_test.go index 076bb625f..0a3465faa 100644 --- a/internal/servers/controller/handlers/authmethods/authmethod_service_test.go +++ b/internal/servers/controller/handlers/authmethods/authmethod_service_test.go @@ -423,14 +423,12 @@ func TestDelete(t *testing.T) { req: &pbs.DeleteAuthMethodRequest{ Id: pwam.GetPublicId(), }, - res: &pbs.DeleteAuthMethodResponse{}, }, { name: "Delete an Existing OIDC AuthMethod", req: &pbs.DeleteAuthMethodRequest{ Id: oidcam.GetPublicId(), }, - res: &pbs.DeleteAuthMethodResponse{}, }, { name: "Delete bad auth_method id", diff --git a/internal/servers/controller/handlers/authtokens/authtoken_service.go b/internal/servers/controller/handlers/authtokens/authtoken_service.go index 556966c4f..8d5386e1f 100644 --- a/internal/servers/controller/handlers/authtokens/authtoken_service.go +++ b/internal/servers/controller/handlers/authtokens/authtoken_service.go @@ -172,7 +172,7 @@ func (s Service) DeleteAuthToken(ctx context.Context, req *pbs.DeleteAuthTokenRe if err != nil { return nil, err } - return &pbs.DeleteAuthTokenResponse{}, nil + return nil, nil } func (s Service) getFromRepo(ctx context.Context, id string) (*pb.AuthToken, error) { diff --git a/internal/servers/controller/handlers/authtokens/authtoken_service_test.go b/internal/servers/controller/handlers/authtokens/authtoken_service_test.go index 0589fc99f..d68cae9ad 100644 --- a/internal/servers/controller/handlers/authtokens/authtoken_service_test.go +++ b/internal/servers/controller/handlers/authtokens/authtoken_service_test.go @@ -522,7 +522,6 @@ func TestDelete(t *testing.T) { req: &pbs.DeleteAuthTokenRequest{ Id: at.GetPublicId(), }, - res: &pbs.DeleteAuthTokenResponse{}, }, { name: "Delete bad token id", diff --git a/internal/servers/controller/handlers/groups/group_service.go b/internal/servers/controller/handlers/groups/group_service.go index 45153e772..f56c84f72 100644 --- a/internal/servers/controller/handlers/groups/group_service.go +++ b/internal/servers/controller/handlers/groups/group_service.go @@ -191,7 +191,7 @@ func (s Service) DeleteGroup(ctx context.Context, req *pbs.DeleteGroupRequest) ( if err != nil { return nil, err } - return &pbs.DeleteGroupResponse{}, nil + return nil, nil } // AddGroupMembers implements the interface pbs.GroupServiceServer. diff --git a/internal/servers/controller/handlers/groups/group_service_test.go b/internal/servers/controller/handlers/groups/group_service_test.go index 333b4163b..4ad49b887 100644 --- a/internal/servers/controller/handlers/groups/group_service_test.go +++ b/internal/servers/controller/handlers/groups/group_service_test.go @@ -348,7 +348,6 @@ func TestDelete(t *testing.T) { req: &pbs.DeleteGroupRequest{ Id: og.GetPublicId(), }, - res: &pbs.DeleteGroupResponse{}, }, { name: "Delete bad group id", @@ -372,7 +371,6 @@ func TestDelete(t *testing.T) { req: &pbs.DeleteGroupRequest{ Id: pg.GetPublicId(), }, - res: &pbs.DeleteGroupResponse{}, }, { name: "Project Scoped Delete bad group id", diff --git a/internal/servers/controller/handlers/host_catalogs/host_catalog_service.go b/internal/servers/controller/handlers/host_catalogs/host_catalog_service.go index e0b176331..e552dedd6 100644 --- a/internal/servers/controller/handlers/host_catalogs/host_catalog_service.go +++ b/internal/servers/controller/handlers/host_catalogs/host_catalog_service.go @@ -243,7 +243,7 @@ func (s Service) DeleteHostCatalog(ctx context.Context, req *pbs.DeleteHostCatal if err != nil { return nil, err } - return &pbs.DeleteHostCatalogResponse{}, nil + return nil, nil } func (s Service) getFromRepo(ctx context.Context, id string) (*pb.HostCatalog, error) { diff --git a/internal/servers/controller/handlers/host_catalogs/host_catalog_service_test.go b/internal/servers/controller/handlers/host_catalogs/host_catalog_service_test.go index 54062e8e6..d7b341bda 100644 --- a/internal/servers/controller/handlers/host_catalogs/host_catalog_service_test.go +++ b/internal/servers/controller/handlers/host_catalogs/host_catalog_service_test.go @@ -289,7 +289,6 @@ func TestDelete(t *testing.T) { req: &pbs.DeleteHostCatalogRequest{ Id: hc.GetPublicId(), }, - res: &pbs.DeleteHostCatalogResponse{}, }, { name: "Delete bad id HostCatalog", diff --git a/internal/servers/controller/handlers/host_sets/host_set_service.go b/internal/servers/controller/handlers/host_sets/host_set_service.go index f3a32e7ed..816e99cda 100644 --- a/internal/servers/controller/handlers/host_sets/host_set_service.go +++ b/internal/servers/controller/handlers/host_sets/host_set_service.go @@ -174,7 +174,7 @@ func (s Service) DeleteHostSet(ctx context.Context, req *pbs.DeleteHostSetReques if err != nil { return nil, err } - return &pbs.DeleteHostSetResponse{}, nil + return nil, nil } // AddHostSetHosts implements the interface pbs.HostSetServiceServer. diff --git a/internal/servers/controller/handlers/host_sets/host_set_service_test.go b/internal/servers/controller/handlers/host_sets/host_set_service_test.go index 6eeaf1a8c..42707ec89 100644 --- a/internal/servers/controller/handlers/host_sets/host_set_service_test.go +++ b/internal/servers/controller/handlers/host_sets/host_set_service_test.go @@ -242,7 +242,6 @@ func TestDelete(t *testing.T) { req: &pbs.DeleteHostSetRequest{ Id: h.GetPublicId(), }, - res: &pbs.DeleteHostSetResponse{}, }, { name: "Delete bad id Host Set", diff --git a/internal/servers/controller/handlers/hosts/host_service.go b/internal/servers/controller/handlers/hosts/host_service.go index a5521e5ac..cd1400dbb 100644 --- a/internal/servers/controller/handlers/hosts/host_service.go +++ b/internal/servers/controller/handlers/hosts/host_service.go @@ -172,7 +172,7 @@ func (s Service) DeleteHost(ctx context.Context, req *pbs.DeleteHostRequest) (*p if err != nil { return nil, err } - return &pbs.DeleteHostResponse{}, nil + return nil, nil } func (s Service) getFromRepo(ctx context.Context, id string) (*pb.Host, error) { diff --git a/internal/servers/controller/handlers/hosts/host_service_test.go b/internal/servers/controller/handlers/hosts/host_service_test.go index 2a35d4014..15a172489 100644 --- a/internal/servers/controller/handlers/hosts/host_service_test.go +++ b/internal/servers/controller/handlers/hosts/host_service_test.go @@ -237,7 +237,6 @@ func TestDelete(t *testing.T) { req: &pbs.DeleteHostRequest{ Id: h.GetPublicId(), }, - res: &pbs.DeleteHostResponse{}, }, { name: "Delete bad id Host", diff --git a/internal/servers/controller/handlers/roles/role_service.go b/internal/servers/controller/handlers/roles/role_service.go index a11deffbd..305c3ea62 100644 --- a/internal/servers/controller/handlers/roles/role_service.go +++ b/internal/servers/controller/handlers/roles/role_service.go @@ -195,7 +195,7 @@ func (s Service) DeleteRole(ctx context.Context, req *pbs.DeleteRoleRequest) (*p if err != nil { return nil, err } - return &pbs.DeleteRoleResponse{}, nil + return nil, nil } // AddRolePrincipals implements the interface pbs.RoleServiceServer. diff --git a/internal/servers/controller/handlers/roles/role_service_test.go b/internal/servers/controller/handlers/roles/role_service_test.go index b04f53294..2408a7a96 100644 --- a/internal/servers/controller/handlers/roles/role_service_test.go +++ b/internal/servers/controller/handlers/roles/role_service_test.go @@ -325,7 +325,6 @@ func TestDelete(t *testing.T) { req: &pbs.DeleteRoleRequest{ Id: or.GetPublicId(), }, - res: &pbs.DeleteRoleResponse{}, }, { name: "Delete bad role id", @@ -349,7 +348,6 @@ func TestDelete(t *testing.T) { req: &pbs.DeleteRoleRequest{ Id: pr.GetPublicId(), }, - res: &pbs.DeleteRoleResponse{}, }, { name: "Project Scoped Delete bad Role id", diff --git a/internal/servers/controller/handlers/scopes/scope_service.go b/internal/servers/controller/handlers/scopes/scope_service.go index 3e4af8099..c4c6734b6 100644 --- a/internal/servers/controller/handlers/scopes/scope_service.go +++ b/internal/servers/controller/handlers/scopes/scope_service.go @@ -270,7 +270,7 @@ func (s Service) DeleteScope(ctx context.Context, req *pbs.DeleteScopeRequest) ( if err != nil { return nil, err } - return &pbs.DeleteScopeResponse{}, nil + return nil, nil } func (s Service) getFromRepo(ctx context.Context, id string) (*pb.Scope, error) { diff --git a/internal/servers/controller/handlers/scopes/scope_service_test.go b/internal/servers/controller/handlers/scopes/scope_service_test.go index da546bb30..475e44e1d 100644 --- a/internal/servers/controller/handlers/scopes/scope_service_test.go +++ b/internal/servers/controller/handlers/scopes/scope_service_test.go @@ -495,7 +495,6 @@ func TestDelete(t *testing.T) { req: &pbs.DeleteScopeRequest{ Id: proj.GetPublicId(), }, - res: &pbs.DeleteScopeResponse{}, }, { name: "Delete bad project id Project", @@ -519,7 +518,6 @@ func TestDelete(t *testing.T) { req: &pbs.DeleteScopeRequest{ Id: org.GetPublicId(), }, - res: &pbs.DeleteScopeResponse{}, }, { name: "Delete bad org id Org", diff --git a/internal/servers/controller/handlers/targets/target_service.go b/internal/servers/controller/handlers/targets/target_service.go index 8407119c7..dc7ce6fcd 100644 --- a/internal/servers/controller/handlers/targets/target_service.go +++ b/internal/servers/controller/handlers/targets/target_service.go @@ -239,7 +239,7 @@ func (s Service) DeleteTarget(ctx context.Context, req *pbs.DeleteTargetRequest) if err != nil { return nil, err } - return &pbs.DeleteTargetResponse{}, nil + return nil, nil } // AddTargetHostSets implements the interface pbs.TargetServiceServer. diff --git a/internal/servers/controller/handlers/targets/target_service_test.go b/internal/servers/controller/handlers/targets/target_service_test.go index 67b79df6f..f45dec070 100644 --- a/internal/servers/controller/handlers/targets/target_service_test.go +++ b/internal/servers/controller/handlers/targets/target_service_test.go @@ -285,7 +285,6 @@ func TestDelete(t *testing.T) { req: &pbs.DeleteTargetRequest{ Id: tar.GetPublicId(), }, - res: &pbs.DeleteTargetResponse{}, }, { name: "Delete Not Existing Target", diff --git a/website/content/docs/api-clients/api.mdx b/website/content/docs/api-clients/api.mdx index 14e918fae..2311ae096 100644 --- a/website/content/docs/api-clients/api.mdx +++ b/website/content/docs/api-clients/api.mdx @@ -17,7 +17,7 @@ Boundary's current API version is 1; all API paths begin with `/v1/`. ## Status Codes -- `2XX`: Boundary returns a code between `200` and `299` on success. Generally this is `200`, but implementations should be prepared to accept any `2XX` status code as indicating success. If a call returns a `2XX` code that is not `200`, it will follow well-understood semantics for those status codes. +- `2XX`: Boundary returns a code between `200` and `299` on success. Generally this is `200`, but implementations should be prepared to accept any `2XX` status code as indicating success. If a call returns a `2XX` code that is not `200`, it will follow well-understood semantics for those status codes. (Starting with Boundary 0.2.1, `delete` actions return `204` on success.) - `400`: Boundary returns `400` when a command cannot be completed due to invalid user input, except for a properly-formatted identifier that does not map to an existing resource, which will return a `404` as discussed below. - `401`: Boundary returns `401` if no authentication token is provided or if the provided token is invalid. A valid token that simply does not have permission for a resource will return a `403` instead. A token that is invalid or missing, but where the anonymous user (`u_anon`) is able to successfully perform the action, will not return a `401` but instead will return the result of the action. - `403`: Boundary returns `403` if a provided token was valid but does not have the grants required to perform the requested action.