github.com/myhau/pulumi/pkg/v3@v3.70.2-0.20221116134521-f2775972e587/resource/deploy/providers/provider.go (about) 1 // Copyright 2016-2021, Pulumi Corporation. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package providers 16 17 import ( 18 "fmt" 19 "strings" 20 21 "github.com/blang/semver" 22 23 "github.com/pulumi/pulumi/sdk/v3/go/common/tokens" 24 "github.com/pulumi/pulumi/sdk/v3/go/common/util/contract" 25 ) 26 27 // A ProviderRequest is a tuple of an optional semantic version, download server url and a package name. Whenever 28 // the engine receives a registration for a resource that doesn't explicitly specify a provider, the engine creates 29 // a ProviderRequest for that resource's provider, using the version passed to the engine as part of RegisterResource 30 // and the package derived from the resource's token. 31 // 32 // The source evaluator (source_eval.go) is responsible for servicing provider requests. It does this by interpreting 33 // these provider requests and sending resource registrations to the engine for the providers themselves. These are 34 // called "default providers". 35 // 36 // ProviderRequest is useful as a hash key. The engine is free to instantiate any number of provider requests, but it 37 // is free to cache requests for a provider request that is equal to one that has already been serviced. If you do use 38 // ProviderRequest as a hash key, you should call String() to get a usable key for string-based hash maps. 39 type ProviderRequest struct { 40 version *semver.Version 41 pkg tokens.Package 42 pluginDownloadURL string 43 } 44 45 // NewProviderRequest constructs a new provider request from an optional version, optional 46 // pluginDownloadURL and package. 47 func NewProviderRequest(version *semver.Version, pkg tokens.Package, pluginDownloadURL string) ProviderRequest { 48 return ProviderRequest{ 49 version: version, 50 pkg: pkg, 51 pluginDownloadURL: strings.TrimSuffix(pluginDownloadURL, "/"), 52 } 53 } 54 55 // Version returns this provider request's version. May be nil if no version was provided. 56 func (p ProviderRequest) Version() *semver.Version { 57 return p.version 58 } 59 60 // Package returns this provider request's package. 61 func (p ProviderRequest) Package() tokens.Package { 62 return p.pkg 63 } 64 65 // PluginDownloadURL returns this providers server url. May be "" if no pluginDownloadURL was 66 // provided. 67 func (p ProviderRequest) PluginDownloadURL() string { 68 return p.pluginDownloadURL 69 } 70 71 // Name returns a QName that is an appropriate name for a default provider constructed from this provider request. The 72 // name is intended to be unique; as such, the name is derived from the version associated with this request. 73 // 74 // If a version is not provided, "default" is returned. Otherwise, Name returns a name starting with "default" and 75 // followed by a QName-legal representation of the semantic version of the requested provider. 76 func (p ProviderRequest) Name() tokens.QName { 77 base := "default" 78 if v := p.version; v != nil { 79 // QNames are forbidden to contain dashes, so we construct a string here using the semantic 80 // version's component parts. 81 base += fmt.Sprintf("_%d_%d_%d", v.Major, v.Minor, v.Patch) 82 for _, pre := range v.Pre { 83 base += "_" + pre.String() 84 } 85 for _, build := range v.Build { 86 base += "_" + build 87 } 88 } 89 90 if url := p.pluginDownloadURL; url != "" { 91 base += "_" + tokens.IntoQName(url).String() 92 } 93 94 // This thing that we generated must be a QName. 95 contract.Assert(tokens.IsQName(base)) 96 return tokens.QName(base) 97 } 98 99 // String returns a string representation of this request. This string is suitable for use as a hash key. 100 func (p ProviderRequest) String() string { 101 var version string 102 if p.version != nil { 103 version = "-" + p.version.String() 104 } 105 var url string 106 if p.pluginDownloadURL != "" { 107 url = "-" + p.pluginDownloadURL 108 } 109 return p.pkg.String() + version + url 110 }