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 }