4. Commands and Bundles¶
As a chatops bot, commands are central to Cog. After all, without commands, Cog wouldn’t actually do anything! Let’s take a look at exactly what commands are, how they are organized, and how they are managed.
Current list Cog Bundles: Bundle Warehouse
Let’s start with an example. If I type the following into Slack:
!operable:help
I should receive a response that looks something like this:
I know about these commands:
* date:date
* github:prs
* github:repo
* operable:bundle
* operable:echo
* operable:filter
* operable:greet
* operable:group
* operable:help
* operable:max
* operable:min
* operable:permissions
* operable:role
* operable:rules
* operable:sort
* operable:sum
* operable:table
* operable:thorn
* operable:unique
* operable:wc
Try calling `operable:help COMMAND` to find out more.
I have just executed the help
command from the operable
command
bundle. From the response, I can see that the system currently has three
bundles installed (date
, github
, and operable
), each of
which contains one or more commands. The date
bundle contains a
single command (also named date
), the github
bundle contains a
prs
and a repo
command, and the operable
bundle contains a
great deal of commands, one of which is the help
command we just
invoked.
4.1. Commands¶
If you view your chatbot as a kind of “shared command line”, then
commands are like the executables in your terminal. In fact, you might
recognize several commands from the operable
namespace above from
your everyday terminal usage: echo
, wc
, sort
, etc.
Command may need some additional information that would not be shared on the “shared command line”, but will have to be setup by an administrator, such as an OAuth key. See the section on Dynamic Command Configuration for more information on how to get this data for command execution.
4.2. Bundles¶
Let’s say that you’ve written some new chat commands for Cog. You have one command that spins up new machines in AWS and another that terminates machines.
These commands are clearly related functionally; you probably won’t use one without the other, after all. They also probably share a good bit of library and / or dependency code. It would be nice to have a way to package up these commands in a way that reflects this.
Enter bundles, the packaging unit for commands. Bundles contain all the code for the commands within, including dependencies and library code. They also carry metadata about the commands, including documentation, details about the various options each command recognizes, configuration that affects how the commands behave in execution pipelines, and even formatting templates, which allow the results of commands to be presented in the best possible way for the chat system you use.
This sounds interesting, right? Come see how simple it is: Writing A Command Bundle.
4.2.1. Bundle Permissions and Rules¶
Bundles also contain an initial set of permissions and authorization rules for their commands. When a bundle is installed, these permissions and accompanying rules are automatically created in the Cog system. These can be used as-is, or can be modified by Cog operators in whatever way suits their organization best.
Since permissions are namespaced to the bundle they originate from, installing a bundle’s permissions will never conflict with any existing authorization system configurations you may have made. No users are automatically assigned any of these permissions, either.
4.2.2. Example: The operable
Bundle¶
The operable
bundle is a unique bundle, in that it is effectively
built into the bot (in code, you will see it referred to as the
“embedded bundle”). All Cog instances will have this bundle installed
automatically, and this is how the core permissions and authorization
rules of the system come to be installed.
4.3. Invoking Commands¶
To invoke a command, like operable:help
, you have a few options.
First, you can address the bot directly by name in a channel in which the bot is listening. Here, my bot is named Marvin
@marvin operable:help
Alternatively, you can configure the bot to use a “command prefix”,
which defaults to !
.
!operable:help
Finally, you can interact with the bot in 1-on-1 chat, in which case you may simply type commands directly; everything you type to the bot is considered a command.
operable:help
4.3.1. Shortcuts¶
Fully qualifying all command names with their bundle can get tedious for
frequently-used commands, as well as for long pipeline sequences.
Fortunately, Cog uses a simple rule to alleviate much of this
frustration. If a command name by itself happens to be unique within a
Cog installation (that is, no other bundles have a command with the same
name), you may type the bare command. Thus our repeated invocations of
operable:help
could also have been written simply as help
, since
the operable
bundle is the only bundle currently installed that has
a help
command.
If on the other hand, your installation were to have two or more bundles
that had a help
command, you would need to specify exactly which
help
command you wanted to invoke; operable:help
, foo:help
,
bar:help
, etc. If there is any ambiguity about which command you are
trying to invoke, Cog will not execute any commands, and will instead
warn you.
4.4. Implementation Details¶
Bundles may take one of two forms. The first, which we’ll call a standard bundle is a docker image that contains all of your commands. This is the form you’ll use if you have custom code to implement your chat commands and wish to package that code and distribute it in a bundle.
Warning
Note that versions on Cog prior to version 0.4 used a different packaging system for standard bundles. These old bundles will not work for current versions of Cog.
The other form of bundle is a
simple bundle, which is
essentially just the config.yaml
file from the “standard” bundle.
This form of bundle can be used to expose executables that are already
on the system path, which may be installed “out of band”, using OS
packages, standard configuration management routes, etc.
It should be noted that “simple” bundles can still be configured to
accept arguments and options. The config.yaml
file thus serves to
describe the command to Cog, to ensure that the proper permissions and
rules are in place for the use of the command, and to instruct Cog how
to interpret and expose invocation options to the command.