Bug 1593576

Summary: calling PUT /api/v2/discovered_hosts/id with build=0 doesn't work
Product: Red Hat Satellite Reporter: matt jia <mjia>
Component: Discovery PluginAssignee: Lukas Zapletal <lzap>
Status: CLOSED ERRATA QA Contact: Radovan Drazny <rdrazny>
Severity: medium Docs Contact:
Priority: unspecified    
Version: 6.3.1CC: adprice, akarsale, apatel, jhutar, lzap, mhulan, pcreech, rabajaj, rdrazny, tstrachota
Target Milestone: 6.4.0Keywords: Regression, Reopened, Triaged
Target Release: Unused   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: tfm-rubygem-foreman_discovery-12.0.1-1.el7sat Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2018-10-16 18:59:49 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description matt jia 2018-06-21 06:46:43 UTC
Description of problem:

There is a regression introduced in foremand_discovery by this commit 044cd42ffcb96819af0bd3d88bb348f2f9dc8ea9.

Sending a put request to /api/v2/discovered_hosts/id with build=0 used to work in 6.2 but now host.build is always set 1 by this API in Satellite 6.3.


Version-Release number of selected component (if applicable):

6.3.1

How reproducible:

Easy


Steps to Reproduce:

Sending a put request to /api/v2/discovered_hosts/id with the data like this 

 {
       "discovered_host": {
       "name": "$hostname",
       "mac": "$mac",
       "ip": "$ip",
       "hostgroup_name": "$hostgroup_name",
       "root_pass": "$root_pass",
       "build": 0,
 }


Actual results:

The discovered host went directly into provisioning and host.build = 1


Expected results:

The discovered host shouldn't go directly into provisioning and host.build = 0

Additional info:

Comparing this two lines in foreman_discovery/app/controllers/api/v2/discovered_hosts_controller.rb 

6.2:

@host = ::ForemanDiscovery::HostConverter.to_managed(@discovered_host)

6.3:

@host = ::ForemanDiscovery::HostConverter.to_managed(@discovered_host, true, true, managed_host_params)

Then take a look foreman_discovery/app/services/foreman_discovery/host_converter.rb +37 in 6.3

host.build = true

This just ignores the build parameter from the API request which is not right.

Comment 4 Lukas Zapletal 2018-06-25 09:57:35 UTC
ACK fix is upstream, one line fix:

https://github.com/theforeman/foreman_discovery/pull/441/files#diff-bca1f0e74fb3aabf3197a48e1c279c09R83

Comment 5 RHEL Program Management 2018-06-25 10:02:48 UTC
Development Management has reviewed and declined this request.
You may appeal this decision by reopening this request.

Comment 6 matt jia 2018-06-26 04:28:15 UTC
Hmm, not quite sure why this bug is closed as "WONTFIX". Even though this has already been fixed in the upstream, I think this should be closed when the fix is released in the next release cycle.

Comment 7 Lukas Zapletal 2018-06-26 08:22:44 UTC
Let me explain, it was a mis-click :-)

The patch was already merged upstream and released in 12.0.1 release (not announced yet tho).

Comment 8 Lukas Zapletal 2018-06-26 08:26:48 UTC
Here is the fixed RPM package for you to try it:

http://koji.katello.org/koji/taskinfo?taskID=106909

Comment 9 matt jia 2018-07-08 23:35:56 UTC
Thanks, Lukas. I've instructed cus with a hotfix based on that one line change and it works like a charm.

Comment 11 Radovan Drazny 2018-09-05 09:58:04 UTC
Tested on Sat 6.4 Snap 20.

It seems that calling the "/api/v2/discovered_hosts/$id" endpoint still sets build mode to True. 

The hostgroup config:

# hammer hostgroup info --id 1
Id:                    1
Name:                  TestHostGroup
Title:                 TestHostGroup
Puppet Environment:    TestPuppetEnv
Description:           
  
Puppet CA Proxy:       satellite.example.com
Puppet Master Proxy:   satellite.example.com
Network:               
    Domain: example.com
