In the 4.2.0 release of the vSphere Plugin, we added Pure1 integration which provided additional insight into your Pure Storage and vSphere Environment. In order to use this though, you need to connect the plugin with Pure1 of course. The authentication method is based on a process which involves something called a JSON Web Token. This is a secure option, but a bit more involved than a user name and password. I made the process of generating this fairly easy, but if something goes wrong you get a fun error message like below:
Hmm.
So we are working on improving the error handling directly in the plugin for Pure1 authentication (which was a major oversight on my part). In the meantime, let’s troubleshoot.
Verify Network Connectivity
This is really step one. Does your vCenter have TCP port 443 access to api.pure1.purestorage.com?
SSH into vCenter and run:
nc api.pure1.purestorage.com 443 -zv
If this fails, you know that there is a network problem.
Verify the JWT
Okay if that is good it is probably something to do with your JWT. Before you walk through this (though it is pretty quick), make sure you have removed all white space from your JWT (like new lines ) by pasting it into notepad or something and making it one line.
If that doesn’t fix the problem, move forward:
1). SSH into a Linux host (or, ideally, your vCenter)
2). Store the JWT into a variable in bash:
JWT=eyJhbGciOiJSUzI1NiIsI<etc. etc. etc.>EopDv-A
If it throws an error, make sure there are no spaces between the around the equals sign (so JWT=ey…. not JWT = ey…..). You can verify it looks good by running:
echo $JWT
3). Paste the entire thing below with no changes in and hit enter:
curl -X POST "https://api.pure1.purestorage.com/oauth2/1.0/token" -H "accept: application/json" -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange&subject_token=$JWT&subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Ajwt"
If there is something wrong with the JWT you will see it here:
In this case you will see a very clear error:
{"error":"unauthorized_client","error_description":"Invalid issuer: JWT validation failed. JWT expired at 2019-12-08T01:44:17Z. Current time: 2019-12-08T02:28:17Z, a difference of 2640636 milliseconds. Allowed clock skew: 0 milliseconds."}
Pretty straight forward–the JWT expired. You can see the full set of error codes here.
Note if you add:
-o /dev/null -w "\nError Code: %{http_code} \n\n" -s
to the end of your command the curl response will just show the Pure1 error code:
If you want to keep using CURL…
If authentication works, we will see something like the below after sending the JWT.
curl -X POST "https://api.pure1.purestorage.com/oauth2/1.0/token" -H "accept: application/json" -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange&subject_token=$JWT&subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Ajwt" {"access_token":"eyJraWQiOiJNZjhyK3JlTTZ6blIrS2NkbzM1d1pkZ3dnS2I2IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJhdWQiOiJwdWJsaWMtYXBpIiwic3ViIjoiMjczNDYiLCJyb2xlIjoiUFVSRSIsIm1heF9yb2xlIjoiYWRtaW4iLCJvcmciOjMyMzYsInBoX29pZCI6MTA4MzYsInBoX3VpZCI6MCwiaXNzIjoiaHR0cHM6Ly90ZXguY2xvdWQtc3VwcG9ydC5wdXJlc3RvcmFnZS5jb20iLCJpYXQiOjE1NzU3NzEwMTksImV4cCI6MTU3NTgwNzAxOSwianRpIjoiODViYzg1MDQtYzk1NC00OWUwLWIxNGItZjJhNzAxMjUzYmZlIn0.jgdWTjAJ-QCn2ZpVUk3wUlP2zUspf8JKPQtBDIgoKQEBA1cUHY_DEOu2QFzwaaPHqDcFhcBzLoY9o5XT00i1WrHk2N40_cRlVrYnu5wwWQaz9E4hJ9LzORtjMXyWV4GbRnnWhTmBO01NO-weXC0CGe6wn6qiHg--NiGFiGorHle2Yz0SRRIUpcBwcNnySK-TyvCGwXYRmRFNIrMsva87UxZhoJJ5UoNpjx3B8Z9gdweC7m4Uj3RmRqwZycecZ1fre-BAvLxVRuyDOfX0MhF6p-Ua836y7zrePjHiPd4EpoVdkq2wom4WZBccY_rhm-zGtgKVQJJAS5tC71DjciQVwg","issued_token_type":"urn:ietf:params:oauth:token-type:access_token","token_type":"Bearer","expires_in":35999}
If you want to play with the Pure1 REST you can take the access token and add “Authorization: Bearer ” before it and pull information from Pure1. This would be a GET on arrays for instance:
AUTH="Authorization: Bearer eyJraWQiOiJNZjhyK3JlTTZ6blIrS2NkbzM1d1pkZ3dnS2I2IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ.eyJhdWQiOiJwdWJsaWMtYXBpIiwic3ViIjoiMjczNDYiLCJyb2xlIjoiUFVSRSIsIm1heF9yb2xlIjoiYWRtaW4iLCJvcmciOjMyMzYsInBoX29pZCI6MTA4MzYsInBoX3VpZCI6MCwiaXNzIjoiaHR0cHM6Ly90ZXguY2xvdWQtc3VwcG9ydC5wdXJlc3RvcmFnZS5jb20iLCJpYXQiOjE1NzU3NzEwMTksImV4cCI6MTU3NTgwNzAxOSwianRpIjoiODViYzg1MDQtYzk1NC00OWUwLWIxNGItZjJhNzAxMjUzYmZlIn0.jgdWTjAJ-QCn2ZpVUk3wUlP2zUspf8JKPQtBDIgoKQEBA1cUHY_DEOu2QFzwaaPHqDcFhcBzLoY9o5XT00i1WrHk2N40_cRlVrYnu5wwWQaz9E4hJ9LzORtjMXyWV4GbRnnWhTmBO01NO-weXC0CGe6wn6qiHg--NiGFiGorHle2Yz0SRRIUpcBwcNnySK-TyvCGwXYRmRFNIrMsva87UxZhoJJ5UoNpjx3B8Z9gdweC7m4Uj3RmRqwZycecZ1fre-BAvLxVRuyDOfX0MhF6p-Ua836y7zrePjHiPd4EpoVdkq2wom4WZBccY_rhm-zGtgKVQJJAS5tC71DjciQVwg" curl https://api.pure1.purestorage.com/api/1.0/arrays -H "${AUTH}" -H 'Content-Type: application/json' {"total_item_count":16,"continuation_token":null,"items":[{"id":"0cb3faec-8246-4159-9bfa-dbfccd2df510","name":"sn1-m20-c08-17","model":"FA-m20r2","os":"Purity//FA","version":"5.3.1","_as_of":1575771331000},{"id":"1037b35f-d0ef-40a5-9a43-ce013dae9f13","name":"sn1-x70-b05-33","model":"FA- <etc........>
I ended up having to bypass this communication from HTTPS inspection on our firewall/URL filter. Oddly enough, i had to bypass it from pure1.purestorage.com. I figured api.pure1.purestorage.com would do the trick, but i didn’t see any traffic going to that URL
Ah interesting, might be something to do with the root address. I will verify this and see that it is documented. Thank you!
It would authenticate, but I’m still having issues pulling data. I tried adding the API.pure1.purestorage url to the bypass but the plug-in still isn’t pleased. The upside is that Pure1 saw it hit the JWT when I attempted it with the Pure1.purestorage.com url bypassed from HTTPS inspection.
To give background, it has to do with the interruption in the cert chain.(per curl errors and past experience) I’ve seen it before with curl, git and any HTTPS process that requires a valid root CA. I can’t speak for all of them, but our HTTPS inspection engine pins the server side cert to it’s own root cert in the chain.
I see three fixes that don’t involve bypassing URLs from HTTPS inspection. 1) Install the HTTPS inspection cert in the VCSA cert store 2) Find a way for the plug-in to allow server side certs that aren’t validated against the cert store. 3) Install the cert on a cert store specific to the plug-in. One of those options isn’t pretty and the other two require altering the plug-in.
Do you mind opening a ticket with Pure support with these requests? I will ensure eng looks at it
Just opened the ticket!
Thank you! If you use Slack, we have a #ask-vsphereplugin channel too you can use, https://codeinvite.purestorage.com/ We can chat there as well, it is harder for me to give quick responses here. And others keep an eye on that channel too. Of course feel free to continue to use this here, just bear in mind I might be slow lol
Is there any mechanism to allow this to happen through a proxy? All of my managed systems live behind a proxy configuration, vCenter is configured to use it, and other HTML5 plug-ins are able to download as expected.