Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28db919ffa |
@@ -16,16 +16,15 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||||
Technology platfom.
|
Technology platfom.
|
||||||
|
|
||||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package decort
|
package decort
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -34,6 +33,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
// "time"
|
// "time"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
@@ -42,42 +42,41 @@ import (
|
|||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||||
// "github.com/hashicorp/terraform-plugin-sdk/terraform"
|
// "github.com/hashicorp/terraform-plugin-sdk/terraform"
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// enumerated constants that define authentication modes
|
// enumerated constants that define authentication modes
|
||||||
const (
|
const (
|
||||||
MODE_UNDEF = iota // this is the invalid mode - it should never be seen
|
MODE_UNDEF = iota // this is the invalid mode - it should never be seen
|
||||||
MODE_LEGACY = iota
|
MODE_LEGACY = iota
|
||||||
MODE_OAUTH2 = iota
|
MODE_OAUTH2 = iota
|
||||||
MODE_JWT = iota
|
MODE_JWT = iota
|
||||||
)
|
)
|
||||||
|
|
||||||
type ControllerCfg struct {
|
type ControllerCfg struct {
|
||||||
controller_url string // always required
|
controller_url string // always required
|
||||||
auth_mode_code int // always required
|
auth_mode_code int // always required
|
||||||
auth_mode_txt string // always required, it is a text representation of auth mode
|
auth_mode_txt string // always required, it is a text representation of auth mode
|
||||||
legacy_user string // required for legacy mode
|
legacy_user string // required for legacy mode
|
||||||
legacy_password string // required for legacy mode
|
legacy_password string // required for legacy mode
|
||||||
legacy_sid string // obtained from DECORT controller on successful login in legacy mode
|
legacy_sid string // obtained from DECORT controller on successful login in legacy mode
|
||||||
jwt string // obtained from Outh2 provider on successful login in oauth2 mode, required in jwt mode
|
jwt string // obtained from Outh2 provider on successful login in oauth2 mode, required in jwt mode
|
||||||
app_id string // required for oauth2 mode
|
app_id string // required for oauth2 mode
|
||||||
app_secret string // required for oauth2 mode
|
app_secret string // required for oauth2 mode
|
||||||
oauth2_url string // always required
|
oauth2_url string // always required
|
||||||
decort_username string // assigned to either legacy_user (legacy mode) or Oauth2 user (oauth2 mode) upon successful verification
|
decort_username string // assigned to either legacy_user (legacy mode) or Oauth2 user (oauth2 mode) upon successful verification
|
||||||
cc_client *http.Client // assigned when all initial checks successfully passed
|
cc_client *http.Client // assigned when all initial checks successfully passed
|
||||||
}
|
}
|
||||||
|
|
||||||
func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
|
func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
|
||||||
// This function first will check that all required provider parameters for the
|
// This function first will check that all required provider parameters for the
|
||||||
// selected authenticator mode are set correctly and initialize ControllerCfg structure
|
// selected authenticator mode are set correctly and initialize ControllerCfg structure
|
||||||
// based on the provided parameters.
|
// based on the provided parameters.
|
||||||
//
|
//
|
||||||
// Next, it will check for validity of supplied credentials by initiating connection to the specified
|
// Next, it will check for validity of supplied credentials by initiating connection to the specified
|
||||||
// DECORT controller URL and, if succeeded, completes ControllerCfg structure with the rest of computed
|
// DECORT controller URL and, if succeeded, completes ControllerCfg structure with the rest of computed
|
||||||
// parameters (e.g. JWT, session ID and Oauth2 user name).
|
// parameters (e.g. JWT, session ID and Oauth2 user name).
|
||||||
//
|
//
|
||||||
// The structure created by this function should be used with subsequent calls to decortAPICall() method,
|
// The structure created by this function should be used with subsequent calls to decortAPICall() method,
|
||||||
// which is a DECORT authentication mode aware wrapper around standard HTTP requests.
|
// which is a DECORT authentication mode aware wrapper around standard HTTP requests.
|
||||||
|
|
||||||
ret_config := &ControllerCfg{
|
ret_config := &ControllerCfg{
|
||||||
@@ -90,7 +89,7 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
|
|||||||
app_id: d.Get("app_id").(string),
|
app_id: d.Get("app_id").(string),
|
||||||
app_secret: d.Get("app_secret").(string),
|
app_secret: d.Get("app_secret").(string),
|
||||||
oauth2_url: d.Get("oauth2_url").(string),
|
oauth2_url: d.Get("oauth2_url").(string),
|
||||||
decort_username: "",
|
decort_username: "",
|
||||||
}
|
}
|
||||||
|
|
||||||
var allow_unverified_ssl bool
|
var allow_unverified_ssl bool
|
||||||
@@ -137,10 +136,10 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
|
|||||||
|
|
||||||
if allow_unverified_ssl {
|
if allow_unverified_ssl {
|
||||||
log.Warn("ControllerConfigure: allow_unverified_ssl is set - will not check certificates!")
|
log.Warn("ControllerConfigure: allow_unverified_ssl is set - will not check certificates!")
|
||||||
transCfg := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true},}
|
transCfg := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}
|
||||||
ret_config.cc_client = &http.Client{
|
ret_config.cc_client = &http.Client{
|
||||||
Transport: transCfg,
|
Transport: transCfg,
|
||||||
Timeout: Timeout180s,
|
Timeout: Timeout180s,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret_config.cc_client = &http.Client{
|
ret_config.cc_client = &http.Client{
|
||||||
@@ -150,7 +149,7 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
|
|||||||
|
|
||||||
switch ret_config.auth_mode_code {
|
switch ret_config.auth_mode_code {
|
||||||
case MODE_LEGACY:
|
case MODE_LEGACY:
|
||||||
ok, err := ret_config.validateLegacyUser()
|
ok, err := ret_config.validateLegacyUser()
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -162,13 +161,13 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
case MODE_OAUTH2:
|
case MODE_OAUTH2:
|
||||||
// on success getOAuth2JWT will set config.jwt to the obtained JWT, so there is no
|
// on success getOAuth2JWT will set config.jwt to the obtained JWT, so there is no
|
||||||
// need to set it once again here
|
// need to set it once again here
|
||||||
_, err := ret_config.getOAuth2JWT()
|
_, err := ret_config.getOAuth2JWT()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// we are not verifying the JWT when parsing because actual verification is done on the
|
// we are not verifying the JWT when parsing because actual verification is done on the
|
||||||
// OVC controller side. Here we do parsing solely to extract Oauth2 user name (claim "user")
|
// OVC controller side. Here we do parsing solely to extract Oauth2 user name (claim "user")
|
||||||
// and JWT issuer name (claim "iss")
|
// and JWT issuer name (claim "iss")
|
||||||
parser := jwt.Parser{}
|
parser := jwt.Parser{}
|
||||||
@@ -181,7 +180,7 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
|
|||||||
tbuf.WriteString(claims["username"].(string))
|
tbuf.WriteString(claims["username"].(string))
|
||||||
tbuf.WriteString("@")
|
tbuf.WriteString("@")
|
||||||
tbuf.WriteString(claims["iss"].(string))
|
tbuf.WriteString(claims["iss"].(string))
|
||||||
ret_config.decort_username = tbuf.String()
|
ret_config.decort_username = tbuf.String()
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("Failed to extract user and iss fields from JWT token in oauth2 mode.")
|
return nil, fmt.Errorf("Failed to extract user and iss fields from JWT token in oauth2 mode.")
|
||||||
}
|
}
|
||||||
@@ -195,7 +194,7 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
|
|||||||
return ret_config, nil
|
return ret_config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config *ControllerCfg) getDecortUsername() (string) {
|
func (config *ControllerCfg) getDecortUsername() string {
|
||||||
return config.decort_username
|
return config.decort_username
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,14 +215,14 @@ func (config *ControllerCfg) getOAuth2JWT() (string, error) {
|
|||||||
params.Add("validity", "3600")
|
params.Add("validity", "3600")
|
||||||
params_str := params.Encode()
|
params_str := params.Encode()
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", config.oauth2_url + "/v1/oauth/access_token", strings.NewReader(params_str))
|
req, err := http.NewRequest("POST", config.oauth2_url+"/v1/oauth/access_token", strings.NewReader(params_str))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
req.Header.Set("Content-Length", strconv.Itoa(len(params_str)))
|
req.Header.Set("Content-Length", strconv.Itoa(len(params_str)))
|
||||||
|
|
||||||
resp, err := config.cc_client.Do(req)
|
resp, err := config.cc_client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -231,16 +230,16 @@ func (config *ControllerCfg) getOAuth2JWT() (string, error) {
|
|||||||
// fmt.Println("response Status:", resp.Status)
|
// fmt.Println("response Status:", resp.Status)
|
||||||
// fmt.Println("response Headers:", resp.Header)
|
// fmt.Println("response Headers:", resp.Header)
|
||||||
// fmt.Println("response Headers:", req.URL)
|
// fmt.Println("response Headers:", req.URL)
|
||||||
return "", fmt.Errorf("getOauth2JWT: unexpected status code %d when obtaining JWT from %q for APP_ID %q, request Body %q",
|
return "", fmt.Errorf("getOauth2JWT: unexpected status code %d when obtaining JWT from %q for APP_ID %q, request Body %q",
|
||||||
resp.StatusCode, req.URL, config.app_id, params_str)
|
resp.StatusCode, req.URL, config.app_id, params_str)
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
responseData, err := ioutil.ReadAll(resp.Body)
|
responseData, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// validation successful - store JWT in the corresponding field of the ControllerCfg structure
|
// validation successful - store JWT in the corresponding field of the ControllerCfg structure
|
||||||
config.jwt = strings.TrimSpace(string(responseData))
|
config.jwt = strings.TrimSpace(string(responseData))
|
||||||
|
|
||||||
@@ -249,10 +248,10 @@ func (config *ControllerCfg) getOAuth2JWT() (string, error) {
|
|||||||
|
|
||||||
func (config *ControllerCfg) validateJWT(jwt string) (bool, error) {
|
func (config *ControllerCfg) validateJWT(jwt string) (bool, error) {
|
||||||
/*
|
/*
|
||||||
Validate JWT against DECORT controller. JWT can be supplied as argument to this method. If empty string supplied as
|
Validate JWT against DECORT controller. JWT can be supplied as argument to this method. If empty string supplied as
|
||||||
argument, JWT will be taken from config attribute.
|
argument, JWT will be taken from config attribute.
|
||||||
DECORT controller URL will always be taken from the config attribute assigned at instantiation.
|
DECORT controller URL will always be taken from the config attribute assigned at instantiation.
|
||||||
Validation is accomplished by attempting API call that lists accounts for the invoking user.
|
Validation is accomplished by attempting API call that lists accounts for the invoking user.
|
||||||
*/
|
*/
|
||||||
if jwt == "" {
|
if jwt == "" {
|
||||||
if config.jwt == "" {
|
if config.jwt == "" {
|
||||||
@@ -265,7 +264,7 @@ func (config *ControllerCfg) validateJWT(jwt string) (bool, error) {
|
|||||||
return false, fmt.Errorf("validateJWT method called, but no OAuth2 URL provided.")
|
return false, fmt.Errorf("validateJWT method called, but no OAuth2 URL provided.")
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", config.controller_url + "/restmachine/cloudapi/accounts/list", nil)
|
req, err := http.NewRequest("POST", config.controller_url+"/restmachine/cloudapi/accounts/list", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -273,14 +272,14 @@ func (config *ControllerCfg) validateJWT(jwt string) (bool, error) {
|
|||||||
req.Header.Set("Authorization", fmt.Sprintf("bearer %s", jwt))
|
req.Header.Set("Authorization", fmt.Sprintf("bearer %s", jwt))
|
||||||
// req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
// req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
// req.Header.Set("Content-Length", strconv.Itoa(0))
|
// req.Header.Set("Content-Length", strconv.Itoa(0))
|
||||||
|
|
||||||
resp, err := config.cc_client.Do(req)
|
resp, err := config.cc_client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return false, fmt.Errorf("validateJWT: unexpected status code %d when validating JWT against %q.",
|
return false, fmt.Errorf("validateJWT: unexpected status code %d when validating JWT against %q.",
|
||||||
resp.StatusCode, req.URL)
|
resp.StatusCode, req.URL)
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
@@ -289,10 +288,10 @@ func (config *ControllerCfg) validateJWT(jwt string) (bool, error) {
|
|||||||
|
|
||||||
func (config *ControllerCfg) validateLegacyUser() (bool, error) {
|
func (config *ControllerCfg) validateLegacyUser() (bool, error) {
|
||||||
/*
|
/*
|
||||||
Validate legacy user by obtaining a session key, which will be used for authenticating subsequent API calls
|
Validate legacy user by obtaining a session key, which will be used for authenticating subsequent API calls
|
||||||
to DECORT controller.
|
to DECORT controller.
|
||||||
If successful, the session key is stored in config.legacy_sid and true is returned. If unsuccessful for any
|
If successful, the session key is stored in config.legacy_sid and true is returned. If unsuccessful for any
|
||||||
reason, the method will return false and error.
|
reason, the method will return false and error.
|
||||||
*/
|
*/
|
||||||
if config.auth_mode_code == MODE_UNDEF {
|
if config.auth_mode_code == MODE_UNDEF {
|
||||||
return false, fmt.Errorf("validateLegacyUser method called for undefined authorization mode.")
|
return false, fmt.Errorf("validateLegacyUser method called for undefined authorization mode.")
|
||||||
@@ -306,7 +305,7 @@ func (config *ControllerCfg) validateLegacyUser() (bool, error) {
|
|||||||
params.Add("password", config.legacy_password)
|
params.Add("password", config.legacy_password)
|
||||||
params_str := params.Encode()
|
params_str := params.Encode()
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", config.controller_url + "/restmachine/cloudapi/users/authenticate", strings.NewReader(params_str))
|
req, err := http.NewRequest("POST", config.controller_url+"/restmachine/cloudapi/users/authenticate", strings.NewReader(params_str))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -314,21 +313,21 @@ func (config *ControllerCfg) validateLegacyUser() (bool, error) {
|
|||||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
req.Header.Set("Content-Length", strconv.Itoa(len(params_str)))
|
req.Header.Set("Content-Length", strconv.Itoa(len(params_str)))
|
||||||
|
|
||||||
resp, err := config.cc_client.Do(req)
|
resp, err := config.cc_client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return false, fmt.Errorf("validateLegacyUser: unexpected status code %d when validating legacy user %q against %q.",
|
return false, fmt.Errorf("validateLegacyUser: unexpected status code %d when validating legacy user %q against %q.",
|
||||||
resp.StatusCode, config.legacy_user, config.controller_url)
|
resp.StatusCode, config.legacy_user, config.controller_url)
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
responseData, err := ioutil.ReadAll(resp.Body)
|
responseData, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// validation successful - keep session ID for future use
|
// validation successful - keep session ID for future use
|
||||||
config.legacy_sid = string(responseData)
|
config.legacy_sid = string(responseData)
|
||||||
|
|
||||||
@@ -336,16 +335,16 @@ func (config *ControllerCfg) validateLegacyUser() (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (config *ControllerCfg) decortAPICall(method string, api_name string, url_values *url.Values) (json_resp string, err error) {
|
func (config *ControllerCfg) decortAPICall(method string, api_name string, url_values *url.Values) (json_resp string, err error) {
|
||||||
// This is a convenience wrapper around standard HTTP request methods that is aware of the
|
// This is a convenience wrapper around standard HTTP request methods that is aware of the
|
||||||
// authorization mode for which the provider was initialized and compiles request accordingly.
|
// authorization mode for which the provider was initialized and compiles request accordingly.
|
||||||
|
|
||||||
if config.cc_client == nil {
|
if config.cc_client == nil {
|
||||||
// this should never happen if ClientConfig was properly called prior to decortAPICall
|
// this should never happen if ClientConfig was properly called prior to decortAPICall
|
||||||
return "", fmt.Errorf("decortAPICall method called with unconfigured DECORT cloud controller HTTP client.")
|
return "", fmt.Errorf("decortAPICall method called with unconfigured DECORT cloud controller HTTP client.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Example: to create api_params, one would generally do the following:
|
// Example: to create api_params, one would generally do the following:
|
||||||
//
|
//
|
||||||
// data := []byte(`{"machineId": "2638"}`)
|
// data := []byte(`{"machineId": "2638"}`)
|
||||||
// api_params := bytes.NewBuffer(data))
|
// api_params := bytes.NewBuffer(data))
|
||||||
//
|
//
|
||||||
@@ -367,42 +366,41 @@ func (config *ControllerCfg) decortAPICall(method string, api_name string, url_v
|
|||||||
}
|
}
|
||||||
params_str := url_values.Encode()
|
params_str := url_values.Encode()
|
||||||
|
|
||||||
req, err := http.NewRequest(method, config.controller_url + api_name, strings.NewReader(params_str))
|
req, err := http.NewRequest(method, config.controller_url+api_name, strings.NewReader(params_str))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
req.Header.Set("Content-Length", strconv.Itoa(len(params_str)))
|
req.Header.Set("Content-Length", strconv.Itoa(len(params_str)))
|
||||||
|
req.Header.Set("Accept", "application/json")
|
||||||
|
|
||||||
if config.auth_mode_code == MODE_OAUTH2 || config.auth_mode_code == MODE_JWT {
|
if config.auth_mode_code == MODE_OAUTH2 || config.auth_mode_code == MODE_JWT {
|
||||||
req.Header.Set("Authorization", fmt.Sprintf("bearer %s", config.jwt))
|
req.Header.Set("Authorization", fmt.Sprintf("bearer %s", config.jwt))
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := config.cc_client.Do(req)
|
resp, err := config.cc_client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode == http.StatusOK {
|
if resp.StatusCode == http.StatusOK {
|
||||||
tmp_body, err := ioutil.ReadAll(resp.Body)
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
json_resp := Jo2JSON(string(tmp_body))
|
log.Debugf("decortAPICall: %s %s\n %s", method, api_name, body)
|
||||||
log.Debugf("decortAPICall: %s %s\n %s", method, api_name, json_resp)
|
return string(body), nil
|
||||||
return json_resp, nil
|
|
||||||
} else {
|
} else {
|
||||||
return "", fmt.Errorf("decortAPICall: unexpected status code %d when calling API %q with request Body %q",
|
return "", fmt.Errorf("decortAPICall: unexpected status code %d when calling API %q with request Body %q",
|
||||||
resp.StatusCode, req.URL, params_str)
|
resp.StatusCode, req.URL, params_str)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if resp.StatusCode == StatusServiceUnavailable {
|
if resp.StatusCode == StatusServiceUnavailable {
|
||||||
return nil, fmt.Errorf("decortAPICall method called for incompatible authorization mode %q.", config.auth_mode_txt)
|
return nil, fmt.Errorf("decortAPICall method called for incompatible authorization mode %q.", config.auth_mode_txt)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user