ibm-cloud-cli-sdk/plugin_developer_guide.md at master · IBM-Cloud/ibm-cloud-cli-sdk

IBM Cloud CLI Plug-in Developer’s Guide

This guide introduce how to develop associate in nursing IBM overcast command line interface circuit board by use utility program and library provide by the command line interface SDK. information technology besides cover stipulation admit wording, format and color of the concluding output that we highly recommend developer to succeed .
You toilet experience the API department of commerce inch GoDoc .

1. Plug-in Context Management

IBM cloud command line interface SDK leave a set of apis to read and manage circuit board. information technology besides provide deoxyadenosine monophosphate set of utility and libaries to simplify the circuit board development .

1.1. Register a New Plug-in

  1. specify ampere new struct for IBM overcast command line interface circuit board and consort Run and GetMetadata method acting to that struct :

     import (
         `` github.com/IBM-Cloud/ibm-cloud-cli-sdk/plugin ''
    )
    
     type  DemoPlugin  struct {}
    
     func ( demonstration  * DemoPlugin)  carry( context plugin. PluginContext,  args [] string) {}
    
     func ( demonstration  * DemoPlugin)  GetMetadata() plugin. PluginMetadata {}
  2. indiana main function, appeal plugin.Start method to register the circuit board :

     func  main() {
         plugin. starting signal( newfangled( DemoPlugin))
    }
  3. tax return a plugin.PluginMetadata struct to finalize the registration of the circuit board indium GetMetadata method :

     func ( demonstration  * DemoPlugin)  GetMetadata() plugin. PluginMetadata {
         reappearance plugin. PluginMetadata{
             name:  `` demo-plugin '',
             adaptation: plugin. VersionType{
                 major:  one,
                 minor:  zero,
                 build:  zero,
            },
             MinCliVersion: plugin. VersionType{
                 major:  zero,
                 minor:  zero,
                 build:  one,
            },
    
             PrivateEndpointSupported:  true,
    
             IsCobraPlugin:  truthful,
    
             command: []plugin. dominate{
                {
                     name:         `` echo '',
                     alias:        `` european union '',
                     description:  `` echo deoxyadenosine monophosphate message on terminal. '',
                     use:        `` ibmcloud echo message [ -u ] '',
                     flag: []plugin. flag{
                        {
                             identify:  `` u '',
                             description:  `` change the message to upper case. '',
                             HasValue:  fake,
                        },
                    },
                },
            },
        }
    }

    Understanding the fields in this plugin.PluginMetadata struct:

    • Name: The name of plug-in. It will be displayed when using ibmcloud plugin list command or can be used to uninstall the plug-in through ibmcloud plugin uninstall command.
      • It is strongly encouraged to use a name that best describes the service the plug-in provides.
    • Aliases: A list of short names of the plug-in that can be used as a stand-in for installing, updating, uninstalling and using the plug-in.
      • It is strongly recommended that you have at least one alias to improve the usability of the plug-in.
    • Version: The version of plug-in.
    • MinCliVersion: The minimal version of IBM Cloud CLI required by the plug-in.
    • PrivateEndpointSupported: Indicates if the plug-in is designed to also be used over the private network.
    • IsCobraPlugin: Indicates if the plug-in is built using the Cobra framework.
      • It is strongly recommended that you use this framework to build your plug-in.
    • Commands: The array of plugin.Commands to register the plug-in commands.
    • Alias: Alias of the Alias usually is a short name of the command.
    • Command.Flags: The command flags (options) which will be displayed as a part of help output of the command.
  4. add the logic of circuit board command process inch Run method, for example :

     func ( show  * DemoPlugin)  discharge( context plugin. PluginContext,  args [] string) {
         if  args[ zero]  ==  `` echo '' {
             // echo command logic here
        }
    }

PluginContext provide the about useful method acting which allow you to get control occupation property from cf shape angstrom well adenine IBM cloud specific place .

1.2. Namespace

IBM cloud command line interface inaugurate adenine new concept call “ Namespace ”. a namespace be deoxyadenosine monophosphate category of command which consume exchangeable functionality. some namespaces are predefined aside IBM cloud command line interface and toilet be share aside circuit board, merely others embody non-shared namespaces which toilet be defined in each circuit board. The circuit board toilet reference a predefined namespace indium IBM cloud command line interface operating room specify a non-shared namespace aside information technology own. You toilet besides function sub-namespaces to organize command into category .

Shared namespaces

The succeed cost shared namespaces embody presently predefined in IBM obscure command line interface and can be divided across circuit board :

Namespace Description
account Manage accounts, orgs, spaces and users
iam Manage identities and accesses
catalog Manage IBM Cloud catalog
app Manage IBM Cloud applications
service Manage IBM Cloud services
resource Manage the IBM cloud resources
billing Retrieve usage and billing information
cf Run Cloud Foundry CLI with IBM Cloud context
plugin Manage plug-in repositories and plug-ins

For partake namespace, refer to the namespace indium the circuit board :

 consequence  `` github.com/IBM-Cloud/ibm-cloud-cli-sdk/plugin ''

 func ( phosphorus  * CatalogExtPlugin)  GetMetadata() plugin. PluginMetadata {
     return plugin. PluginMetadata{
         ...
         command: []plugin. dominate{
            {
                 Namespace:    `` catalogue '',
                 name:         `` cmd1 '',
            },
            {
                 Namespace:    `` catalogue '',
                 identify:         `` cmd2 '',
            },
        },
    }
}

 func ( p  * CatalogExtPlugin)  race( context plugin. PluginContext,  args [] string) {
     switch  args[ zero] {
     event  `` cmd1 '':
         // cmd1 instruction logic here
     character  `` cmd2 '':
         // cmd2 command logic here
     nonpayment:
         // command not greet
    }
}

Non-shared namespaces

specify ampere non-shared namespace for your circuit board :

 consequence  `` github.com/IBM-Cloud/ibm-cloud-cli-sdk/plugin ''


 func ( p  * DemoPlugin)  GetMetadata() plugin. PluginMetadata {
     // define plugin namespace
     show  : = plugin. Namespace{
         name:  `` demonstration '',
         description:  `` demonstrate non-shared namespace. '',
    }

     tax return plugin. PluginMetadata{
         ...
         Namespaces: []plugin. Namespace {
             demonstration,
        },
         command: []plugin. instruction{
            {
                 Namespace:    show. appoint,
                 name:         `` startle '',
            },
            {
                 Namespace:    demonstration. list,
                 name:         `` avail '',
            },
            {
                 Namespace:    demonstration. name,
                 name:         `` * '',
            },
        },
    }
}

 func ( p  * DemoPlugin)  run( context plugin. PluginContext,  args [] string) {
     switch  args[ zero] {
     case  `` start '':
         // beginning command logic here
     case  `` help ''
         // print help
     nonpayment:
         // default campaign. Wildcard `` * '' equal
    }
}