Operating system:      
    Architecture:     x86_64
    Operating System: RHEL Server 7.5
    Partition Table:  Kickstart default
    PXE Loader:       PXELinux UEFI
Puppetclasses:         

Parameters:            

Locations:             
    Default Location
Organizations:         
    Default Organization
OpenSCAP Proxy:        
Content View:          
    ID:   1
    Name: Default Organization View
Lifecycle Environment: 
    ID:   1
    Name: Library
Content Source:        
    ID:   1
    Name: satellite.example.com
Kickstart Repository:  
    ID:   9
    Name: Red Hat Enterprise Linux 7 Server Kickstart x86_64 7.5


I have discovered a virtual host using the FDI. The host was discovered with the ID 15.

Triggering provisioning using the API call. Notice the explicit '"build": "false"'

$ curl -X PUT -H 'Accept: application/json,version=2' -H 'Content-Type: application/json' -u admin:changeme -L -k -i 'https://satellite.example.com/api/v2/discovered_hosts/15' --data '{ 
"discovered_host": {
       "name": "client15",
       "hostgroup_id": 1,
       "build": "false"
        }
}'
HTTP/1.1 200 OK
Date: Wed, 05 Sep 2018 09:41:37 GMT
Server: Apache/2.4.6 (Red Hat Enterprise Linux)
Foreman_version: 1.18.0.18
Foreman_api_version: 2
Apipie-Checksum: bf5a9e3ec38f2bd61f26b75f6d1c39eecc6d9f43
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 3d4c50ea-6019-4f98-b012-fb0923a40b48
X-Runtime: 0.574297
Content-Security-Policy: default-src 'self'; child-src 'self'; connect-src 'self' ws: wss:; img-src 'self' data: *.gravatar.com; script-src 'unsafe-eval' 'unsafe-inline' 'self'; style-src 'unsafe-inline' 'self'
Strict-Transport-Security: max-age=631139040; includeSubdomains
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: sameorigin
X-Permitted-Cross-Domain-Policies: none
X-XSS-Protection: 1; mode=block
X-Powered-By: Phusion Passenger 4.0.18
Set-Cookie: request_method=PUT; path=/; secure; HttpOnly; SameSite=Lax
Set-Cookie: _session_id=d1a9f92eafa3b6511bdc71ffb21c41b4; path=/; secure; HttpOnly; SameSite=Lax
ETag: W/"6a992e9888d4d62eebf06dfe2b5ded15"
Status: 200 OK
Content-Length: 39
Content-Type: application/json; charset=utf-8


Check the host status: 

$ hammer host info --id 15 | grep Build
    Build:                  yes

At this point I have deleted the host, and rediscovered it again, this time with ID 16, and performed the provisioning using the hammer. Again, notice the explicit "--build false":

$ hammer discovery provision --id 16 --build false --hostgroup-id 1 --name client16
Host created
$ hammer host info --id 16 | grep Build
    Build:                  no

Using the API to provision a discovered host with the explict build false still switches the build mode on. Using hammer correctly sets the build mode to off.

Comment 12 Lukas Zapletal 2018-09-07 11:00:36 UTC
Hey,

try to send it as a boolean:

{
	"discovered_host": {
		"name": "client15",
		"hostgroup_id": 1,
		"build": false
	}
}

Comment 13 Radovan Drazny 2018-09-10 08:23:31 UTC
Ok, enclosing the boolean in quotes was a mistake. With false this works as expected.


