Creating new hosts using curl via api

Latest response

Been trying to create a new host in Satellite 6 via curl command, just testing this out to verify it works and be able to help our developers who will be calling the API from remote Enterprise systems to create hosts in a automated fashion.

Not many examples can be found, and I get it. The payload produced will vary greatly based on the data you have placed in your satellite server (organizations/environments/hostgroups/locations/,,,, )
I put the below together, but when i attempt to post the payload via curl, I receive a rather perplexing error message.

I know that hammer is a great tool, I used it to help me put together the payload file below. But really need to better understand the payload requirements/format, so I can better explain them to my developers.

Can anyone point me in the right direction?
Or is this simply a Satellite Bug, that I should open a case for?

# cat payload.json
{"host":
  {"name":"myhost.mydomain.com",
   "location_id":2,
   "organization_id":1,
   "environment_id":1,
   "architecture_id":1,
   "operatingsystem_id":7,
   "medium_id":15,
   "ptable_id":127,
   "hostgroup_id":13,
   "build":true,
   "enabled":true,
   "provision_method":"build",
   "managed":true,
   "compute_attributes":{
      "volumes_attributes":{}
   },
   "content_facet_attributes":{},
   "subscription_facet_attributes":{},
   "overwrite":true,
   "host_parameters_attributes":{},
   "interfaces_attributes":[
     [0],{
        "primary":"true",
        "provision":"true",
        "mac":"00:17:ab:cd:12:34",
        "ip":"192.168.200.20"}],
   "root_pass":"RaNdOm_ChArAcTeRs"}}
# json_verify < ./payload.json
JSON is valid
# curl -s -k -u USER:PASS -d @payload.json -H "Content-Content-Type: application/json" -X POST https://sat6.mydomain.com/api/v2/hosts
{
  "error": {"message":"no implicit conversion of Symbol into Integer"}
}

Responses

@carl, I'm using the REST API to successfully pre-create hosts for an automation solution. My guess to your problem is that, while the JSON is technically valid, the data does not match what the API is expecting to see. I'm all but certain that the culprit is your index into the 'interfaces_attributes'. My suggestion would be to not use the 'interfaces_attributes'. I have found that if you specify ip/mac directly under the host itself it will be assumed to be the primary and provision interface.
I haven't had to provision a system with multiple NICs but I would probably still just configure the single provisioning interface and then use the Kickstart script to configure the others on the system. I think that those extra interfaces would essentially be detected after provisioning and show up in Satellite automatically. I say that to say that you should only need to specify one IP/MAC which will become the primary interface for the system. Also, here are a couple other notes that I would pass along (unless you have specific reasons for being as verbose as you are):

  1. When you create a host through the API it is assumed to be 'managed' so you don't need to pass this parameter.

  2. Many of your parameters can be inherited if you just configure a specific hostgroup with all of the particular parameters and then just tell the host which hostgroup it is a part of at create time. If you do this you can drop root_pass, environment_id, architecture_id, operatingsystem_id, medium_id and ptable_id.

  3. The minimal configuration I have found so far (if you use a hostgroup) is:

      {"host":
        {
        "name": "<name>",
        "build": "true",
        "managed": "true",
        "organization_name": "<org_name>",
        "location_name": "<loc_name>",
        "hostgroup_id": "<hostgroup_id>",
        "ip": "<ip_addr>",
        "mac": "<mac_addr>"
        }
      }  
    

    NOTE: While many values can be used by name (e.g. organization_name) 'hostgroup' should use 'hostgroup_id' because it is possible for two or more hostgroups to have the same 'name' if you use nested hostgroups.

  4. If you intend to do PXE booting you will also need to pass the 'subnet_name' or 'subnet_id' because this is where the TFTP capsule information is stored.

Not been able to debug this too much, but I found that with Satellite 6.3 the above example is not enough to create a host.

This was the json I got working over curl and postman.

{ "host": { "name": "centos7-001.home", "organization_id": "1", "location_id": "2", "hostgroup_id": "1", "compute_resource_id": "", "content_facet_attributes": { "lifecycle_environment_id": "1", "content_view_id": "1", "content_source_id": "1", "kickstart_repository_id": "3" }, "managed": "true", "type": "Host::Managed", "interfaces_attributes": { "0": { "_destroy": "0", "type": "Nic::Managed", "mac": "00:0C:29:D7:1E:CB", "identifier": "", "name": "centos7-001.home", "domain_id": "1", "subnet_id": "1", "ip": "", "ip6": "", "managed": "1", "primary": "1", "provision": "1", "execution": "1", "virtual": "0", "tag": "", "attached_to": "" } }, "architecture_id": "1", "operatingsystem_id": "2", "provision_method": "build", "build": "1", "ptable_id": "90", "pxe_loader": "PXELinux BIOS", "disk": "", "is_owned_by": "3-Users", "enabled": "1", "model_id": "", "comment": "", "overwrite": "false" }, "media_selector": "synced_content", "bare_metal_capabilities": "build" }

Is there a way to re-provision an existing host, either via hammer or api? I guess if I had to I could delete it an re-create it via hammer. I'm just looking for a simple script to place a host into the build state so that when it's rebooted it's automatically re-imaged.