Project

General

Profile

API

Foreman Smart Proxy provides a REST API, communicating via JSON. For providers that take POST requests, some take form parameters as inputs (var=1&var=2), others may take JSON. Please refer to this document for latest information about Foreman Smart Proxy API.

The API entries containing variant are only available in smart-proxy v2.0 and later.

List of API's

Path REST Type Description Example Input
FEATURES
/features GET List of features supported by the proxy
/version GET Proxy version
DHCP
/dhcp GET Retrieve a list of subnets
/dhcp/10.1.2.0 GET Retrieve 10.1.2.0 subnets records
/dhcp/10.1.2.0/10.1.2.5 GET Retrieve 10.1.2.5 reservation information
/dhcp/10.1.2.0/unused_ip GET Provides an unused ip address in 10.1.2.0 subnet mac=00:00:00:00:00:00&from=10.1.2.3&to=10.1.2.254
/dhcp/10.1.2.0 POST creates new reservation in 10.1.2.0 subnet {"hostname":string, "name":string, "filename":string, "ip":string, "nextServer":string, "mac":string}
/dhcp/10.1.2.0/10.1.2.5 DELETE Deletes 10.1.2.5 reservation from 10.1.2.0 subnet (deprecated since 1.15.0)
/dhcp/10.1.2.0/ip/10.1.2.5 DELETE Deletes 10.1.2.5 IP address reservation from 10.1.2.0 subnet (available since 1.15.0)
/dhcp/10.1.2.0/mac/00:11:22:33:44:55 DELETE Deletes 00:11:22:33:44:55 MAC address reservation from 10.1.2.0 subnet (available since 1.15.0)
DNS
/dns/ POST Create a new DNS record fqdn=hostname.example.com&value=192.168.1.1&type=A
/dns/value DELETE remove DNS record for value (IP or reverse), guessing either PTR or A record
/dns/value/type DELETE remove value DNS record, for a given record type (e.g. AAAA)
TFTP
/tftp/00:11:22:33:44:55 POST creates pxelinux configuration file for host with MAC address 00:11:22:33:44:55 {"syslinux_config":string}. Implicit variant of "syslinux"
/tftp/<variant>/00:11:22:33:44:55 POST creates pxeconfig configuration file for host with MAC address 00:11:22:33:44:55 {"pxeconfig":string}. Variant can be "syslinux" or "pxegrub"
/tftp/00:11:22:33:44:55 DELETE remove pxelinux configuration file for host with MAC address 00:11:22:33:44:55 Implicit variant of "syslinux"
/tftp/<variant>/00:11:22:33:44:55 DELETE remove pxeconfig configuration file for host with MAC address 00:11:22:33:44:55 Variant can be "syslinux" or "pxegrub"
/tftp/create_default POST creates a default pxelinux configuration file {"syslinux_config":string}. Implicit variant of "syslinux"
/tftp/<variant>/create_default POST creates a default pxeconfig configuration file {"pxeconfig":string}. Variant can be "syslinux" or "pxegrub"
/tftp/fetch_boot_file POST creates a default pxelinux configuration file {"prefix":string, "path":string}
/tftp/serverName GET fetches the TFTP server name to be used within a dhcp record
PUPPET CA
/puppet/ca GET list of all puppet certificates
/puppet/ca/certname POST Sign pending certificate request
/puppet/ca/certname DELETE Remove (clean) and revoke a certificate
/puppet/ca/autosign GET list of all puppet autosign entires
/puppet/ca/autosign/certname POST Add certname to Puppet autosign
/puppet/ca/autosign/certname DELETE Remove certname from Puppet autosign
PUPPET
/puppet/run POST Trigger puppet run / kick ["hostA", "hostB"]
/puppet/environments GET list of all puppet environment names
/puppet/environments/production> GET show puppet production environment name and module paths
/puppet/environments/production/classes GET return a hash of puppet classes in the production environment Puppet class parameters is supported from 1.1
BMC
/bmc/providers GET Get a list of supported BMC providers
/bmc/providers/installed GET Get a list of installed BMC providers
/bmc/:host GET returns host operations
/bmc/:host/chassis GET returns chassis operations
/bmc/:host/chassis/power/:action GET Gets the power status, does not change power, leave action blank for list of available actions
/bmc/:host/lan/:action GET Get bmc lan details, leave action blank for list of available actions
/bmc/:host/chassis/identify/:action GET gets chassis identify status, leave action blank for list of available actions
/bmc/:host/chassis/config/:function GET Get chassis config details, supports bootdevices, leave function blank for list of available functions
/bmc/:host/chassis/power/:action PUT Control the power of the bmc device, leave action blank for list of available functions valid actions: on, off, cycle, soft
/bmc/:host/chassis/config/:function/:action PUT Set config of bios, currently supports bootdevice valid actions: pxe, cdrom, bios, disk valid options: reboot, persistent
/bmc/:host/chassis/identify/:action PUT controls the chassis identify light, leave action blank for available actions actions: on, off
REALM
/realm/:realm POST Creates/Updates new realm entry. "Userclass" is an arbitrary data field. Used by FreeIPA provider for automembership, and foreman passes the host group title. hostname=host.example.com&userclass=webservers
/realm/:realm POST Recreate realm entry (revokes keytab, etc) hostname=host.example.com&userclass=webservers&rebuild=true
/realm/:realm/:hostname DELETE Deletes new realm entry
LOGS
/logs/ GET Returns proxy log buffer (last N log records) {"info": {}, "logs": [{ "timestamp": 1455783010.8100047, "level": "ERROR", "message": "...", "backtrace": "..." }]}