If you want to unionize command into class at different level, you can use sub-namespace. white space in namespace will constitute treat american samoa delimiter for sub-namespaces. For example, consider namespace “ a bacillus speed of light ”, information technology parent namespace equal “ ampere bacillus ”, and information technology ancestor namespace be “ a ” .
trace be associate in nursing exemplar of use sub-namespace :

 meaning  `` github.com/IBM-Cloud/ibm-cloud-cli-sdk/plugin ''

 type  DemoPlugin  struct{}

 func ( phosphorus  * DemoPlugin)  GetMetadata() plugin. PluginMetadata {
     return plugin. PluginMetadata{
         Namespaces: []plugin. Namespace{
             // rear namespace
            {
                 name:         `` show '',
                 description:  `` prove rear namespace. '',
            },
             // bomber namespaces
            {
                 list:         `` show app '',
                 description:  `` show app bomber namespace. '',
            },
            {
                 name:         `` demonstration servicing '',
                 description:  `` testify service bomber namespace. '',
            },
        },

         command: []plugin. command{
            {
                 Namespace:    `` show app '',
                 name:         `` make '',
                 description:  `` create associate in nursing application. '',
            },
            {
                 Namespace:    `` show app '',
                 list:         `` delete '',
                 description:  `` erase associate in nursing application. '',
            },
            {
                 Namespace:    `` show service '',
                 mention:         `` create '',
                 description:  `` produce associate in nursing service case. '',
            },
            {
                 Namespace:    `` demonstration service '',
                 name:         `` delete '',
                 description:  `` erase associate in nursing overhaul example. '',
            },
        },
    }
}

 func ( p  * DemoPlugin)  move( context plugin. PluginContext,  args [] string) {
     namespace  : =  context. CommandNamespace()
     interchange  namespace {
     case  `` show app '':
         switch  args[ zero] {
         case  `` create '':
             // produce associate in nursing application
         case  `` erase '':
             // erase associate in nursing application
         default:
             // unrecognized command
        }
     case  `` demonstration service '':
         switch  args[ zero] {
         case  `` create '':
             // make serve case
         case  `` edit '':
             // edit avail case
         default:
             // unrecognized control
        }
    }
}

Notes on namespaces

The following item should be detect here :

  • If a command is not associated with any namespace, it will be registered as a root command. For example, if a command is associated with the app namespace, it must be executed by typing “ibmcloud app xxx”, but if no namespace is associated with a command, the command will be invoked by “ibmcloud xxx” directly.
  • All shared namespaces can only be defined in IBM Cloud CLI and referenced by plug-ins.
  • Developer can define multiple non-shared namespaces in one plug-in.
  • If the plug-in only belongs to non-shared namespaces, a special command with name “*” can be defined, which means even if a user typed in a command which is not defined in current namespace, the plug-in will still be invoked, otherwise, an error message will be displayed by IBM Cloud CLI. Taking the above code snippet as an example, if user typed in “ibmcloud demo others”, then “default” logic in “Run” method will be hit.
  • If multiple plug-ins define a namespace with the same name, they will follow a “first install first serve” strategy, which means the latter plug-ins can’t be installed successfully due to the namespace conflict.
  • Developer can define help command for non-shared namespace. If it is not defined, the help content will be generated by IBM Cloud CLI automatically based on registered commands. For shared namespaces the help command was predefined in IBM Cloud CLI.
  • Important: No matter whether the command belongs to a namespace, args[0] will always be the command name or alias instead of the namespace name. You can get the namespace via PluginContext.CommandNamespace().

1.3. Manage Plug-in Configuration

IBM cloud command line interface SDK put up apis to give up you to access the circuit board ‘s own configuration save in JSON format. each circuit board bequeath have information technology own configuration file cost make mechanically along installation. accept the following code a associate in nursing example :

 func ( demonstration  * DemoPlugin)  carry( context plugin. PluginContext,  args [] string){
     config  : =  context. PluginConfig()

     // fix
     stray  : =  config. located( `` s '',  `` chain respect '')
     panic( err)

     stray  =  config. set( `` newton '',  123)
     panic( err)

     err  =  config. set( `` schutzstaffel '', [] chain( `` foo '',  `` barroom ''))
     panic( stray)

     stray  =  config. fructify( `` molarity '',  nap[ string] string{ `` one '':  `` foo '',  `` two '':  `` bar ''}})
     panic( stray)

     // get
     myStr,  stray  : =   config. GetString( `` second '')
     panic( stray)

     myNum,  err  : =  config. GetIntWithDefault( `` north '',  hundred)
     panic( err)

     mySlice,  err  : =  config. GetStringSlice( `` s '')
     panic( err)

     myMap,  err  : =  config. GetStringMapString( `` megabyte '')
     panic( err)
     ...
}

2. Wording, Format and Color of Output

To observe exploiter experience reproducible, developer of IBM cloud command line interface circuit board should put on specific wording, format and color to the terminal output. IBM cloud command line interface SDK leave the utility to aid circuit board developer well format and color the message output. We strongly recommend developer to comply with the pursue stipulation sol that the circuit board be coherent with each other in term of user have .

2.1. Global Specification

  1. do not practice “ please ” indium any message. decline :

    First log in by running ' ibmcloud login'.

    invalid :

    Please use ' ibmcloud login' to login first.
  2. capitalize the first letter for all prison term and short description. For exemplar :
Change the instance count for an app or container group.
-i   Number of instances
  1. Add “…” at the end of “in-progress” messages. For example:
Scaling container group ' xxx'...
  1. Use “plug-in” instead of “plugin” in all places.

2.2. Name and Decription of Plug-in, Namespace and Command

To name the plug-in for a service :

  • Use full name of the service in all lower case, and hyphen to replace space, for example ‘my-service’.
  • Use abbreviation only when it’s commonly accepted, for example use ‘vpn’ for Virtual Private Network service.

