# Hacking with Hammer
![](img/claw_hammer.jpg)
Tomáš Strachota
tstracho@redhat.com
Use arrow keys to switch the slides.
# History
**April 2012**
![](img/initial_commit_1.png)
**July 2013**
![](img/initial_commit_2.png)
# History - 1.5 years later
- hammer-cli v0.1.4
- 20 releases
- 12 plugins
- hammer-cli-foreman
- hammer-cli-katello
- hammer-cli-discovery
- and others...
- we have ~ 70% core commands
([http://projects.theforeman.org/projects/hammer-cli/wiki/List_of_Plugins](http://projects.theforeman.org/projects/hammer-cli/wiki/List_of_Plugins))
# Future
- improving usability
- improving internal API
- completing command gaps and catching up with UI features
# Tutorial - CLI for Foreman settings
![](img/issue.png)
- hammer settings list
- hammer settings set
# Development setup
### Get the code
![](img/fork.png)
```bash
> git clone git@github.com:theforeman/hammer-cli.git
```
```bash
> git clone git@github.com:theforeman/hammer-cli-foreman.git
```
### Configure hammer
```bash
mkdir -p ~/.hammer/cli.modules.d/
cp hammer-cli/config/cli_config.template.yml ~/.hammer/
cp hammer-cli-foreman/config/foreman.yml ~/.hammer/cli.modules.d/
```
### Plug the foreman in
```ruby
# hammer-cli/Gemgile.local
gem 'hammer_cli_foreman', :path => '../hammer-cli-foreman'
```
```bash
alias hammer=bundle exec hammer-cli/bin/hammer
```
# Before we start
- Check online api documentation [http://www.theforeman.org/api_v2.html](http://www.theforeman.org/api_v2.html)
- We're using **API v2** !
![Settings API](img/settings_api.png)
# Before we start
- Hammer reuses information from ApiPie docs
![Settings API](img/settings_api_index_detail.png)
# Where to place the command?
hammer-cli-foreman structure
```bash
> tree -d -L 1
.
├── config # Example configuration files
├── doc # Documentation
├── lib # The code itself
├── locale # Translations
└── test # Unit tests
```
# Step 1 - Create a new command file
```bash
> cd hammer-cli-foreman/lib && tree
.
├── hammer_cli_foreman # One file per first level command
│ ├── architecture.rb
│ ├── associating_commands.rb
│ ├── auth.rb
│ ├── auth_source_ldap.rb
│ ├── auth_source.rb
│ ├── commands.rb
│ ├── common_parameter.rb
│ ├── compute_resource.rb
│ ├── credentials.rb
│ ├── dependency_resolver.rb
│ ├── domain.rb
```
Create the file under a correct namespace:
```bash
touch lib/hammer_cli_foreman/settings.rb
```
# Step 2 - Create a new command class
```ruby
#lib/hammer_cli_foreman/settings.rb
```
# Step 2 - Create a new command class
```ruby
#lib/hammer_cli_foreman/settings.rb
module HammerCLIForeman
end
```
Wrap all your commands in a module.
# Step 2 - Create a new command class
```ruby
#lib/hammer_cli_foreman/settings.rb
module HammerCLIForeman
# Wraper command
class Settings < HammerCLIForeman::Command
end
end
```
Create wrapper command `hammer settings`.
# Step 2 - Create a new command class
```ruby
#lib/hammer_cli_foreman/settings.rb
module HammerCLIForeman
# Wraper command
class Settings < HammerCLIForeman::Command
# Set API resource
resource :settings
end
end
```
Set the API resource.
# Step 2 - Create a new command class
```ruby
#lib/hammer_cli_foreman/settings.rb
module HammerCLIForeman
# Wraper command
class Settings < HammerCLIForeman::Command
# Set API resource
resource :settings
class ListCommand < HammerCLIForeman::ListCommand
end
end
end
```
There are base command classes with predefined behavior:
`ListCommand`, `ShowCommand`, `CreateCommand`, `UpdateCommand`, `DeleteCommand`.
# Step 2 - Create a new command class
```ruby
#lib/hammer_cli_foreman/settings.rb
module HammerCLIForeman
# Wraper command
class Settings < HammerCLIForeman::Command
# Set API resource
resource :settings
class ListCommand < HammerCLIForeman::ListCommand
end
autoload_subcommands # Plug the subcommands in
end
end
```
There are base command classes with predefined behavior:
`ListCommand`, `ShowCommand`, `CreateCommand`, `UpdateCommand`, `DeleteCommand`.
# Step 2 - Let's try the new command
```bash
> hammer settings -h
```
# Step 2 - Let's try the new command
```bash
> hammer settings -h
Error: No such sub-command 'settings'
See: 'hammer --help'
```
Setting is still missing...
# Step 3 - Attach the new command
Add magic lines to `lib/hammer_cli_foreman.rb` ...
```ruby
HammerCLI::MainCommand.lazy_subcommand('settings',
_("Change server settings."), # command description
'HammerCLIForeman::Settings', # command class
'hammer_cli_foreman/settings' # path to the command file
)
```
# Step 3 - Attach the new command
Add magic lines to `lib/hammer_cli_foreman.rb` ...
```ruby
HammerCLI::MainCommand.lazy_subcommand('settings',
_("Change server settings."), # command description
'HammerCLIForeman::Settings', # command class
'hammer_cli_foreman/settings' # path to the command file
)
```
...and try again.
```bash
> hammer settings -h
```
# Step 3 - Attach the new command
Add magic lines to `lib/hammer_cli_foreman.rb` ...
```ruby
HammerCLI::MainCommand.lazy_subcommand('settings',
_("Change server settings."), # command description
'HammerCLIForeman::Settings', # command class
'hammer_cli_foreman/settings' # path to the command file
)
```
...and try again.
```bash
> hammer settings -h
Usage:
hammer settings [OPTIONS] SUBCOMMAND [ARG] ...
Parameters:
SUBCOMMAND subcommand
[ARG] ... subcommand arguments
Subcommands:
list List all settings
Options:
-h, --help print help
```
# Step 4 - Let's try listing
```bash
> hammer settings list
```
# Step 4 - Let's try listing
```bash
> hammer settings list
>
```
...no output
# Step 4 - Let's try listing
```bash
> hammer settings list
>
```
...no output
```bash
> hammer -d settings list
```
# Step 4 - Let's try listing
```bash
> hammer settings list
>
```
...no output
```bash
> hammer -d settings list
[ INFO 2015-01-28 14:59:40 Init] Initialization of Hammer CLI (0.1.4) has started...
[DEBUG 2015-01-28 14:59:40 Init] Running at ruby 1.8.7-p374
[ INFO 2015-01-28 14:59:40 Init] Configuration from the file /etc/hammer/cli_config.yml has been loaded
[ INFO 2015-01-28 14:59:40 Init] Configuration from the file /etc/hammer/cli.modules.d/foreman.yml has been loaded
[ INFO 2015-01-28 14:59:40 Init] Configuration from the file /root/.hammer/cli_config.yml has been loaded
[DEBUG 2015-01-28 14:59:41 Connection] Registered: foreman
[DEBUG 2015-01-28 14:59:41 API] Global headers: {
"Accept-Language" => "en",
:accept => "application/json;version=2",
:content_type => "application/json"
}
[DEBUG 2015-01-28 14:59:41 Init] Apipie cache was cleared
[ INFO 2015-01-28 14:59:41 API] GET /apidoc/apipie_checksum
[DEBUG 2015-01-28 14:59:41 API] Params: {}
[DEBUG 2015-01-28 14:59:41 API] Headers: {
:accept => "application/json",
:params => {}
}
[DEBUG 2015-01-28 14:59:41 API] Response: {
"checksum" => "0e10ccff1babc8fd126d0c0f0fb2a6cc"
}
[DEBUG 2015-01-28 14:59:41 API] Response headers: {
:x_ua_compatible => "IE=Edge",
:apipie_checksum => "0e10ccff1babc8fd126d0c0f0fb2a6cc",
:set_cookie => [
[0] "request_method=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT"
],
:server => "thin",
:connection => "close",
:content_type => "application/json; charset=utf-8",
:cache_control => "max-age=0, private, must-revalidate",
:x_request_id => "d9c19d5a76db080ddcbe435ab97fd84e",
:etag => "\"91d0030428a55dfb6417ec20900fc504\"",
:x_runtime => "0.011813"
}
[ INFO 2015-01-28 14:59:41 API] GET /apidoc/v2.en.json
[DEBUG 2015-01-28 14:59:41 API] Params: {}
[DEBUG 2015-01-28 14:59:41 API] Headers: {
:accept => "application/json",
:params => {}
}
[DEBUG 2015-01-28 14:59:41 API] 404 Resource Not Found
" "
[ INFO 2015-01-28 14:59:41 API] GET /apidoc/v2.json
[DEBUG 2015-01-28 14:59:41 API] Params: {}
[DEBUG 2015-01-28 14:59:41 API] Headers: {
:accept => "application/json",
:params => {}
}
[DEBUG 2015-01-28 14:59:41 API] Response: Received OK
[DEBUG 2015-01-28 14:59:41 API] Response headers: {
:x_ua_compatible => "IE=Edge",
:apipie_checksum => "0e10ccff1babc8fd126d0c0f0fb2a6cc",
:content_disposition => "inline; filename=\"v2.json\"",
:content_transfer_encoding => "binary",
:set_cookie => [
[0] "request_method=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT"
],
:server => "thin",
:connection => "close",
:content_type => "application/json",
:cache_control => "private",
:x_request_id => "32908515ceba20efbd1e3e285008f386",
:x_runtime => "0.008055"
}
[DEBUG 2015-01-28 14:59:41 API] New apidoc loaded from the server
[ INFO 2015-01-28 14:59:41 API] GET /apidoc/apipie_checksum
[DEBUG 2015-01-28 14:59:41 API] Params: {}
[DEBUG 2015-01-28 14:59:41 API] Headers: {
:accept => "application/json",
:params => {}
}
[DEBUG 2015-01-28 14:59:41 API] Response: {
"checksum" => "0e10ccff1babc8fd126d0c0f0fb2a6cc"
}
[DEBUG 2015-01-28 14:59:41 API] Response headers: {
:x_ua_compatible => "IE=Edge",
:apipie_checksum => "0e10ccff1babc8fd126d0c0f0fb2a6cc",
:set_cookie => [
[0] "request_method=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT"
],
:server => "thin",
:connection => "close",
:content_type => "application/json; charset=utf-8",
:cache_control => "max-age=0, private, must-revalidate",
:x_request_id => "67e406ef26d70767755c72dfeed91c84",
:etag => "\"91d0030428a55dfb6417ec20900fc504\"",
:x_runtime => "0.011414"
}
[ INFO 2015-01-28 14:59:41 Modules] Extension module hammer_cli_foreman (0.1.4) loaded
[DEBUG 2015-01-28 14:59:41 Init] Using locale 'en'
[DEBUG 2015-01-28 14:59:41 Init] 'mo' files for locale domain 'hammer-cli' loaded from '/root/hammer/hammer-cli/locale'
[DEBUG 2015-01-28 14:59:41 Init] 'mo' files for locale domain 'hammer-cli@system' loaded from '/usr/share/locale'
[DEBUG 2015-01-28 14:59:41 Init] 'mo' files for locale domain 'hammer-cli-foreman' loaded from '/root/hammer/hammer-cli-foreman/locale'
[DEBUG 2015-01-28 14:59:41 Init] 'mo' files for locale domain 'hammer-cli-foreman@system' loaded from '/usr/share/locale'
[ INFO 2015-01-28 14:59:41 HammerCLI::MainCommand] Called with options: {"option_debug"=>true}
[ INFO 2015-01-28 14:59:41 HammerCLIForeman::Settings] Called with options: {}
[ INFO 2015-01-28 14:59:41 HammerCLIForeman::Settings::ListCommand] Called with options: {}
[ INFO 2015-01-28 14:59:41 API] GET /apidoc/apipie_checksum
[DEBUG 2015-01-28 14:59:41 API] Params: {}
[DEBUG 2015-01-28 14:59:41 API] Headers: {
:accept => "application/json",
:params => {}
}
[DEBUG 2015-01-28 14:59:41 API] Response: {
"checksum" => "0e10ccff1babc8fd126d0c0f0fb2a6cc"
}
[DEBUG 2015-01-28 14:59:41 API] Response headers: {
:x_ua_compatible => "IE=Edge",
:apipie_checksum => "0e10ccff1babc8fd126d0c0f0fb2a6cc",
:set_cookie => [
[0] "request_method=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT"
],
:server => "thin",
:connection => "close",
:content_type => "application/json; charset=utf-8",
:cache_control => "max-age=0, private, must-revalidate",
:x_request_id => "62d7bc3377fc01af41347be65330e958",
:etag => "\"91d0030428a55dfb6417ec20900fc504\"",
:x_runtime => "0.011806"
}
[ INFO 2015-01-28 14:59:41 API] GET /api/settings
[DEBUG 2015-01-28 14:59:41 API] Params: {}
[DEBUG 2015-01-28 14:59:41 API] Headers: {
:params => {}
}
[DEBUG 2015-01-28 14:59:41 API] Response: {
"search" => nil,
"per_page" => 20,
"page" => 1,
"subtotal" => 63,
"total" => 63,
"results" => [
[ 0] {
"created_at" => "2014-06-20T17:29:20+01:00",
"updated_at" => "2014-10-20T16:04:06+01:00",
"settings_type" => "array",
"description" => "Foreman will evaluate host smart variables in this order by default",
"value" => [
[0] "fqdn",
[1] "hostgroup",
[2] "os",
[3] "domain"
],
"id" => 19,
"category" => "Setting::Puppet",
"default" => [
[0] "fqdn",
[1] "hostgroup",
[2] "os",
[3] "domain"
],
"name" => "Default_variables_Lookup_Path"
},
[ 1] {
"created_at" => "2014-06-20T17:29:20+01:00",
"updated_at" => "2014-10-20T16:04:06+01:00",
"settings_type" => "boolean",
"description" => "Authorize login delegation with REMOTE_USER environment variable",
"value" => false,
"id" => 7,
"category" => "Setting::General",
"default" => false,
"name" => "authorize_login_delegation"
},
[ 2] {
"created_at" => "2014-06-20T17:29:20+01:00",
"updated_at" => "2014-10-20T16:04:06+01:00",
"settings_type" => "boolean",
"description" => "Authorize login delegation with REMOTE_USER environment variable for API calls too",
"value" => false,
"id" => 8,
"category" => "Setting::General",
"default" => false,
"name" => "authorize_login_delegation_api"
},
[ 3] {
"created_at" => "2014-06-20T17:29:21+01:00",
"updated_at" => "2014-10-20T16:04:07+01:00",
"settings_type" => nil,
"description" => "Name of the external auth source where unknown externally authentication users (see authorize_login_delegation) should be created (keep unset to prevent the autocreation)",
"value" => nil,
"id" => 60,
"category" => "Setting::Auth",
"default" => nil,
"name" => "authorize_login_delegation_auth_source_user_autocreate"
},
[ 4] {
"created_at" => "2014-06-20T17:29:20+01:00",
"updated_at" => "2014-10-20T16:04:07+01:00",
"settings_type" => "boolean",
"description" => "Foreman will create the host when new facts are received",
"value" => true,
"id" => 27,
"category" => "Setting::Puppet",
"default" => true,
"name" => "create_new_host_when_facts_are_uploaded"
}
],
"sort" => {
"by" => nil,
"order" => nil
}
}
[DEBUG 2015-01-28 14:59:41 API] Response headers: {
:x_ua_compatible => "IE=Edge",
:foreman_version => "1.8.0-develop",
:apipie_checksum => "0e10ccff1babc8fd126d0c0f0fb2a6cc",
:set_cookie => [
[0] "_session_id=7d26025dfc37197c1b0ec625f348e51b; path=/; HttpOnly",
[1] "request_method=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT"
],
:server => "thin",
:connection => "close",
:content_type => "application/json; charset=utf-8",
:cache_control => "max-age=0, private, must-revalidate",
:x_request_id => "eef017bbf59c52edb877cf6f9bbf968a",
:etag => "\"5ca93855e32208e24ee30442357a7194\"",
:x_runtime => "0.199984",
:foreman_api_version => "2"
}
```
# Step 5 - Defining the output
Hammer needs to know which fields should be displayed.
Where do I get available fields?
- examples from API docs
- running in debug mode `hammer -d`
```bash
[14] {
"id" => 15,
"category" => "Setting::Puppet",
"created_at" => "2014-06-20T17:29:20+01:00",
"description" => "Document root where puppetdoc files should be created",
"value" => "/root/foreman/public/puppet/rdoc",
"updated_at" => "2014-10-20T16:04:06+01:00",
"default" => "/root/foreman/public/puppet/rdoc",
"settings_type" => "string",
"name" => "document_root"
},
```
`name`, `value` and `description` seem to be important
# Step 5 - Defining output fields
```ruby
#lib/hammer_cli_foreman/settings.rb
module HammerCLIForeman
class Settings < HammerCLIForeman::Command
resource :settings
class ListCommand < HammerCLIForeman::ListCommand
end
autoload_subcommands
end
end
```
# Step 5 - Defining output fields
```ruby
#lib/hammer_cli_foreman/settings.rb
module HammerCLIForeman
class Settings < HammerCLIForeman::Command
resource :settings
class ListCommand < HammerCLIForeman::ListCommand
output do
end
end
autoload_subcommands
end
end
```
# Step 5 - Defining output fields
```ruby
#lib/hammer_cli_foreman/settings.rb
module HammerCLIForeman
class Settings < HammerCLIForeman::Command
resource :settings
class ListCommand < HammerCLIForeman::ListCommand
output do
field :name, _('Name')
field :value, _('Value')
field :description, _('Description')
end
end
autoload_subcommands
end
end
```
# Step 5 - Defining output fields
```bash
> hammer settings list
```
# Step 5 - Defining output fields
```bash
> hammer settings list
-------------------------------|------------|-------------------
NAME | VALUE | DESCRIPTION
-------------------------------|------------|-------------------
Default_variables_Lookup_Path | [ "fqdn" ] | Foreman will evalu
Enable_Smart_Variables_in_ENC | true | Foreman smart vari
Parametrized_Classes_in_ENC | true | Foreman will use t
authorize_login_delegation | | Authorize login de
authorize_login_delegation_api | | Authorize login de
```
# Step 6 - Updating settings
```ruby
#lib/hammer_cli_foreman/settings.rb
class UpdateCommand < HammerCLIForeman::UpdateCommand
end
```
```bash
> hammer settings update -h
```
# Step 6 - Updating settings
```ruby
#lib/hammer_cli_foreman/settings.rb
class UpdateCommand < HammerCLIForeman::UpdateCommand
end
```
```bash
> hammer settings update -h
Usage:
hammer settings update [OPTIONS]
Options:
-h, --help print help
```
# Step 6 - Updating settings
```ruby
#lib/hammer_cli_foreman/settings.rb
class UpdateCommand < HammerCLIForeman::UpdateCommand
# Change the default name
command_name 'set'
end
```
```bash
> hammer settings set -h
```
# Step 6 - Updating settings
```ruby
#lib/hammer_cli_foreman/settings.rb
class UpdateCommand < HammerCLIForeman::UpdateCommand
# Change the default name
command_name 'set'
end
```
```bash
> hammer settings set -h
Usage:
hammer settings set [OPTIONS]
Options:
-h, --help print help
```
# Step 6 - Updating settings
```ruby
#lib/hammer_cli_foreman/settings.rb
class UpdateCommand < HammerCLIForeman::UpdateCommand
# Change the default name
command_name 'set'
# Build options based on the API docs
build_options
end
```
```bash
> hammer settings set -h
```
# Step 6 - Updating settings
```ruby
#lib/hammer_cli_foreman/settings.rb
class UpdateCommand < HammerCLIForeman::UpdateCommand
# Change the default name
command_name 'set'
# Build options based on the API docs
build_options
end
```
```bash
> hammer settings set -h
Usage:
hammer settings set [OPTIONS]
Options:
--id ID
--name NAME Setting name
--value VALUE
-h, --help print help
```
# Step 6 - Updating settings - test
```bash
> hammer settings set --name Default_variables_Lookup_Path --value '[ "fqdn", "os" ]'
```
# Step 6 - Updating settings - test
```bash
> hammer settings set --name Default_variables_Lookup_Path --value '[ "fqdn", "os" ]'
>
```
No output again!
# Step 6 - Updating settings - test
```bash
> hammer settings set --name Default_variables_Lookup_Path --value '[ "fqdn", "os" ]'
>
```
No output again!
```bash
> hammer settings list
```
# Step 6 - Updating settings - test
```bash
> hammer settings set --name Default_variables_Lookup_Path --value '[ "fqdn", "os" ]'
>
```
No output again!
```bash
> hammer settings list
-------------------------------|------------------|-------------
NAME | VALUE | DESCRIPTION
-------------------------------|------------------|-------------
Default_variables_Lookup_Path | [ "fqdn", "os" ] | Foreman will
Enable_Smart_Variables_in_ENC | true | Foreman smar
Parametrized_Classes_in_ENC | true | Foreman will
authorize_login_delegation | | Authorize lo
authorize_login_delegation_api | | Authorize lo
```
# Step 7 - Better output for settings set
```ruby
#lib/hammer_cli_foreman/settings.rb
class UpdateCommand < HammerCLIForeman::UpdateCommand
command_name 'set'
build_options
end
```
# Step 7 - Better output for settings set
```ruby
#lib/hammer_cli_foreman/settings.rb
class UpdateCommand < HammerCLIForeman::UpdateCommand
command_name 'set'
# Define status messages
success_message _("Setting [%{name}] updated to [%{value}]")
failure_message _("Could not update the setting")
build_options
end
```
# Step 7 - Better output for settings set
```ruby
#lib/hammer_cli_foreman/settings.rb
class UpdateCommand < HammerCLIForeman::UpdateCommand
command_name 'set'
# Define status messages
success_message _("Setting [%{name}] updated to [%{value}]")
failure_message _("Could not update the setting")
build_options
end
```
Success message:
```bash
> hammer settings set --name Default_variables_Lookup_Path --value '[ "fqdn", "os" ]'
```
# Step 7 - Better output for settings set
```ruby
#lib/hammer_cli_foreman/settings.rb
class UpdateCommand < HammerCLIForeman::UpdateCommand
command_name 'set'
# Define status messages
success_message _("Setting [%{name}] updated to [%{value}]")
failure_message _("Could not update the setting")
build_options
end
```
Success message:
```bash
> hammer settings set --name Default_variables_Lookup_Path --value '[ "fqdn", "os" ]'
Setting [Default_variables_Lookup_Path] updated to [["fqdn", "os"]]
```
# Step 7 - Better output for settings set
```ruby
#lib/hammer_cli_foreman/settings.rb
class UpdateCommand < HammerCLIForeman::UpdateCommand
command_name 'set'
# Define status messages
success_message _("Setting [%{name}] updated to [%{value}]")
failure_message _("Could not update the setting")
build_options
end
```
Failure message:
```bash
> hammer settings set --name Default_variables_Lookup_Path --value '123'
```
# Step 7 - Better output for settings set
```ruby
#lib/hammer_cli_foreman/settings.rb
class UpdateCommand < HammerCLIForeman::UpdateCommand
command_name 'set'
# Define status messages
success_message _("Setting [%{name}] updated to [%{value}]")
failure_message _("Could not update the setting")
build_options
end
```
Failure message:
```bash
> hammer settings set --name Default_variables_Lookup_Path --value '123'
Could not update the setting:
Value is invalid: must be an array
```
# And that's it!
```bash
> hammer settings -h
Usage:
hammer settings [OPTIONS] SUBCOMMAND [ARG] ...
Parameters:
SUBCOMMAND subcommand
[ARG] ... subcommand arguments
Subcommands:
list List all settings
set Update a setting
Options:
-h, --help print help
```
# And that's it!
```bash
> hammer settings -h
Usage:
hammer settings [OPTIONS] SUBCOMMAND [ARG] ...
Parameters:
SUBCOMMAND subcommand
[ARG] ... subcommand arguments
Subcommands:
list List all settings
set Update a setting
Options:
-h, --help print help
```
The last step is:
```bash
git commit -m 'Fixes #2918 - Add commands for settings'
```
![](img/create_pr.png)
Check out the code on github http://bit.ly/1E7p8XP
When tuning is needed
![](img/tuning.png)
# When tuning is needed
`hammer -d` is your friend
```bash
[ INFO 2015-01-28 14:59:40 Init] Initialization of Hammer CLI (0.1.4) has started...
[DEBUG 2015-01-28 14:59:40 Init] Running at ruby 1.8.7-p374
[ INFO 2015-01-28 14:59:40 Init] Configuration from the file /etc/hammer/cli_config.yml has been loaded
[ INFO 2015-01-28 14:59:40 Init] Configuration from the file /etc/hammer/cli.modules.d/foreman.yml has been loaded
[ INFO 2015-01-28 14:59:40 Init] Configuration from the file /root/.hammer/cli_config.yml has been loaded
[DEBUG 2015-01-28 14:59:41 Connection] Registered: foreman
[DEBUG 2015-01-28 14:59:41 API] Global headers: {
"Accept-Language" => "en",
:accept => "application/json;version=2",
:content_type => "application/json"
}
```
# When tuning is needed
Extending incoming data
```ruby
class ListCommand < HammerCLIForeman::ListCommand
output do
field :name, _('Name')
field :value, _('Value')
field :description, _('Description')
end
build_options
end
```
# When tuning is needed
Extending incoming data
```ruby
class ListCommand < HammerCLIForeman::ListCommand
output do
field :name, _('Name')
field :value, _('Value')
field :description, _('Description')
end
# Individualy change each item
def extend_data(data)
data['value'] = data['value'].to_s
data
end
build_options
end
```
# When tuning is needed
Disabling options
```ruby
class ListCommand < HammerCLIForeman::ListCommand
output do
field :name, _('Name')
field :value, _('Value')
field :description, _('Description')
end
build_options
end
```
# When tuning is needed
Disabling options
```ruby
class ListCommand < HammerCLIForeman::ListCommand
output do
field :name, _('Name')
field :value, _('Value')
field :description, _('Description')
end
build_options :without => [:search, :order]
end
```
# Creating custom plugin
- plugins are nothing but gems
# Creating custom plugin
- plugins are nothing but gems
- gem needs to be named `"hammer_cli_<plugin_name>"`
# Creating custom plugin
- plugins are nothing but gems
- gem needs to be named `"hammer_cli_<plugin_name>"`
- yaml settings
- file placed in `<hammer_cfg_path>/cli.modules.d/`
- values nested in a `<plugin_name>`
- enabling the plugin in the settings
# Creating custom plugin
- plugins are nothing but gems
- gem needs to be named `"hammer_cli_<plugin_name>"`
- yaml settings
- file placed in `<hammer_cfg_path>/cli.modules.d/`
- values nested in a `<plugin_name>`
- enabling the plugin in the settings
```yaml
:foreman: # <plugin_name>
# Enable/disable foreman commands
:enable_module: true
# Your foreman server address
:host: 'https://localhost/'
```
# Creating custom plugin
- plugins are nothing but gems
- gem needs to be named `"hammer_cli_<plugin_name>"`
- yaml settings
- file placed in `<hammer_cfg_path>/cli.modules.d/`
- values nested in a `<plugin_name>`
- enabling the plugin in the settings
```yaml
:foreman: # <plugin_name>
# Enable/disable foreman commands
:enable_module: true
# Your foreman server address
:host: 'https://localhost/'
```
- add commands to the `MainCommand` at load time
```ruby
HammerCLI::MainCommand.subcommand
HammerCLI::MainCommand.lazy_subcommand
```
# Want to know more?
## Documentation:
- Clamp
[https://github.com/mdub/clamp/](https://github.com/mdub/clamp/)
- Hammer CLI
[https://github.com/theforeman/hammer-cli/](https://github.com/theforeman/hammer-cli/)
- Hammer CLI Foreman
[https://github.com/theforeman/hammer-cli-foreman/](https://github.com/theforeman/hammer-cli-foreman/)
## Looking for help?
- `#foreman` or `#foreman-dev` on FreeNode
- foreman-users@googlegroups.com
- foreman-dev@googlegroups.com
Thanks for your attention!
https://github.com/tstrachota/hammer-cli-foreman/compare/tstrachota:cfgmgmt_demo_before...tstrachota:cfgmgmt_demo
or
http://bit.ly/1E7p8XP