Please raise a new issue if you need additional API's

Manually Calling the API

The API can be manually tested out using curl. GET types can be retrieved like any other URL. This one, for example, will return the HTML formatted page with the list of features enabled on the proxy.

curl http://localhost:8443/features

The results can also be returned as JSON if you set an appropriate Accept header.

curl -H "Accept: application/json" http://localhost:8443/features

POST URLs, used to create objects or trigger actions, need to have the parameters passed in via the -d argument. This curl command line will trigger a puppetrun on server.example.com.

curl -d 'nodes=server.example.com' http://localhost:8443/puppet/run

This curl command line will add an A record for server.example.com with ip address of 10.1.2.5.

curl -d 'fqdn=servers.example.com&value=10.1.2.5&type=A' http://localhost:8443/dns/

This curl command line will remove the A record added above.

curl -XDELETE http://localhost:8443/dns/servers.example.com

Multiple post options may be specified by repeating the -d argument.

curl -d 'prefix=boot/CentOS-5-x86_64' -d 'path=http://yourlocalmirrorhere/pub/centos/5/os/x86_64/images/pxeboot/vmlinuz'  http://localhost:8443/tftp/fetch_boot_file

When you are creating an object, the identifier for the object is typically passed in as part of the URL, rather than as a POST value. For example, this will create a PXE boot configuration file for a host with MAC address 00:11:22:33:44:55, and will just put "Hello World" as the contents of the file. (A real world example would, of course, substitute a valid PXE boot configuration in the string.)

curl -d 'syslinux_config=Hello World' http://localhost:8443/tftp/00:11:22:33:44:55

In order to delete objects, you use the same URL as in the original creation, but pass it not POST values, and use the DELETE HTTP method instead of POST. This will delete the PXE boot configuration file created above.

curl -X DELETE http://localhost:8443/tftp/00:11:22:33:44:55

BMC Controls

Summary
The smart-proxy can now control BMC devices through the use of the IPMI protocol. The smart proxy utilizes ipmitool and freeipmi to control your BMC devices through the network.

Prerequisites

In order to control the BMC device using the smart proxy you must perform the following actions:

1. Enable bmc support in the settings.yml file
2. Install rubyipmi gem,
3. Install freeipmi, and/or ipmitool either from source or package
4. The bmc device must be setup on the network with login credentials
5. Smart proxy must be able to reach the bmc device through the network

Using Parameters with the BMC API

1. When using the bmc api, you must send the credentials of the bmc device using Http Basic Authorization
2. If you wish to override the default bmc provider for a particular BMC device please specify in the http parameter (bmc_provider) Valid options are ipmitool and freeipmi
3. Some api calls have optional parameters, leaving the action blank on some api calls will return valid actions and options.

BMC Security

Its important to note that at this time the bmc api does not encrypt your credentials. Your credentials are sent in the clear to the smart proxy and then used on the command line to execute the local command.
In order to achieve some level of security it is important that your smart proxy use https. Using https will ensure that your credentials are sent via the encrypted https channel. Additionally, by default the bmc api
will never expose your credentials to prying eyes via logs or process checks. The local bmc commands will be run with the credentials placed in a random file which is deleted upon every call and cannot be opened
by any other user.

Examples

