github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/oci/common/errors.go (about)

     1  // Copyright 2018 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details
     3  
     4  package common
     5  
     6  import (
     7  	"github.com/juju/collections/set"
     8  	ociCommon "github.com/oracle/oci-go-sdk/common"
     9  
    10  	"github.com/juju/juju/environs/context"
    11  	"github.com/juju/juju/provider/common"
    12  )
    13  
    14  // Oracle bundles authorisation errors into HTTP 401, HTTP 404 and
    15  // HTTP 409, without specifically indicating that it's an authorisation
    16  // failure. Each response includes a Code field that we can match against,
    17  // but they remain intentionally ambiguous.
    18  //
    19  // The codes we match against are:
    20  //   - HTTP 401 ("NotAuthenticated")
    21  //   - HTTP 404 ("NotAuthorizedOrNotFound")
    22  //   - HTTP 409 ("NotAuthorizedOrResourceAlreadyExists")
    23  //
    24  // As we're not generating any API calls manually, it's unlikely
    25  // that we'll be striking URIs that don't exist at all, therefore we assume
    26  // auth issues are causing the errors.
    27  //
    28  // For more details, see https://docs.cloud.oracle.com/iaas/Content/API/References/apierrors.htm
    29  var authErrorCodes = set.NewStrings(
    30  	"NotAuthenticated",
    31  	"NotAuthorizedOrResourceAlreadyExists",
    32  	"NotAuthorizedOrNotFound",
    33  )
    34  
    35  // IsAuthorisationFailure reports whether the error is related to
    36  // attempting to access the provider with invalid or expired credentials.
    37  func IsAuthorisationFailure(err error) bool {
    38  	if err == nil {
    39  		return false
    40  	}
    41  
    42  	serviceError, ok := err.(ociCommon.ServiceError)
    43  	if !ok {
    44  		// Just to double check, also try the SDK's
    45  		// implementation. This isn't checked first, because
    46  		// it is hard to test.
    47  		serviceError, ok = ociCommon.IsServiceError(err)
    48  	}
    49  
    50  	if ok && authErrorCodes.Contains(serviceError.GetCode()) {
    51  		return true
    52  	}
    53  
    54  	return false
    55  }
    56  
    57  // HandleCredentialError marks the current credentials as invalid internally
    58  //  if Oracle believes that they are expired
    59  func HandleCredentialError(err error, ctx context.ProviderCallContext) {
    60  	common.HandleCredentialError(IsAuthorisationFailure, err, ctx)
    61  }