2020-08-13 11:20:22 -04:00
package scopes
import (
"fmt"
2020-09-15 01:08:21 -04:00
"net/http"
2020-08-13 11:20:22 -04:00
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/scopes"
"github.com/hashicorp/boundary/internal/cmd/base"
"github.com/hashicorp/boundary/internal/cmd/common"
"github.com/hashicorp/boundary/internal/types/resource"
2020-09-09 01:24:25 -04:00
"github.com/hashicorp/boundary/sdk/strutil"
2020-08-13 11:20:22 -04:00
"github.com/mitchellh/cli"
"github.com/posener/complete"
)
var _ cli . Command = ( * Command )( nil )
var _ cli . CommandAutocomplete = ( * Command )( nil )
type Command struct {
* base . Command
Func string
2020-08-26 23:27:25 -04:00
2020-09-29 20:38:16 -04:00
flagSkipAdminRoleCreation bool
flagSkipDefaultRoleCreation bool
2020-08-13 11:20:22 -04:00
}
func ( c * Command ) Synopsis () string {
return common . SynopsisFunc ( c . Func , "scope" )
}
var flagsMap = map [ string ][] string {
2020-09-29 20:38:16 -04:00
"create" : { "scope-id" , "name" , "description" , "skip-admin-role-creation" , "skip-default-role-creation" },
2020-08-13 11:20:22 -04:00
"update" : { "id" , "name" , "description" , "version" },
"read" : { "id" },
"delete" : { "id" },
2020-09-08 13:27:51 -07:00
"list" : { "scope-id" },
2020-08-13 11:20:22 -04:00
}
func ( c * Command ) Help () string {
2020-08-13 20:59:32 -04:00
helpMap := common . HelpMap ( "scope" )
2020-08-13 11:20:22 -04:00
if c . Func == "" {
return helpMap [ "base" ]()
}
2020-08-18 17:46:34 -04:00
return helpMap [ c . Func ]() + c . Flags (). Help ()
2020-08-13 11:20:22 -04:00
}
func ( c * Command ) Flags () * base . FlagSets {
set := c . FlagSet ( base . FlagSetHTTP | base . FlagSetClient | base . FlagSetOutputFormat )
2020-08-13 20:59:32 -04:00
if len ( flagsMap [ c . Func ]) > 0 {
f := set . NewFlagSet ( "Command Options" )
2020-08-18 17:46:34 -04:00
common . PopulateCommonFlags ( c . Command , f , resource . Scope . String (), flagsMap [ c . Func ])
2020-08-26 23:27:25 -04:00
if c . Func == "create" {
f . BoolVar ( & base . BoolVar {
2020-09-29 20:38:16 -04:00
Name : "skip-admin-role-creation" ,
Target : & c . flagSkipAdminRoleCreation ,
2020-08-26 23:27:25 -04:00
Usage : "If set, a role granting the current user access to administer the newly-created scope will not automatically be created" ,
})
2020-09-29 20:38:16 -04:00
f . BoolVar ( & base . BoolVar {
Name : "skip-default-role-creation" ,
Target : & c . flagSkipDefaultRoleCreation ,
Usage : "If set, a role granting the anonymous user access to log into auth methods and a few other actions within the newly-created scope will not automatically be created" ,
})
2020-08-26 23:27:25 -04:00
}
2020-08-13 20:59:32 -04:00
}
2020-08-13 11:20:22 -04:00
return set
}
func ( c * Command ) AutocompleteArgs () complete . Predictor {
return complete . PredictAnything
}
func ( c * Command ) AutocompleteFlags () complete . Flags {
return c . Flags (). Completions ()
}
func ( c * Command ) Run ( args [] string ) int {
if c . Func == "" {
return cli . RunResultHelp
}
f := c . Flags ()
if err := f . Parse ( args ); err != nil {
c . UI . Error ( err . Error ())
return 1
}
if strutil . StrListContains ( flagsMap [ c . Func ], "id" ) && c . FlagId == "" {
c . UI . Error ( "ID is required but not passed in via -id" )
return 1
}
2020-09-08 13:27:51 -07:00
if strutil . StrListContains ( flagsMap [ c . Func ], "scope-id" ) && c . FlagScopeId == "" {
c . UI . Error ( "Scope ID must be passed in via -scope-id" )
return 1
}
2020-08-13 11:20:22 -04:00
client , err := c . Client ()
if err != nil {
c . UI . Error ( fmt . Sprintf ( "Error creating API client: %s" , err . Error ()))
return 2
}
var opts [] scopes . Option
switch c . FlagName {
case "" :
case "null" :
opts = append ( opts , scopes . DefaultName ())
default :
opts = append ( opts , scopes . WithName ( c . FlagName ))
}
switch c . FlagDescription {
case "" :
case "null" :
opts = append ( opts , scopes . DefaultDescription ())
default :
opts = append ( opts , scopes . WithDescription ( c . FlagDescription ))
}
2020-09-29 20:38:16 -04:00
if c . flagSkipAdminRoleCreation {
opts = append ( opts , scopes . WithSkipAdminRoleCreation ( c . flagSkipAdminRoleCreation ))
}
if c . flagSkipDefaultRoleCreation {
opts = append ( opts , scopes . WithSkipDefaultRoleCreation ( c . flagSkipDefaultRoleCreation ))
2020-09-16 11:15:42 -04:00
}
2020-08-26 23:27:25 -04:00
2020-08-27 20:43:33 -04:00
scopeClient := scopes . NewClient ( client )
2020-08-13 11:20:22 -04:00
// Perform check-and-set when needed
var version uint32
switch c . Func {
case "create" , "read" , "delete" , "list" :
// These don't udpate so don't need the existing version
default :
switch c . FlagVersion {
case 0 :
2020-09-08 13:27:51 -07:00
opts = append ( opts , scopes . WithAutomaticVersioning ( true ))
2020-08-13 11:20:22 -04:00
default :
version = uint32 ( c . FlagVersion )
}
}
2020-09-15 01:08:21 -04:00
existed := true
var result api . GenericResult
var listResult api . GenericListResult
2020-08-13 11:20:22 -04:00
switch c . Func {
case "create" :
2020-09-24 14:34:58 -07:00
result , err = scopeClient . Create ( c . Context , c . FlagScopeId , opts ... )
2020-08-13 11:20:22 -04:00
case "update" :
2020-09-24 14:34:58 -07:00
result , err = scopeClient . Update ( c . Context , c . FlagId , version , opts ... )
2020-08-13 11:20:22 -04:00
case "read" :
2020-09-24 14:34:58 -07:00
result , err = scopeClient . Read ( c . Context , c . FlagId , opts ... )
2020-08-13 11:20:22 -04:00
case "delete" :
2020-09-24 14:34:58 -07:00
_ , err = scopeClient . Delete ( c . Context , c . FlagId , opts ... )
if apiErr := api . AsServerError ( err ); apiErr != nil && apiErr . Status == int32 ( http . StatusNotFound ) {
2020-09-15 01:08:21 -04:00
existed = false
2020-09-24 14:34:58 -07:00
err = nil
2020-09-15 01:08:21 -04:00
}
2020-08-13 11:20:22 -04:00
case "list" :
2020-09-24 14:34:58 -07:00
listResult , err = scopeClient . List ( c . Context , c . FlagScopeId , opts ... )
2020-08-13 11:20:22 -04:00
}
plural := "scope"
if c . Func == "list" {
plural = "scopes"
}
if err != nil {
2020-09-24 14:34:58 -07:00
if api . AsServerError ( err ) != nil {
c . UI . Error ( fmt . Sprintf ( "Error from controller when performing %s on %s: %s" , c . Func , plural , err . Error ()))
return 1
}
2020-08-13 11:20:22 -04:00
c . UI . Error ( fmt . Sprintf ( "Error trying to %s %s: %s" , c . Func , plural , err . Error ()))
return 2
}
switch c . Func {
case "delete" :
switch base . Format ( c . UI ) {
case "json" :
c . UI . Output ( "null" )
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 )
}
return 0
case "list" :
2020-09-15 01:08:21 -04:00
listedScopes := listResult . GetItems ().([] * scopes . Scope )
2020-08-13 11:20:22 -04:00
switch base . Format ( c . UI ) {
case "json" :
if len ( listedScopes ) == 0 {
c . UI . Output ( "null" )
return 0
}
b , err := base . JsonFormatter {}. Format ( listedScopes )
if err != nil {
2020-08-13 20:59:32 -04:00
c . UI . Error ( fmt . Errorf ( "Error formatting as JSON: %w" , err ). Error ())
2020-08-13 11:20:22 -04:00
return 1
}
c . UI . Output ( string ( b ))
case "table" :
if len ( listedScopes ) == 0 {
2020-09-14 12:30:11 -04:00
c . UI . Output ( "No child scopes found" )
2020-08-13 11:20:22 -04:00
return 0
}
var output [] string
output = [] string {
"" ,
"Scope information:" ,
}
for i , s := range listedScopes {
if i > 0 {
output = append ( output , "" )
}
if true {
output = append ( output ,
2020-08-13 20:59:32 -04:00
fmt . Sprintf ( " ID: %s" , s . Id ),
fmt . Sprintf ( " Version: %d" , s . Version ),
2020-08-13 11:20:22 -04:00
)
}
if s . Name != "" {
output = append ( output ,
2020-08-13 20:59:32 -04:00
fmt . Sprintf ( " Name: %s" , s . Name ),
2020-08-13 11:20:22 -04:00
)
}
if s . Description != "" {
output = append ( output ,
2020-08-13 20:59:32 -04:00
fmt . Sprintf ( " Description: %s" , s . Description ),
2020-08-13 11:20:22 -04:00
)
}
}
c . UI . Output ( base . WrapForHelpText ( output ))
}
return 0
}
2020-09-15 01:08:21 -04:00
scope := result . GetItem ().( * scopes . Scope )
2020-08-13 11:20:22 -04:00
switch base . Format ( c . UI ) {
case "table" :
c . UI . Output ( generateScopeTableOutput ( scope ))
case "json" :
b , err := base . JsonFormatter {}. Format ( scope )
if err != nil {
2020-08-13 20:59:32 -04:00
c . UI . Error ( fmt . Errorf ( "Error formatting as JSON: %w" , err ). Error ())
2020-08-13 11:20:22 -04:00
return 1
}
c . UI . Output ( string ( b ))
}
return 0
}