returns boolean if the power is off (Note this only occurs when using GET

curl -vks --data 'bmc_provider=freeipmi' 'http://127.0.0.1:8443/bmc/192.168.1.16/chassis/power/off' -X GET -u admin:password  => {"action":"off","result":true}

returns status when the power is turned off (Note this only occurs when using PUT)

curl -vks --cacert /var/lib/puppet/ssl/certs/ca.pem --cert /var/lib/puppet/ssl/certs/`hostname -f`.pem --key /var/lib/puppet/ssl/private_keys/`hostname -f`.pem \
     --data 'bmc_provider=freeipmi' 'https://127.0.0.1:8443/bmc/192.168.1.16/chassis/power/off' -X PUT -u admin:password  => {"action":"off","result":"192.168.1.16: ok\n"}

if you can't remember the basic bmc api actions you just leave things blank and the proxy will try to help you out.

curl -vks --data 'bmc_provider=freeipmi' 'http://127.0.0.1:8443/bmc/192.168.1.16/chassis' -X GET -u admin:password => {"actions":["power","identify","config"]}

Troubleshooting

In these examples you will notice that I have turned off SSL which you should never do in a production environment, but this is a short lived development machine.
If you have some weird BMC issue you can have a look at the log if your using the latest smart proxy >= 1.9. Starting with Rubyipmi 0.9.0 it will now generate a log with all the commands and responses it runs.

curl -vks --data 'bmc_provider=freeipmi' 'http://127.0.0.1:8443/bmc/192.168.1.16/chassis/power/off' -X GET -u admin:password  => {"action":"off","result":true}
D, [2015-03-10T16:12:57.328430 #68510] DEBUG -- : /usr/local/sbin/ipmipower --hostname=192.168.1.16   --stat --config-file=/var/folders/h6/v6nv76td37s7vqj902_z59kh0000gn/T/20150310-68510-w3rw89
D, [2015-03-10T16:12:57.694174 #68510] DEBUG -- : "/usr/local/sbin/ipmipower --hostname=192.168.1.16   --stat --config-file=/var/folders/h6/v6nv76td37s7vqj902_z59kh0000gn/T/20150310-68510-w3rw89 --driver-type=LAN_2_0" 
D, [2015-03-10T16:12:57.694256 #68510] DEBUG -- : 192.168.1.16: off

If you just want to test your connection to see if your BMC device works with the provided information you can now use one of the new API commands named "test". What this is doing in the background is running a bmc info command and if that
command fails it returns false. You can view the logs to see why it failed. In a later release we will detail what caused the test to fail.

# good password
curl -vks --data 'bmc_provider=freeipmi' 'http://127.0.0.1:8443/bmc/192.168.1.16/test' -X GET -u admin:password
{"action":"test","result":true}
#  bad password
curl -vks --data 'bmc_provider=freeipmi' 'http://127.0.0.1:8443/bmc/192.168.1.16/test' -X GET -u admin:bad_password
{"action":"test","result":false}
D, [2015-03-20T10:04:25.288696 #92467] DEBUG -- : /usr/local/sbin/bmc-info --hostname=192.168.1.16   --config-file=/var/folders/h6/v6nv76td37s7vqj902_z59kh0000gn/T/20150320-92467-1og0ucl
D, [2015-03-20T10:04:25.335628 #92467] DEBUG -- : "/usr/local/sbin/bmc-info --hostname=192.168.1.16   --config-file=/var/folders/h6/v6nv76td37s7vqj902_z59kh0000gn/T/20150320-92467-1og0ucl --driver-type=LAN_2_0" 
D, [2015-03-20T10:04:25.335706 #92467] DEBUG -- : /usr/local/sbin/bmc-info: password invalid

How to provide additional options in the body

curl -vks --header "Content-Type: application/json" -d '{"bmc_provider":"freeipmi", "options":{"driver":"lan20", "privilege":"USER"}}' 'http://127.0.0.1:8443/bmc/192.168.1.21/chassis/power/off' -X GET -u admin:password

Draft 2.0 version of DNS API

Realm API

Draft design: http://projects.theforeman.org/projects/foreman/wiki/RealmJoinIntegration

New Host

The FreeIPA returns the raw XMLRPC JSON when creating a host, however the only relevant key is "randompassword." Any other Realm providers at a minimum should return an OTP for a new host.

Example full output from FreeIPA:

{
  "dn": "fqdn=hostname.example.com,cn=computers,cn=accounts,dc=example,dc=com", 
  "fqdn": [
    "hostname.example.com" 
  ], 
  "has_keytab": false, 
  "has_password": true, 
  "ipauniqueid": [
    "5f5d467c-9fce-11e3-bcca-525400d17cb3" 
  ], 
  "managedby_host": [
    "hostname.example.com" 
  ], 
  "objectclass": [
    "ipaSshGroupOfPubKeys", 
    "ipaobject", 
    "ieee802device", 
    "nshost", 
    "top", 
    "ipaservice", 
    "pkiuser", 
    "ipahost", 
    "ipasshhost" 
  ], 
  "randompassword": "_i7@PhgpAnjn" 
}

Update Host

  • "rebuild=true" is passed for any host being rebuilt in order to know whether to revoke any outstanding certificates, etc. A new randompassword should be issued.
  • Foreman also triggers an update if the "userclass" is being updated. You should not return a new one-time password for this, only update the attribute (if desired) and return 200. If nothing needs to be updated, you should return resposen 200 and this JSON
{"message" => "nothing to do"}

Delete a host

The Smart Proxy will return 404 if not found, 400 for any other error.