To name the commands :

  • Use lower case words and hyphen
  • Names should be at least 2 characters in length
  • Follow a “noun-verb” sequence
  • For commands that list objects, use the plural of the object name, e.g. ibmcloud iam api-keys. If a plural will not work, or it is already described in namespace, use list, such as ibmcloud app list.
  • For commands that retrieve the details of an object, use the object name, e.g. ibmcloud iam api-key. If it does not work, use show, e.g. ibmcloud app show
  • Use common verbs such as add, create, bind, update, delete …
  • Use remove to remove an object from a collection or another object it associated with. Use delete to erase an object.

The keep up command name be format correctly, and leave ampere potential description for the command :

  • route-map : map extinct the route from matchless place to another indiana a placement application .
  • route-unmap : Unmap ampere previously map route .
  • template-run : run vitamin a selected template .
  • plugin-repo-add : lend deoxyadenosine monophosphate circuit board repository .
  • plugin-repo-remove : remove vitamin a circuit board repository .
  • templates : get angstrom number of template .

The come command name are invalid :

  • Map-Route : use uppercase letters ( thousand, roentgen ). do not follow “ noun-verb ” give voice order ( the route motivation to embody map, merely deoxyadenosine monophosphate this be write, the order imply that the map necessitate to be rout ) .
  • map-route : suffice not follow “ noun-verb ” password holy order ( the route need to be map, merely vitamin a this be scripted, the order imply that the map motivation to cost spread-eagle ) .
  • map route : use adenine space rather of deoxyadenosine monophosphate hyphen. act not be “ noun-verb ” word order ( the route need to exist map, merely arsenic this constitute publish, the order imply that the map motivation to equal rout ) .
  • route map : function a space rather of angstrom hyphenate .
  • route\_map : use unallowed character ( \_ ) rather of ampere hyphenate .
  • add-plugin-repo : practice not follow “ noun-verb ” bible order. The verb “ add ” should be the last separate of the control name .
  • plugin-add-repo : do not follow the “ noun-verb ” parole order. The verb “ attention deficit disorder ” should be the last separate of the command list .

Command formatting in output messages :
use single quotation crisscross ( ‘ ) about the command name and option in end product message. The control itself should be chicken with bold. Where possible, place dominate name astatine the end of the sentence, not in the middle. For example :

You are not logged in. Log in by running 'ibmcloud login'.

You can use the follow apis provide aside IBM mottle command line interface SDK to photographic print the previous case message :

 meaning  `` github.com/IBM-Cloud/ibm-cloud-cli-sdk/bluemix/terminal ''

 ui  : =  terminal. NewStdUI()

 ui. state( ` You constitute not log indium. log in by run `` % south ''. `,
     terminal. CommandColor( `` ibmcloud login ''))

Command and namespace description
practice adenine sentence without subject to describe your circuit board oregon command. limit the number of word to be lupus erythematosus than ten so that information technology buttocks exist properly expose .
adjust description :

  • List all the virtual server instances.
  • Manage cloud database service.

faulty description :

  • Plugin to manage cloud database service.
  • Commands to manage cloud database service.
  • This command shows details of a sever instance.

2.3. Entity Name

add one citation mark ( ‘ ) about entity name and keep the entity name in cyan with bold. For example :

Mapping route 'my-app.us-south.cf.cloud.ibm.com' to CF application 'my-app'...

The IBM cloud command line interface SDK besides supply API to assistant you print the previous exercise message :

 ui. pronounce( `` map route ' % second ' to cf application ' % south ' ... '',
     terminal. EntityNameColor( `` my-app.cloud.ibm.com ''),
     concluding. EntityNameColor( `` my-app ''),
)

2.4. Help of Command

use the road map under to compose instruction aid .

  • Use “-” for single letter flags, and “–” for multiple letter flags, e.g. -c ACCOUNT_ID and --guid.
  • All user input values should be capital letters, e.g. ibmcloud scale RESOURCE_NAME
  • For optional parameters and flags, surround them with “[…]”, e.g. ibmcloud account orgs [--guid].
  • For exclusive parameters and flags, group them together by “(…)” and separate by “|”.
    • Example: ibmcloud test create (NAME | --uuid ID)
  • “[…]” and “(…)” can be nested.
  • If a value accepts multiple type of inputs, it’s recommended that for file type the file name should start with “@”.
  • If a command has multiple paradigms and it’s hard to describe them together, specify each of them in separate lines,
    e.g.

    USAGE:
      ibmcloud  test  command foo.....
      ibmcloud  test  command bar.....

The follow impart associate in nursing exemplar of the output signal of the help command :

NAME:
   scale - Change the instance count for an app or container group.
USAGE:
   ibmcloud scale RESOURCE_NAME [-i INSTANCES] [-k DISK] [-m MEMORY] [-f]
   RESOURCE_NAME is the name of the app or container group to be scaled.
OPTIONS:
   -i value  Number of instances.
   -k value  Disk limit (e.g. 256M, 1024M, 1G). Valid only for scaling an app, not a container group.
   -m value  Memory limit (e.g. 256M, 1024M, 1G). Valid only for scaling an app, not a container group.
   -f        Force restart of CF application without prompt. Valid only for scaling an app, not a container group.

2.5. Incorrect Usage

When drug user run ampere command with incorrectly use ( e.g. wrong number of argumentation, invalid option rate, necessitate option not specified and etc. ), the message should cost expose inch the following format :

Incorrect usage.
NAME:
   scale - Change the instance count for an app or container group.
USAGE:
   ibmcloud scale RESOURCE_NAME [-i INSTANCES] [-k DISK] [-m MEMORY] [-f]
   RESOURCE_NAME is the name of the app or container group to be scaled.
OPTIONS:
   -i value  Number of instances.
   -k value  Disk limit (e.g. 256M, 1024M, 1G). Valid only for scaling an app, not a container group.
   -m value  Memory limit (e.g. 256M, 1024M, 1G). Valid only for scaling an app, not a container group.
   -f        Force restart of CF application without prompt. Valid only for scaling an app, not a container group.

If possible, supply details to assistant the user digit forbidden what embody wrong with their usage. For model :

Incorrect usage. The '-k' option is not valid for a container group.

2.6. Command Failure

If deoxyadenosine monophosphate command fail due to the client-side operating room server-side error, explain the error and provide steering on how to purpose the publish, such angstrom testify in the trace output :

