@@ -18,52 +18,85 @@ import (
1818)
1919
2020func ensureTargetConnection () error {
21- // If the targetConfig.accesstoken is not set or testAccesToken returns false
22- if ! testAccessToken () {
23- var authError error
24- // Authenticate
25- if targetConfig .apitoken != "" {
26- targetConfig .accesstoken , authError = authenticateCloud (targetConfig )
27- } else {
28- targetConfig .accesstoken , authError = authenticateOnPrem (targetConfig )
29- }
30- if authError != nil {
31- return authError
21+ if testAccessToken () { // If the Access Token is OK
22+ log .Debugln ("Access Token is valid" )
23+ } else {
24+ var refreshTokenError , credentialError error
25+ targetConfig .accesstoken , refreshTokenError = authenticateApiToken (targetConfig .server , targetConfig .apitoken ) // Test the API Token (refresh_token)
26+ if refreshTokenError != nil { // We could not get an access token from the API Token
27+ log .Debugln ("Refresh Token is invalid" )
28+ if targetConfig .server == "api.mgmt.cloud.vmware.com" { // If it's vRA Cloud we have no credentials to authenticate
29+ return refreshTokenError // Return the token error
30+ }
31+ targetConfig .apitoken , credentialError = authenticateCredentials (targetConfig .server , targetConfig .username , targetConfig .password , targetConfig .domain )
32+ if credentialError != nil {
33+ return credentialError // Return the credential error
34+ }
35+ // Try again, now we have a new access token
36+ targetConfig .accesstoken , refreshTokenError = authenticateApiToken (targetConfig .server , targetConfig .apitoken ) // Test the API Token (refresh_token)
37+ if refreshTokenError != nil {
38+ return refreshTokenError
39+ }
3240 }
33- if viper .ConfigFileUsed () != "" {
41+
42+ if viper .ConfigFileUsed () != "" { // If we're using a Config file
3443 viper .Set ("target." + currentTargetName + ".accesstoken" , targetConfig .accesstoken )
44+ viper .Set ("target." + currentTargetName + ".apitoken" , targetConfig .apitoken )
3545 viper .WriteConfig ()
3646 }
47+
3748 }
3849 return nil
3950}
4051
41- func authenticateOnPrem (target config ) (string , error ) {
42- log .Debugln ("Authenticating vRA" )
52+ // authenticateCredentials - returns the API Refresh Token for vRA On-premesis (8.0.1+)
53+ func authenticateCredentials (server string , username string , password string , domain string ) (string , error ) {
54+ log .Debugln ("Authenticating vRA with Credentials" )
55+ var authPath string
56+ var authBody AuthenticationRequest
57+ authBody .Username = username
58+ authBody .Password = password
4359 client := resty .New ()
44- queryResponse , err := client .SetTLSClientConfig (& tls.Config {InsecureSkipVerify : ignoreCert }).R ().
45- SetBody (AuthenticationRequest {target .username , target .password , target .domain }).
60+
61+ if domain == "" {
62+ log .Debugln ("Basic Auth" )
63+ // Use Basic Authentication
64+ authPath = "/csp/gateway/am/api/login?access_token"
65+ } else {
66+ log .Debugln ("Enhanced Auth" )
67+ // Use Enhanced Login (e.g. domain users)
68+ authPath = "/csp/gateway/am/idp/auth/login?access_token"
69+ authBody .Domain = domain
70+ }
71+
72+ loginResponse , err := client .SetTLSClientConfig (& tls.Config {InsecureSkipVerify : ignoreCert }).R ().
73+ SetBody (authBody ).
4674 SetResult (& AuthenticationResponse {}).
4775 SetError (& AuthenticationError {}).
48- Post ("https://" + target .server + "/csp/gateway/am/idp/auth/login?access_token" )
49- if queryResponse .IsError () {
50- return "" , errors .New (queryResponse .Error ().(* AuthenticationError ).ServerMessage )
76+ Post ("https://" + server + authPath )
77+ if loginResponse .IsError () {
78+ log .Debugln ("Authentication failed" )
79+ return "" , errors .New (loginResponse .Error ().(* AuthenticationError ).ServerMessage )
5180 }
52- return queryResponse .Result ().(* AuthenticationResponse ).AccessToken , err
81+ log .Debugln ("Authentication succeeded" )
82+ return loginResponse .Result ().(* AuthenticationResponse ).RefreshToken , err
5383}
54- func authenticateCloud (target config ) (string , error ) {
55- log .Debugln ("Authenticating vRA Cloud" )
84+
85+ // authenticateApiToken - get vRA Access token (valid for 8h)
86+ func authenticateApiToken (server string , token string ) (string , error ) {
87+ log .Debug ("Attempting to authenticate the API Refresh Token" )
5688 client := resty .New ()
5789 queryResponse , err := client .SetTLSClientConfig (& tls.Config {InsecureSkipVerify : ignoreCert }).R ().
58- SetBody (AuthenticationRequestCloud { target . apitoken }).
59- SetResult (& AuthenticationResponseCloud {}).
60- SetError (& AuthenticationError {}).
61- Post ("https://" + target . server + "/iaas/api/login" )
90+ SetBody (ApiAuthentication { token }).
91+ SetResult (& ApiAuthenticationResponse {}).
92+ SetError (& ApiAuthenticationError {}).
93+ Post ("https://" + server + "/iaas/api/login" )
6294 if queryResponse .IsError () {
63- log .Debugln ( "Authentication failed!" , queryResponse . RawResponse )
64- return "" , errors .New (queryResponse .Error ().(* AuthenticationError ). ServerMessage )
95+ log .Debug ( "Refresh Token failed" )
96+ return "" , errors .New (queryResponse .Error ().(* ApiAuthenticationError ). Message )
6597 }
66- return queryResponse .Result ().(* AuthenticationResponseCloud ).Token , err
98+ log .Debug ("Refresh Token succeeded" )
99+ return queryResponse .Result ().(* ApiAuthenticationResponse ).Token , err
67100}
68101
69102func testAccessToken () bool {
0 commit comments