Okay, so the other day I had someone reach out to me for a vCenter rest API issue, Apparently, REST API to any vCenter component using the API explorer or the CLI would return the error

com.vmware.vapi.rest.httpNotFound

Cli: Generate session: (on bash shell): (or simply go grab the complete command from the API explorer)

**edit the below**
 VC_ADDRESS=vcenter.domain.local
 VC_USER=administrator@vsphere.local
 VC_PASSWORD=password

**do not change the below***
curl -u "$VC_USER:$VC_PASSWORD" \
    -X POST \
    -k --cookie-jar cookies.txt \
    "https://$VC_ADDRESS/rest/com/vmware/cis/session"

**the cookies file should now have a sessionID, use this session in the upcomeing commands*** 

test VAPI using bash

root@nvcsa-01 [ /tmp ]# curl -X GET --header 'Accept: application/json' --header 'vmware-api-session-id: 71b32ba6c59bc4bc284757b2a0d6e525' 'https://vcsa/rest/vcenter/cluster'
{"name":"com.vmware.vapi.rest.httpNotFound","localizableMessages":[{"defaultMessage":"Not found.","id":"com.vmware.vapi.rest.httpNotFound"}],"majorErrorCode":404}r

at this time clearly, something is wrong. Looking at the URL: https://vcsa_URL/rest/vcenter

Looking at the rhttp configuration:

root@VCSA [ /etc/vmware-rhttpproxy/endpoints.conf.d ]# grep rest *.conf
vapi-endpoint.conf:/rest local 12346 redirect allow
vapi-endpoint.conf:/site/rest local 12346 redirect allow

Looking at the process:

root@vcsa [ /etc/vmware-rhttpproxy/endpoints.conf.d ]# netstat -anop | grep -i listen | grep 12346
tcp6       0      0 ::1:12346               :::*                    LISTEN      11956/vmware-vapi-e off (0.00/0/0)
tcp6       0      0 127.0.0.1:12346         :::*                    LISTEN      11956/vmware-vapi-e off (0.00/0/0)

So it is clear that the service responsible for REST is vapi and the service is running.
looking at the logs did not reveal anything out of the ordinary. in fact it reported nothing. aside from the below

2019-11-27T02:45:19.623+08:00 | INFO  | state-manager1            | DefaultStateManager            | Invoking http-server
2019-11-27T02:45:19.624+08:00 | INFO  | state-manager1            | BaseServerBuilder              | Creating endpoint with name 'default' on address(es): 127.0.0.1, ::1 with port: 12346
2019-11-27T02:45:19.682+08:00 | WARN  | state-manager1            | BaseServerBuilder              | Failed to bind /0:0:0:0:0:0:0:1:12346 while testing the endpoint validity
java.net.SocketException: Protocol family unavailable
        at java.net.PlainSocketImpl.socketBind(Native Method)
        at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387)
        at java.net.Socket.bind(Socket.java:644)
        at com.vmware.vapi.endpoint.http.BaseServerBuilder.isPortAccessible(BaseServerBuilder.java:172)
        at com.vmware.vapi.endpoint.http.BaseServerBuilder.trimInvalidEndpoints(BaseServerBuilder.java:147)
        at com.vmware.vapi.endpoint.http.BaseServerBuilder.populateEndpointSettings(BaseServerBuilder.java:183)
        at com.vmware.vapi.endpoint.http.BaseServerBuilder.createServer(BaseServerBuilder.java:233)
        at com.vmware.vapi.endpoint.http.BaseServerBuilder.buildInitial(BaseServerBuilder.java:75)
        at com.vmware.vapi.state.impl.DefaultStateManager.build(DefaultStateManager.java:354)
        at com.vmware.vapi.state.impl.DefaultStateManager$1.doInitialConfig(DefaultStateManager.java:168)
        at com.vmware.vapi.state.impl.DefaultStateManager$1.run(DefaultStateManager.java:151)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

okay, so this made clear to me that the application “default” had problems with a port bind, (bind /0:0:0:0:0:0:0:1:12346), so I took a look at the configuration file /etc/vmware-vapi/endpoint.properties, removed the ::1 from the config (I don’t think this is a problem TBH since all the other web apps load up and is accessible via rest)

So I bumped up the VAPI logging (instructions here) and found the below