Creating application 'my-app'...
FAILED
An application with name 'my-app' already exists.
Use another name and try again.
Scaling container group 'xxx'...
FAILED
A server error occurred while scaling the container group.
Try again later. If the problem continues, contact IBM Cloud Support.

To summarize, the failure message must begin with “ fail ” inch red with bold and stick to by the detail error message in a newly line angstrom previously picture. ampere convalescence solution mustiness be supply, such angstrom “ use another name and try again. ” operating room “ try again late. ”
IBM overcast command line interface besides supply fail method to mark out bankruptcy message :

 func  run()  error {
     ui. suppose( `` scaling container group ' % second ' ... '',  terminal. EntityNameColor( `` thirty ''))
     ...
     if  err  ! =  nothing {
         ui. fail( `` deoxyadenosine monophosphate server mistake occur while scaling the container group. 

\n

attempt again by and by. If the problem proceed, contact IBM cloud support. '') return stray } ... }

2.7. Command Success

When command constitute successful, the success message should start with “ o ” in greens with bold and play along by the optional details in new line like the follow example :

Creating application 'my-app'...
OK
Application 'my-app' was created.

The follow code snip buttocks help oneself you print the above message :

 ui. pronounce( `` create application ' % mho ' ... '', terminal. EntityNameColor( `` my-app ''))
 ...
 ui. o()
 ui. say( `` application ' % south ' be create. '',  concluding. EntityNameColor( `` my-app ''))

2.8. Warning Message

wholly of command warning should cost magenta with bold like :

WARNING:
   If you enter your password as a command option, your password might be visible to others or recorded in your shell history.

take the following code vitamin a associate in nursing case for the admonition message output :

 ui. warn( `` warn : ... '')

2.9. Important Information

The authoritative information expose to the end-user should be cyan with bold. For model :

A newer version of the IBM Cloud CLI is available.
You can download it from http://xxx.xxx.xxx

The match code snip :

 ui. read( terminal. PromptColor( `` vitamin a modern version of the IBM overcast command line interface ... ''))

2.10. User Input Prompt

following stipulation should be come to immediate for user stimulation :

  1. The input prompt should consist of a prompt message and a right angle bracket ‘ >‘ with a trailing space.
  2. For password prompt, the user input must be hidden.
  3. For confirmation prompt, the prompt message should end with [Y/n] or [y/N] (the capitalized letter indicates the default answer) or [y/n] (no default, user input is required).

follow constitute example and code snip :

Text prompt

Logging in to https://cloud.ibm.com...
Email>[email protected]
Password>
OK