$ curl -X PUT -k -H 'Accept: application/json,version=2' -H 'Content-Type: application/json' -H 'Authorization: Basic YWRtaW46Y2hhbmdlbWU=' -i 'https://satellite.example.com/api/v2/discovered_hosts/25' --data '{
> "discovered_host": {
>        "name": "client25",
>        "hostgroup_id": 1,
>        "build": false
>         }
> }'
HTTP/1.1 200 OK
Date: Mon, 10 Sep 2018 07:52:13 GMT
Server: Apache/2.4.6 (Red Hat Enterprise Linux)
Foreman_version: 1.18.0.18
Foreman_api_version: 2
Apipie-Checksum: bf5a9e3ec38f2bd61f26b75f6d1c39eecc6d9f43
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: e7d16c81-7fbe-46a0-9df0-88cb4e1ed68e
X-Runtime: 0.559308
Content-Security-Policy: default-src 'self'; child-src 'self'; connect-src 'self' ws: wss:; img-src 'self' data: *.gravatar.com; script-src 'unsafe-eval' 'unsafe-inline' 'self'; style-src 'unsafe-inline' 'self'
Strict-Transport-Security: max-age=631139040; includeSubdomains
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: sameorigin
X-Permitted-Cross-Domain-Policies: none
X-XSS-Protection: 1; mode=block
X-Powered-By: Phusion Passenger 4.0.18
Set-Cookie: request_method=PUT; path=/; secure; HttpOnly; SameSite=Lax
Set-Cookie: _session_id=0af72ba62c83a1b521f339d6ad4c0008; path=/; secure; HttpOnly; SameSite=Lax
ETag: W/"f135046460569cc5148ae5bc67909906"
Status: 200 OK
Content-Length: 39
Content-Type: application/json; charset=utf-8

{"name":"client25.example.com","id":25}

$ hammer host info --id 25 | grep Build
    Build:                  no


Nevertheless, there is still a problem when using 0 instead of boolean, which should be supported according to API docs:

discovered_host[build]
optional , nil allowed 	

Validations:

Must be one of: true, false, 1, 0


$ curl -X PUT -k -H 'Accept: application/json,version=2' -H 'Content-Type: application/json' -H 'Authorization: Basic YWRtaW46Y2hhbmdlbWU=' -i 'https://satellite.example.com/api/v2/discovered_hosts/27' --data '{
> "discovered_host": {
>        "name": "client27",
>        "hostgroup_id": 1,
>        "build": 0
>         }
> }'

HTTP/1.1 200 OK
Date: Mon, 10 Sep 2018 08:01:58 GMT
Server: Apache/2.4.6 (Red Hat Enterprise Linux)
Foreman_version: 1.18.0.18
Foreman_api_version: 2
Apipie-Checksum: bf5a9e3ec38f2bd61f26b75f6d1c39eecc6d9f43
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 1a1807c9-6079-41ef-9c10-46d4cd1fdc93
X-Runtime: 0.309610
Content-Security-Policy: default-src 'self'; child-src 'self'; connect-src 'self' ws: wss:; img-src 'self' data: *.gravatar.com; script-src 'unsafe-eval' 'unsafe-inline' 'self'; style-src 'unsafe-inline' 'self'
Strict-Transport-Security: max-age=631139040; includeSubdomains
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: sameorigin
X-Permitted-Cross-Domain-Policies: none
X-XSS-Protection: 1; mode=block
X-Powered-By: Phusion Passenger 4.0.18
Set-Cookie: request_method=PUT; path=/; secure; HttpOnly; SameSite=Lax
Set-Cookie: _session_id=5413ae127d7ab0f52b9a2a7335225028; path=/; secure; HttpOnly; SameSite=Lax
ETag: W/"a2e350861bc48aeb562205cb965e9615"
Status: 200 OK
Content-Length: 39
Content-Type: application/json; charset=utf-8

{"name":"client27.example.com","id":27}

$ hammer host info --id 27 | grep Build
    Build:                  yes

Comment 14 Lukas Zapletal 2018-09-10 09:22:54 UTC
I do believe this bug is VERIFIED and we need to discuss how we document boolean flags in our API. Integers must not be documented as supported, while they *can* work, they will definitely work at all places.

https://community.theforeman.org/t/boolean-normalization-in-the-api/11034

Let's revisit this bug next ween after the discussion is closed.

Comment 16 Bryan Kearney 2018-10-16 18:59:49 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHSA-2018:2927