Looking deeper at the logs with trivia enabled, I found the below when the REST calls failed:

2019-11-27T04:21:10.398+08:00 | DEBUG | vAPI-I/O dispatcher-1     | JsonServerConnection           | Sending JSON response of size 50
2019-11-27T04:21:21.213+08:00 | DEBUG | jetty-default-35          | RequestDispatcher              | method=GET, uriInfo=/vcenter/datacenter
2019-11-27T04:21:21.214+08:00 | DEBUG | jetty-default-35          | UriLocatorImpl                 | Matched uriTemplates are not found for requesturi = /vcenter/datacenter
2019-11-27T04:21:21.215+08:00 | DEBUG | jetty-default-35          | RestMainServlet                | Failed to process request.
RestException [majorErrorCode=404, messageId=com.vmware.vapi.rest.MessageId@1721d534, params=[], message=null]
        at com.vmware.vapi.rest.RequestDispatcher.dispatch(RequestDispatcher.java:64)
        at com.vmware.vapi.endpoint.servlet.rest.RestMainServlet.service(RestMainServlet.java:44)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
        at com.vmware.vapi.endpoint.common.ProxyServlet.service(ProxyServlet.java:50)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
        at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812)
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)
        at org.eclipse.jetty.servlets.DoSFilter.doFilterChain(DoSFilter.java:471)
        at org.eclipse.jetty.servlets.DoSFilter.doFilter(DoSFilter.java:323)
        at org.eclipse.jetty.servlets.DoSFilter.doFilter(DoSFilter.java:293)
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
        at com.vmware.vapi.endpoint.http.RequestSizeFilter.doFilter(RequestSizeFilter.java:59)
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
        at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)
        at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
        at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
        at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:52)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
        at org.eclipse.jetty.server.Server.handle(Server.java:499)
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:258)
        at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
        at java.lang.Thread.run(Thread.java:748)

Okay, so now we are getting somewhere. “Matched uriTemplates are not found for requesturi = /vcenter/datacenter”

I quickly installed jxplorer and reviewed the endpoints for vApi (configuration>site>%site_name%>lookupService>ServiceRegisteration)
Basically, I was looking for the endpoints registered as serviceType.product=com.vmware.cis serviceType.type=cs.vapi

Basically, you wanna look for an endpoint type: .protocol=vapi.json.http and ID com.vmware.vapi.vcenter under the vCenter’s vapi instance similar to the below which was missing on the problematic vCenter.

note that the endpoint name does not really matter. On the problematic vCenter, there existed endpoint9 but it was for a different endpoint.

So what is the difference?

I quickly grabbed the service ID for vApi service for both the working and nonworking instance as a spec using the below command: (replace the id with the service ID on your instance)

/usr/lib/vmidentity/tools/scripts/lstool.py get --url "https://localhost/lookupservice/sdk" --id "f8ab1f69-c73a-4d94-9ac8-7bf85308954e" --no-check-cert --as-spec > /tmp/spec.txI

I observed the below endpoint where missing on the broken vCenter:

endpoint9.type.id=com.vmware.vapi.vcenter  <----------------------------
endpoint9.url=http://localhost:12346/vcenter
endpoint9.ssltrust0=
endpoint9.data0.key=com.vmware.vapi.metadata.authentication.remote
endpoint9.data0.value=http://localhost:12346/vcenter
endpoint9.data1.key=com.vmware.vapi.metadata.metamodel.remote
endpoint9.data1.value=http://localhost:12346/vcenter
endpoint9.data2.key=com.vmware.vapi.metadata.cli.remote
endpoint9.data2.value=http://localhost:12346/vcenter

On the broken vCenter VAPi endpoint spec, I added the above as endpoint12 (11 was in use), Saved the file and re-imported it back in using the below command

/usr/lib/vmidentity/tools/scripts/lstool.py reregister --spec spec.txt --url https://localhost/lookupservice/sdk --user administrator@vsphere.local --password "Admin!23" --id "f8ab1f69-c73a-4d94-9ac8-7bf85308954e" --no-check-cert

Note that the value for “endpoint9.ssltrust0=” should be filled up with the contents found in the spec file

Restarted the VAPI service and VOLA! Rest API for vCenter started to work!!!!

Leave a Reply

Your email address will not be published. Required fields are marked *