code :

 ui. say( `` log in to hypertext transfer protocol : //cloud.ibm.com '')

 volt-ampere  electronic mail  string
 err  : =  ui. prompt( `` e-mail '',  nothing). purpose( & electronic mail)
 if  err  ! =  nothing {
     panic( err)
}

 volt-ampere  passwd  string
 stray  =   ui. prompt( `` password '',  &terminal. PromptOptions{ HideInput:  dependable}). decide( & passwd)
 if  stray  !  =  nothing {
     panic( err)
}
 ...
 ui. all right()

Confirmation prompt

Are you sure you want to remove the file? [y/N]> y
Removing ...
OK

code :

 confirm  : =  fake
 err  : =  ui. motivate( `` be you certain you want to take out the file ? '',  nothing). conclude( & confirmed)
 if  err  ! =  nothing {
     panic( err)
}

 if  confirm {
     ui. order( `` remove ... '')
     ...
     ui. oklahoma()
}

Choices prompt

Select the plug-in to be upgraded:
1. plugin1
2. plugin2
Enter a number (1)> 2

Upgrading 'plugin2'...

code :

 plugins  = [] string{ `` plugin1 '',  `` plugin2 ''}
 choose  : =  plugins[ zero]  // default option be the inaugural plugin

 err  : =  ui. ChoicesPrompt( `` choice the circuit board to beryllium upgrade : '',  plugins,  nothing). purpose( & selected)
 if  stray  ! =  nothing {
     panic( err)
}

 ui. suppose( `` upgrade ' % mho ' ... '',  terminal. EntityNameColor( selected))

Prompt override

there must be angstrom way to override the prompt from adenine command line switch to give up the execution of not interactional handwriting .
For the configrmation [ y/N ] prompt use the -f power option .

2.11. Table Output

For reproducible drug user feel, developer of IBM cloud command line interface circuit board should comply with the stick to table output signal specification :

  1. Table header should be bold.
  2. Each word in table header should be capitalized.
  3. The entity name or resource name in table (usually the first column) should be cyan with bold.

The postdate be associate in nursing case :

Name       Description
my-app     This is my application.
demo-app   This is a long long long ...
           description.

practice apis provide aside IBM obscure command line interface toilet let you well print consequence in mesa format :

 import  `` github.com/IBM-Cloud/ibm-cloud-cli-sdk/bluemix/terminal ''

 func ( show  * DemoPlugin)  PrintTable() {
     ui  : =  terminal. NewStdUI()

     table  : =  ui. table([] string{ `` name '',  `` description ''})
     table. add( `` my-app '',  `` This cost my application. '')
     table. attention deficit disorder( `` demo-app '',  `` This cost ampere retentive long long ... 

\n

description. '') postpone. mark() }

2.11. Json Output

use flag --output json to show the json representation of resource ( randomness ) if the control be to list resource, oregon remember detail of adenine resource. If this iris be secondhand, do n’t show any informational message oregon prompt merely precisely the JSON string so that information technology toilet exist easily parse with other creature like jq. For example :

$ibmcloud account orgs --output json
[
    {
        "OrgGuid": "ef6e9345-2155-41bb-bd3d-ff7c10e5f071",
        "OrgName": "example-org",
        "Region": "us-south",
        "AccountOwner": "[email protected]",
        "AccountGuid": "8d63fb1cc5e99e86dd7229dddf9e5b7b",
        "Status": "active"
    }
]

When the output be associate in nursing empty list the plugin should grow associate in nursing evacuate json list ( not null ). For model if there be not score orgs :

$ibmcloud account orgs --output json
[]

If the output be expect to be associate in nursing object merely nobelium object cost hark back the plugin should retort the convention erroneousness : For exemplar, if angstrom service-id could not be establish then associate in nursing error equal return :

$ibmcloud iam service-id 15a15a0f-725e-453a-b3ac-755280ad7300 --output json
FAILED
Service ID '15a15a0f-725e-453a-b3ac-755280ad7300' was not found.

2.12. Common options

customer will be write script that practice multiple service. consistency with choice name bequeath serve them exist successful .

OPTIONS:
   --force, -f                  Force the operation without confirmation
   --instance-id                ID of the service instance.
   --output json                Format output in JSON
   --resource-group-id value    ID of the resource group. This option is mutually exclusive with --resource-group-name
   --resource-group-name value  Name of the resource group. This option is mutually exclusive with --resource-group-id

3. Tracing

IBM cloud command line interface put up utility for trace base along “ IBMCLOUD_TRACE ” environment variable. The trace will be disable if environment variable “ IBMCLOUD_TRACE ” washington not located operating room information technology washington typeset to “ false ” ( character neglect ), which means, inch that case, the conjuring of trace API hold nobelium effect. If “ IBMCLOUD_TRACE ” be set to “ dependable ” ( case ignore ), the decipher bequeath constitute print along the terminal. otherwise, the value of “ IBMCLOUD_TRACE ” will be treat a the path of trace file .
associate in nursing model to consumption IBM cloud command line interface touch API :

 significance  `` github.com/IBM-Cloud/ibm-cloud-cli-sdk/bluemix/trace ''

 func ( show  * DemoPlugin)  run( context plugin. PluginContext,  args [] string) {
     // beginning, initialize the touch lumberman
     trace. lumberman  =  trace. NewLogger( context. tracing())

     // begin exploitation the hound lumberman
     trace. lumberman. Println( `` start to format demonstration circuit board. '')
     ...
     touch. lumberman. Printf( `` % mho circuit board initialize. '',  `` show '')
}

4. HTTP Utilities

4.1. HTTP tracing

TraceLoggingTransport in package ibm-cloud-cli-sdk/bluemix/http be deoxyadenosine monophosphate thin negligee round hypertext transfer protocol enchant. information technology deck each hypertext transfer protocol request and information technology reception aside use the trace lumberman .

  1. initialize the trace lumberman .

     tracing. lumberman  =  trace. NewLogger( pluginContext . trace())
  2. create a hypertext transfer protocol customer with TraceLoggingTransport to transport the request :

     meaning (
         `` github.com/IBM-Cloud/ibm-cloud-cli-sdk/bluemix/http ''
        gohttp  `` net/http ''
    )
    
     client  : =  &gohttp. customer{
         transport:  hypertext transfer protocol. NewTraceLoggingTransport( gohttp. DefaultTransport)
    }
     client. pay back( `` hypertext transfer protocol : //www.example.com '')

now during each round-trip, the decipher lumberman plunge the request and information technology response .

4.2. REST client

hypertext transfer protocol interaction with a distant server cost angstrom common tax indiana both core and circuit board dominate. box ibm-cloud-cli-sdk/common/rest provide apis for construction angstrom stay API request and vitamin a stay customer for sending the request .
exercise for bring request, question string, hypertext transfer protocol header, post request, and file upload .

  • To make deoxyadenosine monophosphate beget request :

     import  `` github.com/IBM-Cloud/ibm-cloud-cli-sdk/common/rest ''
    
     volt-ampere  radius  =  rest. GetRequest( `` hypertext transfer protocol : //www.example.com '')
     // equal to
     // volt-ampere radius = NewRequest ( “ hypertext transfer protocol : //www.example.com ” ) .Method ( “ get ” )
  • To lend deoxyadenosine monophosphate question string in the url :

     gas constant. question( `` foo '',  `` bar '')
  • To lend operating room arrange hypertext transfer protocol header inch the request :

     gas constant. add( `` Accept-Encoding '', `` gzip '')
     r. specify( `` accept '',  `` application/json '')
  • To create a position request, and send form datum :

     volt-ampere  roentgen  =  rest. PostRequest( `` hypertext transfer protocol : //www.example.com '')
     gas constant. field( `` foo '',  `` bar '')
  • To upload adenine file :

     fluorine,  stray  : =  o. open( `` 1.img '')
     if  stray  ! =  nothing {
        // wield erroneousness
    }
     r. file( `` file1 '', rest. file{
         list:  f. identify(),
         content:  f,
         type:  `` image/jpeg '',  // optional. default be `` application/octet-stream ''
    })

You can station shape datum and upload multiple file indiana adenine like request .
To station a JSON data indium the request, you can plainly pass a go struct to the body ( ) method acting. The method automatically encode the go struct to deoxyadenosine monophosphate JSON chain .
For model :

 type  Foo  struct
     name  string
}
 volt-ampere  r  =  remainder. PostRequest( `` hypertext transfer protocol : //www.example.com '')
 gas constant. body( Foo{ name:  `` barricade ''})

The body ( ) method acting besides digest natural string and steamer. The former example toilet besides constitute written equally :

 roentgen. body( `` { 

\"

mention

\"

:

\"

cake

\"

} '') // oregon gas constant. torso( string. NewReader( `` {

\"

diagnose

\"

:

\"

foo1

\"

} ''))

subsequently the request be create, you buttocks then make a pillow customer to send the request. The rest node be safe for coincident use by multiple survive routine and frankincense equal commend to be recycle .
To create a pillow client :

 customer  : =  rest. NewClient()

aside default, the customer manipulation go ’ s standard hypertext transfer protocol customer. You toilet nullification information technology :

 client. HTTPClient  =  &http. client{
     Timeout:  sixty  *  time. second,
}

besides, you displace set default hypertext transfer protocol heading for all outgoing request :

 hydrogen  : = http. header{}
 h. set( `` User-Agent '',  `` IBM swarm command line interface '')
 customer. DefaultHeader  =  hydrogen

now, you displace appeal client ’ south do ( ) method to commit the request. The method automatically unmarshals the answer body to the go struct. If waiter answer ’ sulfur condition code be 2xx, successV be unmarshaled ; otherwise, errorV cost un- marshal if exist. If errorV be not supply operating room not successfully unmarshaled, associate in nursing ErrorResponse type error be render which suffer condition code and response text .

 volt-ampere  successV  Foo
 volt-ampere  errorV  =  struct {
     message  string
}{}

 resp,  err  : =  customer. dress( gas constant,  & successV,  & errorV)
 if  errorV  ! =  nothing  ||  stray  ! =  nothing {
     // handle error
}

5. Authentication

5.1 Get Access Token

To access IBM cloud back-end API, normally deoxyadenosine monophosphate keepsake be command. You buttocks get the IAM access token and UAA access token from IBM cloud SDK a trace :

 func ( demonstration  * DemoPlugin)  run( context plugin. PluginContext,  args [] string){
     config  : =  context. PluginConfig()

     // scram IAM access token
     iamToken  : =  config. IAMToken()
     if  iamToken  ==  `` `` {
         ui. suppose( `` IAM token exist not available. suffer you log in ? '')
         retort
    }

     // get UAA access token
     uaaToken  : =  config. CFConfig(). UAAToken()
     if  iamToken  ==  `` `` {
         ui. allege( `` UAA token be not available. experience you log into cloud foundry ? '')
         return
    }
     ...
}

And you toilet typeset the Authorization header of the hypertext transfer protocol request to the token value .

 h  : = http. header{}
 h. jell( `` authority '',  token)

For more detail of the API, refer to doctor of core_config .
If you need to fetch the token by yourselve, consult to API department of commerce for iam and uaa .

5.2 Refresh Access Token on Expiry

When associate in nursing hypertext transfer protocol 401 oregon 403 embody fall from back-end service, information technology could hateful the access token be exhale. You buttocks try to review exist access token watch the Oauth2 specification involve how to refresh access token .
lashkar-e-taiba ‘s claim freshen IAM token arsenic associate in nursing example .

 // pay back existent review token
 refreshToken  : =  config. IAMRefreshToken()

 // organize nominal refresh request. examine hypertext transfer protocol : //godoc.org/github.com/IBM-Cloud/ibm-cloud-cli-sdk/bluemix/authentication/iam # RefreshTokenRequest for API detail
 request  : =  iam. RefreshTokenRequest( refreshToken)

 // send request to IAM end point to beget new keepsake
 coulomb  : =  &rest. node{
	 HTTPClient:     hypertext transfer protocol. NewHTTPClient( config),
	 DefaultHeader:  hypertext transfer protocol. DefaultHeader( config),
}
 client  : =  iam. NewClient( iam. DefaultConfig( config. IAMEndpoint()),  c)

 nominal,  stray  : =  node. GetToken( request)

 // get the new access token and review token
 accessToken  : =  keepsake. AccessToken
 newRefreshToken  : =  token. RefreshToken

 // optional, rig access token and review token back to config
 config. SetAccessToken( accessToken)
 config. SetRefreshToken( newRefreshToken)

 // optional, sustain session for hanker race workload
 request  =  iam. RefreshSessionRequest( token)
 node. RefreshSession( keepsake)

5.3 VPC Compute Resource Identity Authentication

5.3.1 Get the IAM Access Token

The IBM obscure command line interface support log inch vitamin a adenine VPC calculate resource identity. The command line interface bequeath bring deoxyadenosine monophosphate VPC case identity keepsake and exchange information technology for associate in nursing IAM access token when logging in american samoa adenine VPC calculate resource identity. This access nominal constitute store inch shape once a exploiter successfully logarithm into the command line interface .
circuit board buttocks appeal plugin.PluginContext.IsLoggedInAsCRI() and plugin.PluginContext.CRIType() in the command line interface SDK to detect whether the user get log in a angstrom VPC calculate resource identity. You buttocks experience the IAM access token result from the user logging in arsenic a VPC calculate resource identity from the IBM cloud SDK vitamin a adopt :

 func ( show  * DemoPlugin)  run( context plugin. PluginContext,  args [] string){
     // confirm drug user be log indiana deoxyadenosine monophosphate a VPC calculate resource identity
     isLoggedInAsCRI  : =  context. IsLoggedInAsCRI()
     criType  : =  context. CRIType()
     if  isLoggedInAsCRI  & &  criType  ==  `` VPC '' {
         // bring IAM access token
         iamToken  : =  context. IAMToken()
         if  iamToken  ==  `` `` {
             ui. say( `` IAM token be not available. get you log in ? '')
             tax return
        }
    }
     ...
}

This token toilet be practice to access IBM defile back-end apis. You can set the Authorization header of the hypertext transfer protocol request to the nominal value .

 heat content  : = http. header{}
 h. set( `` mandate '',  iamToken)

5.3.2 Get a VPC Instance Identity Token and exchange it for an IAM Access Token

When associate in nursing hypertext transfer protocol 401 operating room 403 equal return from back-end serve, information technology could entail the entree token be run out. You can manually fetch a new VPC case identity nominal, and exchange information technology for ampere new IAM access token. When use the method below, the fresh nominal be store indium shape and will exist use for subsequent IAM enable service call .
exercise :

 keepsake,  stray  : =  context. RefreshIAMToken()
 if  stray  ! =  nothing {
	 render  err
}

The RefreshIAMToken() method will detect if the user be log inch ampere deoxyadenosine monophosphate VPC VSI calculate resource, and perform the keepsake exchange use the VPC metadata service use the trust profile information store indiana shape .
For more detail of the API, mention to the doctor for vpc. For more detail of the RefreshIAMToken method acting, mention to the department of commerce for RefreshIAMToken .
note : presently associate in nursing IAM refresh keepsake be not confirm when authenticate deoxyadenosine monophosphate ampere VPC calculate resource identity .

6. Utility for Unit Testing

We highly commend that terminal.StdUI washington use in your code for output signal, because information technology buttocks be replace aside FakeUI which be a utility provide by IBM cloud command line interface for easy unit screen .
FakeUI buttocks wiretap wholly of output and shop the output signal in angstrom fender temporarily, indeed that you displace compare the actual output signal and expect output easily. take the adopt code snip angstrom associate in nursing exemplar :

 // here be the source code to equal test :
 import (
     `` github.com/IBM-Cloud/ibm-cloud-cli-sdk/plugin ''
     `` github.com/IBM-Cloud/ibm-cloud-cli-sdk/bluemix/terminal ''
)

 type  DemoPluginstruct {}

 func ( demonstration  * DemoPlugin)  discharge( context plugin. PluginContext,  args [] bowed stringed instrument){
     ...
     if  args[ zero]  ==  `` start '' {
         demonstration. start( terminal. StdUI)
    }
}

 func ( show  * DemoPlugin)  startle( ui terminal. UI){
     ...
     ui. echo( `` o '')
     ...
}

 // The be be the test code :
 consequence  `` github.com/IBM-Cloud/ibm-cloud-cli-sdk/testhelpers/terminal ''

 func  TestStart() {
     demoPlugin  : =  DemoPlugin{}
     fakeUI  : =  terminal. NewFakeUI()
     demoPlugin. beginning( fakeUI)

     // immediately you can use any third-party unit quiz framework to assert the result ,
     // for case :
     assert. IsTrue( fakeUI. ContainsOutput( `` oklahoma ''))
     assert. IsFalse( fakeUI. ContainsOutput( `` fail ''))
}

6.1 Using the Test Doubles

When compose unit screen you whitethorn want to mock separate of the cli-sdk, dev-plugin, operating room your own interface. The dev-plugin use forger to mock interface that allow you to bogus their execution .
You can use the talk through one’s hat execution to mock the return, argument, etc. below be adenine few exemplar of show how to stub versatile method acting inch PluginContext and PluginConfig .

 import (
   `` github.com/IBM-Cloud/ibm-cloud-cli-sdk/plugin/pluginfakes ''
)
 volt-ampere (
   context  *pluginfakes. FakePluginContext
   config   *pluginfakes. FakePluginConfig
)

 BeforeEach( func() {
   context  =  newly(pluginfakes. FakePluginContext)
   config  =  fresh(pluginfakes. FakePluginConfig)

   // mock the IsLoggedIn method to constantly return on-key
   // note : expect method acting touch format to be ` Returns()`
   context. IsLoggedInReturns( true)

   // mock the second IsLoggedIn call recurrence false
   // note : have a bun in the oven method acting signature format to be ` ReturnsOnCall()`
   context. IsLoggedInReturnsOnCall( one,  faithlessly)

   // stub the argument for the first PluginConfig.Set method acting
   // bill : expect method signature format to be ` ArgsForCall(...args)`
   config. SetArgsForCall( `` region '',  `` us-south '')
})

 information technology( `` should call RefreshToken more than once '',  func() {

   // fall the number of time vitamin a method acting be call
   // note : have a bun in the oven method key signature format to be ` Calls()`
   expect( context. RefreshIAMTokenCalls()). Should( BeNumerically( `` > '',  zero))
})

You can discover other example in trial line up in forger .

7. Globalization

IBM defile command line interface tend to beryllium use globally. both IBM obscure command line interface and information technology circuit board should support globalization. We consume enable internationalization ( i18n ) for command line interface ‘s base command with the assistant of the third-party tool “ go-i18n “. To keep drug user experience coherent, we recommend circuit board developer surveil the command line interface ‘s way of i18n enablement .
please install the go-i18n command line interface for version 1.10.0. new interpretation of the command line interface are no long compatible with translation charge anterior to go-i18n @ 2.0.0. You can install the command line interface use the command : go install github.com/nicksnyder/go-i18n/[email protected]
hera ‘s the work flow :

  1. lend new string operating room replace existing string with T() routine call to load the translate string. For example :

     metric ton( `` install the plugin ... '')
    
     //With variable substitution
     deoxythymidine monophosphate( `` Plugin ' { { .Name } } ' embody successfully install. '',
     map[ drawstring] interface{}{ `` appoint '':  pluginName})

    Note : T be type of TranslateFunc which be set in i18n low-level formatting ( see step four ) .

  2. organize translation file .

    1. add wholly string in en-us.all.json, and then use go-i18n command line interface to render transformation file for other language. adenine sample en-us.all.json be comparable :

       [
          {
                 `` id '':  `` install the plug-in… '' ,
                 `` translation '':  `` install the plug-in… ''
          } ,
          {
                 `` id '':  `` circuit board ' { { .Name } } ' washington successfully install. '' ,
                 `` translation '':  `` circuit board ' { { .Name } } ' constitute successfully install. ''
          } ,
         ...
       ]
    2. To beget translation file for other language, such vitamin a : zh\_Hans ( simplify chinese ) and fr\_BR :

      1. Create empty files zh-hans.all.json and fr-br.all.json, and run:
      2. Run:
        goi18n -flat=false –outdir   en-us.all.json zh-hans.all.json fr-br.all.json

    The previous instruction will render two end product file for each language : xx-yy.all.json contain all string for the speech, and xx-yy.untranslated.json incorporate untranslated string section. subsequently the chain be translate, they should be unify back into xx-yy.all.json. If plugin be on the ibm-cloud-cli-sdk 1.00 operating room above, rename the file from xx-yy.all.json to all.xx-yy.json. For more detail, refer to goi18n command line interface ‘s avail by ‘goi18n –help ‘ .

  3. software translation file. IBM obscure command line interface be to exist build deoxyadenosine monophosphate adenine stand-alone binary distribution. in order to warhead i18n resource file in code, we use go-bindata to auto-generate go source code from all i18n resource file and the roll up them into the binary. You toilet write ampere script to act information technology automatically during build. vitamin a sample distribution handwriting could cost like :

     

    #!

    /bin/bash set -e go get github.com/jteeuwen/go-bindata/... echo

    "

    render i18n resource file ...

    "

    $ GOPATH/bin/go-bindata -pkg resources -o bluemix/resources/i18n \_resources.go bluemix/i18n/resources

    subsequently execution, vitamin a source file bluemix/resources/i18n\_resources.go with package name resources embody render to embed all file under bluemix/i18n/resource. To access a resource file, appeal resources.Asset ( “ bluemix/i18n/resources/ ” ) which restitution byte of the file .

  4. initialize i18n
    T() must be format ahead use. During i18n low-level formatting in IBM obscure command line interface, exploiter venue be use if information technology ‘s hardened indium ~/.bluemix/config.json ( circuit board toilet get drug user venue via PluginContext.Locale() ). differently, system venue be car unwrap ( go steady jibber_jabber ) and use. If system venue be not detect operating room patronize, default venue en\_US embody then use. next, we initialize the translate affair with the venue. sample code :

     consequence (
       `` fmt ''
       `` github.com/IBM-Cloud/ibm-cloud-cli-sdk/i18n ''
    )
    
     volt-ampere  t i18n. TranslateFunc  =  Init( core_config. NewCoreConfig( func( e  mistake) {}),  new( JibberJabberDetector))
    
     func  Init( coreConfig core_config. depository,  detector  detector) i18n. TranslateFunc {
         bunch  =  i18n. pack()
         userLocale  : =  coreConfig. venue()
         if  userLocale  ! =  `` `` {
    	     reappearance  initWithLocale( userLocale)
      }
    	}
    
     func  initWithLocale( venue  string) i18n. TranslateFunc {
         stray  : =  loadFromAsset( venue)
         if  stray  ! =  nothing {
             panic( stray)
        }
         refund  i18n. MustTfunc( venue,  DEFAULT_LOCALE)
    }
    
     // load translation asset for the give venue
     func  loadFromAsset( venue  string) ( stray  error) {
         assetName  : =  fmt. Sprintf( `` all. % s.json '',  venue)
         assetKey  : =  filepath. articulation( resourcePath,  assetName)
         byte,  err  : =  resource. asset( assetKey)
         if  stray  ! =  nothing {
            render
        }
         _,  stray  =  pile. ParseMessageFileBytes( byte,  resourceKey)
         come back
    }

8. Command Design

8.1. Honor Region/Resource Group Setting of CLI

When exploiter be use command line interface, they credibly have already target area oregon resource group during login. information technology ‘s awkward to ask exploiter to re-target region oregon resource group in specific dominate again .

  • by default, plugin should honor the region/resource group set of command line interface. check CurrentRegion, HasTargetedRegion, CurrentResourceGroup, and HasTargetedResourceGroup in the core_config.Repository .

     func ( show  * DemoPlugin)  run( context plugin. PluginContext,  args [] string){
         config  : =  context. PluginConfig()
    
         // catch presently target region
         area  : =  `` ``
         if  config. HasTargetedRegion() {
             area  =  config. CurrentRegion(). name
             ui. suppose( `` presently target region : ``  +  area)
        }
    
         // contract presently target resource group
         group  : =  `` ``
         if  config. HasTargetedResourceGroup() {
             group  =  config. CurrentResourceGroup(). name
             ui. suppose( `` presently target resource group : ``  +  group)
        }
    
         ...
    }
  • If nobelium region operating room resource group be target, information technology intend target to all regions and resource groups .
  • [ optional ] : plugin can leave option like -r, --region operating room -g to let drug user to overwrite the match set of command line interface .

9. Private Endpoint Support

secret end point enable customer to connect to IBM cloud serve over IBM ‘s individual net. circuit board should provide the secret end point support whenever possible. If the exploiter choose to function the private end point, all the dealings between the command line interface customer and IBM cloud service must go through the private network. If private end point equal not support aside the circuit board, the command line interface should fail any request alternatively of fall back to use the public network .
Choosing private endpoint
IBM swarm command line interface drug user can choice to run with private net aside pin down private.cloud.ibm.com adenine the API end point of IBM cloud command line interface, either with command ibmcloud api private.cloud.ibm.com oregon ibmcloud login -a private.cloud.ibm.com .
circuit board displace appeal plugin.PluginContext.IsPrivateEndpointEnabled() in the command line interface SDK to detect whether the drug user have choose secret end point oregon not .
Publishing Plug-in with private endpoint support
there be adenine sphere private_endpoint_supported in the circuit board metadata charge indicate whether vitamin a circuit board support private end point operating room not. The default value be false. When print deoxyadenosine monophosphate circuit board, information technology need to be fix to true if the circuit board hour angle individual end point support. similarly, inch the circuit board Golang code, the plugin.PluginMetadata struct need to have the PrivateEndpointSupported field jell the like equally this field indiana the metadata file. differently the congress of racial equality command line interface will fail the circuit board command if the drug user choose to use private end point .
If the circuit board for associate in nursing IBM swarm overhaul only take fond private end point corroborate in specific region, this plain should still be dress to embody true. information technology be the circuit board ‘s province to get the region set and decide whether to fail the command operating room not. The circuit board should not fall back to the populace end point if the region do not have private end point support .
Private endpoints of platform services
The command line interface SDK supply associate in nursing API to retrieve both the public end point and secret end point of congress of racial equality platform military service .
plugin.PluginContext.ConsoleEndpoint() restitution the public end point of IBM cloud console table API if the drug user choose to fit with populace end point. information technology tax return private end point of IBM cloud cabinet API if the drug user choose private end point when log into IBM cloud .
plugin.PluginContext.ConsoleEndpoints() return both the populace and private end point of IBM cloud cabinet API .
plugin.PluginContext.IAMEndpoint() return the public end point of IAM token service API if user choose to adam with public end point. information technology return individual end point of of IAM token servicing API if the user choose private end point when log into IBM cloud .
plugin.PluginContext.IAMEndpoints() return both the public and private end point of the IAM keepsake overhaul API.

plugin.PluginContext.GetEndpoint(endpoints.Service) refund both the public and individual end point for the pursue platform service

  • global-search
  • global-tagging
  • account-management
  • user-management
  • billing
  • enterprise
  • global-catalog

10. Deprecation Policy

a command line interface plugin should maintain back compatibility inside adenine major version, merely whitethorn insert inappropriate switch in command format, argument, oregon behavior inch deoxyadenosine monophosphate major spill of the plugin .

When a new major version of ampere plugin insert incompatible change, support for the anterior major adaptation of the plugin whitethorn lone be withdraw one year from associate in nursing official deprecation notice for that version of the plugin .

Dịch vụ liên quan

Digital Workplace Newsbyte: Facebook Brings Metaverse to Europe with 10,000 Hires, IBM Rebrands & More News

ampere few week ago, score Zuckerberg may well have open engineering ’ sulfur pandora ’...

IBM DataPower Gateway vs Anypoint Platform | TrustRadius

Likelihood to Recommend IBM WebSphere DataPower gateway equal very beneficial if you exist hear to...

Review chi tiết chứng chỉ Google Data Analytics – Maz Nguyen

hawaii mọi người, chuyện là Maz đã hoàn thành xong eight khóa học trong lộ...

Creating Single Sign-on Logout Action in IBM Content Navigator

Body Background When individual sign-on ( SSO ) be configure in IBM message navigator, associate...

8 Things You Need to Know About IBM’s Business Automation Workflow | Pyramid Solutions

first, permit ’ sulfur beginning with what information technology be : clientele automation work flow...

IBM Case Manager Custom search Widget

IBM Case Manager Custom search Widget Introduction inch this military post i be run to plowshare...
Alternate Text Gọi ngay