github.com/iaas-resource-provision/iaas-rpc@v1.0.7-0.20211021023331-ed21f798c408/internal/getproviders/errors.go (about)

     1  package getproviders
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  
     7  	svchost "github.com/iaas-resource-provision/iaas-rpc-svchost"
     8  	"github.com/iaas-resource-provision/iaas-rpc/internal/addrs"
     9  )
    10  
    11  // ErrHostNoProviders is an error type used to indicate that a hostname given
    12  // in a provider address does not support the provider registry protocol.
    13  type ErrHostNoProviders struct {
    14  	Hostname svchost.Hostname
    15  
    16  	// HasOtherVersionis set to true if the discovery process detected
    17  	// declarations of services named "providers" whose version numbers did not
    18  	// match any version supported by the current version of Terraform.
    19  	//
    20  	// If this is set, it's helpful to hint to the user in an error message
    21  	// that the provider host may be expecting an older or a newer version
    22  	// of Terraform, rather than that it isn't a provider registry host at all.
    23  	HasOtherVersion bool
    24  }
    25  
    26  func (err ErrHostNoProviders) Error() string {
    27  	switch {
    28  	case err.HasOtherVersion:
    29  		return fmt.Sprintf("host %s does not support the provider registry protocol required by this Terraform version, but may be compatible with a different Terraform version", err.Hostname.ForDisplay())
    30  	default:
    31  		return fmt.Sprintf("host %s does not offer a Terraform provider registry", err.Hostname.ForDisplay())
    32  	}
    33  }
    34  
    35  // ErrHostUnreachable is an error type used to indicate that a hostname
    36  // given in a provider address did not resolve in DNS, did not respond to an
    37  // HTTPS request for service discovery, or otherwise failed to correctly speak
    38  // the service discovery protocol.
    39  type ErrHostUnreachable struct {
    40  	Hostname svchost.Hostname
    41  	Wrapped  error
    42  }
    43  
    44  func (err ErrHostUnreachable) Error() string {
    45  	return fmt.Sprintf("could not connect to %s: %s", err.Hostname.ForDisplay(), err.Wrapped.Error())
    46  }
    47  
    48  // Unwrap returns the underlying error that occurred when trying to reach the
    49  // indicated host.
    50  func (err ErrHostUnreachable) Unwrap() error {
    51  	return err.Wrapped
    52  }
    53  
    54  // ErrUnauthorized is an error type used to indicate that a hostname
    55  // given in a provider address returned a "401 Unauthorized" or "403 Forbidden"
    56  // error response when we tried to access it.
    57  type ErrUnauthorized struct {
    58  	Hostname svchost.Hostname
    59  
    60  	// HaveCredentials is true when the request that failed included some
    61  	// credentials, and thus it seems that those credentials were invalid.
    62  	// Conversely, HaveCredentials is false if the request did not include
    63  	// credentials at all, in which case it seems that credentials must be
    64  	// provided.
    65  	HaveCredentials bool
    66  }
    67  
    68  func (err ErrUnauthorized) Error() string {
    69  	switch {
    70  	case err.HaveCredentials:
    71  		return fmt.Sprintf("host %s rejected the given authentication credentials", err.Hostname)
    72  	default:
    73  		return fmt.Sprintf("host %s requires authentication credentials", err.Hostname)
    74  	}
    75  }
    76  
    77  // ErrProviderNotFound is an error type used to indicate that requested provider
    78  // was not found in the source(s) included in the Description field. This can be
    79  // used to produce user-friendly error messages.
    80  type ErrProviderNotFound struct {
    81  	Provider addrs.Provider
    82  	Sources  []string
    83  }
    84  
    85  func (err ErrProviderNotFound) Error() string {
    86  	return fmt.Sprintf(
    87  		"provider %s was not found in any of the search locations",
    88  		err.Provider,
    89  	)
    90  }
    91  
    92  // ErrRegistryProviderNotKnown is an error type used to indicate that the hostname
    93  // given in a provider address does appear to be a provider registry but that
    94  // registry does not know about the given provider namespace or type.
    95  //
    96  // A caller serving requests from an end-user should recognize this error type
    97  // and use it to produce user-friendly hints for common errors such as failing
    98  // to specify an explicit source for a provider not in the default namespace
    99  // (one not under registry.terraform.io/hashicorp/). The default error message
   100  // for this type is a direct description of the problem with no such hints,
   101  // because we expect that the caller will have better context to decide what
   102  // hints are appropriate, e.g. by looking at the configuration given by the
   103  // user.
   104  type ErrRegistryProviderNotKnown struct {
   105  	Provider addrs.Provider
   106  }
   107  
   108  func (err ErrRegistryProviderNotKnown) Error() string {
   109  	return fmt.Sprintf(
   110  		"provider registry %s does not have a provider named %s",
   111  		err.Provider.Hostname.ForDisplay(),
   112  		err.Provider,
   113  	)
   114  }
   115  
   116  // ErrPlatformNotSupported is an error type used to indicate that a particular
   117  // version of a provider isn't available for a particular target platform.
   118  //
   119  // This is returned when DownloadLocation encounters a 404 Not Found response
   120  // from the underlying registry, because it presumes that a caller will only
   121  // ask for the DownloadLocation for a version it already found the existence
   122  // of via AvailableVersions.
   123  type ErrPlatformNotSupported struct {
   124  	Provider addrs.Provider
   125  	Version  Version
   126  	Platform Platform
   127  
   128  	// MirrorURL, if non-nil, is the base URL of the mirror that serviced
   129  	// the request in place of the provider's origin registry. MirrorURL
   130  	// is nil for a direct query.
   131  	MirrorURL *url.URL
   132  }
   133  
   134  func (err ErrPlatformNotSupported) Error() string {
   135  	if err.MirrorURL != nil {
   136  		return fmt.Sprintf(
   137  			"provider mirror %s does not have a package of %s %s for %s",
   138  			err.MirrorURL.String(),
   139  			err.Provider,
   140  			err.Version,
   141  			err.Platform,
   142  		)
   143  	}
   144  	return fmt.Sprintf(
   145  		"provider %s %s is not available for %s",
   146  		err.Provider,
   147  		err.Version,
   148  		err.Platform,
   149  	)
   150  }
   151  
   152  // ErrProtocolNotSupported is an error type used to indicate that a particular
   153  // version of a provider is not supported by the current version of Terraform.
   154  //
   155  // Specfically, this is returned when the version's plugin protocol is not supported.
   156  //
   157  // When available, the error will include a suggested version that can be displayed to
   158  // the user. Otherwise it will return UnspecifiedVersion
   159  type ErrProtocolNotSupported struct {
   160  	Provider   addrs.Provider
   161  	Version    Version
   162  	Suggestion Version
   163  }
   164  
   165  func (err ErrProtocolNotSupported) Error() string {
   166  	return fmt.Sprintf(
   167  		"provider %s %s is not supported by this version of terraform",
   168  		err.Provider,
   169  		err.Version,
   170  	)
   171  }
   172  
   173  // ErrQueryFailed is an error type used to indicate that the hostname given
   174  // in a provider address does appear to be a provider registry but that when
   175  // we queried it for metadata for the given provider the server returned an
   176  // unexpected error.
   177  //
   178  // This is used for any error responses other than "Not Found", which would
   179  // indicate the absense of a provider and is thus reported using
   180  // ErrProviderNotKnown instead.
   181  type ErrQueryFailed struct {
   182  	Provider addrs.Provider
   183  	Wrapped  error
   184  
   185  	// MirrorURL, if non-nil, is the base URL of the mirror that serviced
   186  	// the request in place of the provider's origin registry. MirrorURL
   187  	// is nil for a direct query.
   188  	MirrorURL *url.URL
   189  }
   190  
   191  func (err ErrQueryFailed) Error() string {
   192  	if err.MirrorURL != nil {
   193  		return fmt.Sprintf(
   194  			"failed to query provider mirror %s for %s: %s",
   195  			err.MirrorURL.String(),
   196  			err.Provider.String(),
   197  			err.Wrapped.Error(),
   198  		)
   199  	}
   200  	return fmt.Sprintf(
   201  		"could not query provider registry for %s: %s",
   202  		err.Provider.String(),
   203  		err.Wrapped.Error(),
   204  	)
   205  }
   206  
   207  // Unwrap returns the underlying error that occurred when trying to reach the
   208  // indicated host.
   209  func (err ErrQueryFailed) Unwrap() error {
   210  	return err.Wrapped
   211  }
   212  
   213  // ErrRequestCancelled is an error type used to indicate that an operation
   214  // failed due to being cancelled via the given context.Context object.
   215  //
   216  // This error type doesn't include information about what was cancelled,
   217  // because the expected treatment of this error type is to quickly abort and
   218  // exit with minimal ceremony.
   219  type ErrRequestCanceled struct {
   220  }
   221  
   222  func (err ErrRequestCanceled) Error() string {
   223  	return "request canceled"
   224  }
   225  
   226  // ErrIsNotExist returns true if and only if the given error is one of the
   227  // errors from this package that represents an affirmative response that a
   228  // requested object does not exist.
   229  //
   230  // This is as opposed to errors indicating that the source is unavailable
   231  // or misconfigured in some way, where we therefore cannot say for certain
   232  // whether the requested object exists.
   233  //
   234  // If a caller needs to take a special action based on something not existing,
   235  // such as falling back on some other source, use this function rather than
   236  // direct type assertions so that the set of possible "not exist" errors can
   237  // grow in future.
   238  func ErrIsNotExist(err error) bool {
   239  	switch err.(type) {
   240  	case ErrProviderNotFound, ErrRegistryProviderNotKnown, ErrPlatformNotSupported:
   241  		return true
   242  	default:
   243  		return false
   244  	}
   245  }