123 lines
4.2 KiB
Go
123 lines
4.2 KiB
Go
// Copyright 2016-2018, Pulumi Corporation.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package providers
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/pulumi/pulumi/sdk/go/common/resource"
|
|
"github.com/pulumi/pulumi/pkg/resource/plugin"
|
|
"github.com/pulumi/pulumi/pkg/tokens"
|
|
"github.com/pulumi/pulumi/pkg/util/contract"
|
|
)
|
|
|
|
// A provider reference is (URN, ID) tuple that refers to a particular provider instance. A provider reference's
|
|
// string representation is <URN> "::" <ID>. The URN's type portion must be of the form "pulumi:providers:<pkg>".
|
|
|
|
// UnknownID is a distinguished token used to indicate that a provider's ID is not known (e.g. because we are
|
|
// performing a preview).
|
|
const UnknownID = plugin.UnknownStringValue
|
|
|
|
// IsProviderType returns true if the supplied type token refers to a Pulumi provider.
|
|
func IsProviderType(typ tokens.Type) bool {
|
|
// Tokens without a module member are definitely not provider types.
|
|
if !tokens.Token(typ).HasModuleMember() {
|
|
return false
|
|
}
|
|
return typ.Module() == "pulumi:providers" && typ.Name() != ""
|
|
}
|
|
|
|
// IsDefaultProvider returns true if this URN refers to a default Pulumi provider.
|
|
func IsDefaultProvider(urn resource.URN) bool {
|
|
return IsProviderType(urn.Type()) && strings.HasPrefix(urn.Name().String(), "default")
|
|
}
|
|
|
|
// MakeProviderType returns the provider type token for the given package.
|
|
func MakeProviderType(pkg tokens.Package) tokens.Type {
|
|
return tokens.Type("pulumi:providers:" + pkg)
|
|
}
|
|
|
|
// GetProviderPackage returns the provider package for the given type token.
|
|
func GetProviderPackage(typ tokens.Type) tokens.Package {
|
|
contract.Require(IsProviderType(typ), "typ")
|
|
return tokens.Package(typ.Name())
|
|
}
|
|
|
|
func validateURN(urn resource.URN) error {
|
|
if !urn.IsValid() {
|
|
return errors.Errorf("%s is not a valid URN", urn)
|
|
}
|
|
typ := urn.Type()
|
|
if typ.Module() != "pulumi:providers" {
|
|
return errors.Errorf("invalid module in type: expected 'pulumi:providers', got '%v'", typ.Module())
|
|
}
|
|
if typ.Name() == "" {
|
|
return errors.New("provider URNs must specify a type name")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Reference represents a reference to a particular provider.
|
|
type Reference struct {
|
|
urn resource.URN
|
|
id resource.ID
|
|
}
|
|
|
|
// URN returns the provider reference's URN.
|
|
func (r Reference) URN() resource.URN {
|
|
return r.urn
|
|
}
|
|
|
|
// ID returns the provider reference's ID.
|
|
func (r Reference) ID() resource.ID {
|
|
return r.id
|
|
}
|
|
|
|
// String returns the string representation of this provider reference.
|
|
func (r Reference) String() string {
|
|
return string(r.urn) + resource.URNNameDelimiter + string(r.id)
|
|
}
|
|
|
|
// NewReference creates a new reference for the given URN and ID.
|
|
func NewReference(urn resource.URN, id resource.ID) (Reference, error) {
|
|
if err := validateURN(urn); err != nil {
|
|
return Reference{}, err
|
|
}
|
|
return Reference{urn: urn, id: id}, nil
|
|
}
|
|
|
|
func mustNewReference(urn resource.URN, id resource.ID) Reference {
|
|
ref, err := NewReference(urn, id)
|
|
contract.Assert(err == nil)
|
|
return ref
|
|
}
|
|
|
|
// ParseReference parses the URN and ID from the string representation of a provider reference. If parsing was
|
|
// not possible, this function returns false.
|
|
func ParseReference(s string) (Reference, error) {
|
|
// If this is not a valid URN + ID, return false. Note that we don't try terribly hard to validate the URN portion
|
|
// of the reference.
|
|
lastSep := strings.LastIndex(s, resource.URNNameDelimiter)
|
|
if lastSep == -1 {
|
|
return Reference{}, errors.Errorf("expected '%v' in provider reference '%v'", resource.URNNameDelimiter, s)
|
|
}
|
|
urn, id := resource.URN(s[:lastSep]), resource.ID(s[lastSep+len(resource.URNNameDelimiter):])
|
|
if err := validateURN(urn); err != nil {
|
|
return Reference{}, err
|
|
}
|
|
return Reference{urn: urn, id: id}, nil
|
|
}
|