Bug 1684359 - Cannot launch provision request from API from global region using LDAP user who never logged into the sub region
Summary: Cannot launch provision request from API from global region using LDAP user w...
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Red Hat CloudForms Management Engine
Classification: Red Hat
Component: API
Version: 5.10.0
Hardware: Unspecified
OS: Unspecified
medium
high
Target Milestone: GA
: 5.10.3
Assignee: Joe Vlcek
QA Contact: Parthvi Vala
Red Hat CloudForms Documentation
URL:
Whiteboard:
Depends On:
Blocks: 1692488
TreeView+ depends on / blocked
 
Reported: 2019-03-01 04:52 UTC by Nikhil Gupta
Modified: 2020-08-10 10:27 UTC (History)
6 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2019-03-25 17:39:40 UTC
Category: Bug
Cloudforms Team: CFME Core
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)

Description Nikhil Gupta 2019-03-01 04:52:00 UTC
Description of problem:

We are trying to launch a provisioning request using the API from the master region to a subregion. We are using the API request documented here:
http://manageiq.org/docs/reference/fine/api/reference/provision_requests

We have created a service catalog in the master region that parses details from the dialog performs the API call to the subregion to provision the VM. One of the fields in the POST request is the owner. We set that as the current logged in user who initiated the request.

Both master and subregion are integrated with the same active directory. 

If we use the default admin account that ships with CFME it works fine and the VM is provisioned. 

However, if we use a user from the AD who never logged into the sub region, and logged into the Master appliance and order the same catalog. The provision request fails. The API returns a 404.

If the AD user logs in the subregion, and then the process is repeated by ordering from the master it works fine.

After debugging I found out that it is trying to lookup the user and it doesn't find him so it throws a 404. If I log in at least once on the subregion with the AD user and then repeat it works.

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

How reproducible:
Always

Steps to Reproduce:
1- Setup appliance as sub region as remote.
2- Setup appliance as master region as global.
3- Add provider to subregion.
4- Integrate both master and subregion with LDAP (same source)
5- Create a service catalog in sub region
6- Log into the master appliance using a LDAP user who has never logged into to sub region.
7- Make a create_provision_request using the API http://manageiq.org/docs/reference/fine/api/examples/provision_request
8- In the POST body params set the requester info to an LDAP user that has never logged into CFME ex:
      "requester" : {
        "user_name" : "ldapuser1",
        "owner_first_name" : "Sam",
        "owner_last_name" : "ple",
        "owner_email" : "sample",
        "auto_approve" : true
      }
9- Service provisioning will fail (404 errors from subregion API in logs)
10- Login using the same LDAP user but on the subregion
11- Request catalog from master again.
12- Service provisioning is successful.

Actual results:
API Provisioning request fails with 404 Not Found error
~~~
/opt/rh/cfme-gemset/gems/rest-client-2.0.2/lib/restclient/abstract_response.rb:223:in `exception_with_response': 404 Not Found (RestClient::NotFound)
	from /opt/rh/cfme-gemset/gems/rest-client-2.0.2/lib/restclient/abstract_response.rb:103:in `return!'
	from /opt/rh/cfme-gemset/gems/rest-client-2.0.2/lib/restclient/request.rb:809:in `process_result'
	from /opt/rh/cfme-gemset/gems/rest-client-2.0.2/lib/restclient/request.rb:725:in `block in transmit'
	from /opt/rh/rh-ruby23/root/usr/share/ruby/net/http.rb:853:in `start'
	from /opt/rh/cfme-gemset/gems/rest-client-2.0.2/lib/restclient/request.rb:715:in `transmit'
	from /opt/rh/cfme-gemset/gems/rest-client-2.0.2/lib/restclient/request.rb:145:in `execute'
	from /opt/rh/cfme-gemset/gems/rest-client-2.0.2/lib/restclient/request.rb:52:in `execute'
	from rest_check.rb:20:in `create_provision_request_api'
	from rest_check.rb:73:in `<main>'
~~~

Expected results:
API Provisioning should be successful.

Additional info:

The source of the API call is not relevant in this issue. I can make the API call from a master appliance, ansible tower or even a plain ruby script or even cURL.

The issue I am facing is the CFME API itself. This is even reproducible on a single appliance setup:

1- Setup SINGLE CFME appliance
2- Add Provider (vcenter)
3- Add LDAP authentication
4-  Make a create_provision_request using the API http://manageiq.org/docs/reference/fine/api/examples/provision_request
5- In the POST body params set the requester info to an LDAP user that has never logged into CFME ex:
      "requester" : {
        "user_name" : "ldapuser1",
        "owner_first_name" : "John",
        "owner_last_name" : "Doe",
        "owner_email" : "jdoe",
        "auto_approve" : true
      }
6- API response will be 404. Internally the API tries to lookup user and fails even though the user exists in the LDAP.
7- Now log in CFME using ldapuser1
8- Repeat API call
9- API response is 200, provision request is created and vm provision is initiated.

Comment 4 Joe Vlcek 2019-03-04 17:21:45 UTC
Nikhil,

Please provide the following information to help me diagnose this issue.

    - When the user is created in the sub-regions are they auto-created
      by logging into the UI as the new user or are they manually created
      by logging in as admin and manually created them with the CFME UI?

    - Has Red Hat support been able to recreate this failure inside the Red Hat 
      network? If so please post a private message to this BZ with the
      credentials to the CFME systems.
 
    - On the global and sub-regions please provide the information described in the
      "Troubleshooting ManageIQ Authentication" blog post [1]
      Specifically the data described in the Appendix titled:

      * "Capturing ManageIQ Log Files" [2]
        Please capture the logs immediately following the recreation of the  failure,
        so the logs will include the failures.

      * "Capturing Authentication Data From ManageIQ DB" [3]
        Please provide the output from each of the rails runner commands
        from both the global and remote region when the failure is observed.

    [1] http://manageiq.org/blog/2018/01/troubleshooting-auth/
    [2] http://manageiq.org/blog/2018/01/troubleshooting-auth/#capturing-manageiq-log-files
    [3] http://manageiq.org/blog/2018/01/troubleshooting-auth/#capturing-authentication-data-from-manageiq-db

Thank you! JoeV

Comment 7 Joe Vlcek 2019-03-08 16:50:09 UTC
Neha,

I believe I have found the source of this failure.

The bug description states:

> 7- Make a create_provision_request using the API http://manageiq.org/docs/reference/fine/api/examples/provision_request

I think the issue is rooted in this script.

Can you please attach in a private message to this BZ with the version of this script being used in the Global/Sub-region
setup?

The version of this script available on the stand alone test system get's a token for the admin user then
issues the provision request with the payload post_params that contain the "joev" user.

In order for this to work the "joev" users credentials also need to be used on the initial request to get the token.

To reproduce the "correct" behavior I logged into the stand alone system and updated the rest_check.rb script to use
the joev user's credentials instead of the admin user's when getting the token:

e.g.:
Change from:
  8 def create_provision_request_api(ip, post_params)
  9   api_uri = "https://#{ip}/api"
 10   url = URI.encode(api_uri + '/auth')
 11   rest_return = RestClient::Request.execute(
 12     :method => "get",
 13     :url => url,
 14     :user => "admin",
 15     :password => "smartvm",
 16     :headers => {:accept => :json},
 17     :verify_ssl => false
 18   )
 19   auth_token = JSON.parse(rest_return)['auth_token']


Change to:
  8 def create_provision_request_api(ip, post_params)
  9   api_uri = "https://#{ip}/api"
 10   url = URI.encode(api_uri + '/auth')
 11   rest_return = RestClient::Request.execute(
 12     :method => "get",
 13     :url => url,
 14     :user => "joev",
 15     :password => < joev's password> ,
 16     :headers => {:accept => :json},
 17     :verify_ssl => false
 18   )
 19   auth_token = JSON.parse(rest_return)['auth_token']


Leave everything else as it is and this will work. If the joev user does not yet exists
it will be created.

It is still not clear to me exactly what tooling is being used to perform the provision_request
in the non-stand-alone setup but I suspect all that needs to be done in this case also will be
to ensure the token being used is for the current user (User.current_userid) and not admin.


Please let me know if this works for you and if not please provide more information regarding
the tooling being used to perform the provision_request in the non-stand-alone setup. You can
simply past the script in a private message to this BZ if need be.

Hope this resolves the issue.
Thank you, JoeV

Comment 8 Joe Vlcek 2019-03-25 17:39:40 UTC
Since the associated customer case has been CLOSED  I am going to close this BZ.

It seems the problem was simply one of incorrect usage. The information I provided in comment
#7 describes the correct usage.

If it is felt this BZ should be reopened please provide justification.

Thank you, JoeV


Note You need to log in before you can comment on or make changes to this bug.