2019-07-02 03:37:00 +02:00
|
|
|
package provider
|
2019-06-27 00:27:39 +02:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
|
2019-07-02 15:03:13 +02:00
|
|
|
"github.com/hashicorp/hcl2/hclwrite"
|
2019-07-02 00:13:58 +02:00
|
|
|
"github.com/hashicorp/terraform/plugin/discovery"
|
2019-06-27 00:27:39 +02:00
|
|
|
|
|
|
|
"github.com/hashicorp/terraform/plugin"
|
|
|
|
"github.com/hashicorp/terraform/providers"
|
|
|
|
"go.starlark.net/starlark"
|
|
|
|
)
|
|
|
|
|
2019-07-03 01:05:35 +02:00
|
|
|
type Provider struct {
|
2019-06-27 00:27:39 +02:00
|
|
|
name string
|
|
|
|
provider *plugin.GRPCProvider
|
2019-07-02 00:13:58 +02:00
|
|
|
meta discovery.PluginMeta
|
2019-06-27 00:27:39 +02:00
|
|
|
|
2019-07-03 01:05:35 +02:00
|
|
|
dataSources *MapSchema
|
|
|
|
resources *MapSchema
|
2019-06-27 00:27:39 +02:00
|
|
|
}
|
|
|
|
|
2019-07-03 01:05:35 +02:00
|
|
|
func MakeProvider(pm *PluginManager, name, version string) (*Provider, error) {
|
2019-07-02 00:13:58 +02:00
|
|
|
cli, meta := pm.Get(name, version)
|
2019-06-27 00:27:39 +02:00
|
|
|
rpc, err := cli.Client()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
raw, err := rpc.Dispense(plugin.ProviderPluginName)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
provider := raw.(*plugin.GRPCProvider)
|
|
|
|
response := provider.GetSchema()
|
|
|
|
|
|
|
|
defer cli.Kill()
|
2019-07-03 01:05:35 +02:00
|
|
|
return &Provider{
|
2019-06-27 00:27:39 +02:00
|
|
|
name: name,
|
|
|
|
provider: provider,
|
2019-07-02 00:13:58 +02:00
|
|
|
meta: meta,
|
2019-07-03 01:05:35 +02:00
|
|
|
dataSources: NewMapSchema(name, response.DataSources),
|
|
|
|
resources: NewMapSchema(name, response.ResourceTypes),
|
2019-06-27 00:27:39 +02:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2019-07-03 01:05:35 +02:00
|
|
|
func (p *Provider) String() string {
|
|
|
|
return fmt.Sprintf("provider(%q)", p.name)
|
2019-06-27 00:27:39 +02:00
|
|
|
}
|
|
|
|
|
2019-07-03 01:05:35 +02:00
|
|
|
func (p *Provider) Type() string {
|
2019-06-27 00:27:39 +02:00
|
|
|
return "provider-instance"
|
|
|
|
}
|
|
|
|
|
2019-07-03 01:05:35 +02:00
|
|
|
func (p *Provider) Freeze() {}
|
|
|
|
func (p *Provider) Truth() starlark.Bool { return true }
|
|
|
|
func (p *Provider) Hash() (uint32, error) { return 1, nil }
|
|
|
|
func (p *Provider) Name() string { return p.name }
|
|
|
|
func (p *Provider) Attr(name string) (starlark.Value, error) {
|
2019-06-27 09:48:37 +02:00
|
|
|
switch name {
|
2019-07-02 00:13:58 +02:00
|
|
|
case "version":
|
2019-07-03 01:05:35 +02:00
|
|
|
return starlark.String(p.meta.Version), nil
|
2019-06-27 09:48:37 +02:00
|
|
|
case "data":
|
2019-07-03 01:05:35 +02:00
|
|
|
return p.dataSources, nil
|
2019-06-27 09:48:37 +02:00
|
|
|
case "resource":
|
2019-07-03 01:05:35 +02:00
|
|
|
return p.resources, nil
|
2019-07-02 15:03:13 +02:00
|
|
|
case "to_hcl":
|
2019-07-03 01:05:35 +02:00
|
|
|
return BuiltinToHCL(p, hclwrite.NewEmptyFile()), nil
|
2019-06-27 09:48:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return starlark.None, nil
|
|
|
|
}
|
|
|
|
|
2019-07-03 01:05:35 +02:00
|
|
|
func (p *Provider) AttrNames() []string {
|
2019-06-27 09:48:37 +02:00
|
|
|
return []string{"data", "resource"}
|
|
|
|
}
|
|
|
|
|
2019-07-03 01:05:35 +02:00
|
|
|
type MapSchema struct {
|
2019-07-02 03:37:00 +02:00
|
|
|
prefix string
|
|
|
|
schemas map[string]providers.Schema
|
|
|
|
collections map[string]*ResourceCollection
|
2019-06-27 09:48:37 +02:00
|
|
|
}
|
|
|
|
|
2019-07-03 01:05:35 +02:00
|
|
|
func NewMapSchema(prefix string, schemas map[string]providers.Schema) *MapSchema {
|
|
|
|
return &MapSchema{
|
2019-07-02 03:37:00 +02:00
|
|
|
prefix: prefix,
|
|
|
|
schemas: schemas,
|
|
|
|
collections: make(map[string]*ResourceCollection),
|
|
|
|
}
|
2019-06-27 09:48:37 +02:00
|
|
|
}
|
2019-06-27 00:27:39 +02:00
|
|
|
|
2019-07-03 01:05:35 +02:00
|
|
|
func (m *MapSchema) String() string {
|
|
|
|
return fmt.Sprintf("schemas(%q)", m.prefix)
|
2019-06-27 09:48:37 +02:00
|
|
|
}
|
|
|
|
|
2019-07-03 01:05:35 +02:00
|
|
|
func (m *MapSchema) Type() string {
|
2019-06-27 09:48:37 +02:00
|
|
|
return "schemas"
|
|
|
|
}
|
|
|
|
|
2019-07-03 01:05:35 +02:00
|
|
|
func (m *MapSchema) Freeze() {}
|
|
|
|
func (m *MapSchema) Truth() starlark.Bool { return true }
|
|
|
|
func (m *MapSchema) Hash() (uint32, error) { return 1, nil }
|
|
|
|
func (m *MapSchema) Name() string { return m.prefix }
|
2019-06-27 09:48:37 +02:00
|
|
|
|
2019-07-03 01:05:35 +02:00
|
|
|
func (m *MapSchema) Attr(name string) (starlark.Value, error) {
|
2019-07-02 15:03:13 +02:00
|
|
|
if name == "to_hcl" {
|
2019-07-03 01:05:35 +02:00
|
|
|
return BuiltinToHCL(m, hclwrite.NewEmptyFile()), nil
|
2019-07-02 15:03:13 +02:00
|
|
|
}
|
|
|
|
|
2019-07-03 01:05:35 +02:00
|
|
|
name = m.prefix + "_" + name
|
2019-06-27 09:48:37 +02:00
|
|
|
|
2019-07-03 01:05:35 +02:00
|
|
|
if c, ok := m.collections[name]; ok {
|
2019-07-02 03:37:00 +02:00
|
|
|
return c, nil
|
|
|
|
}
|
|
|
|
|
2019-07-03 01:05:35 +02:00
|
|
|
if schema, ok := m.schemas[name]; ok {
|
|
|
|
m.collections[name] = NewResourceCollection(name, false, schema.Block)
|
|
|
|
return m.collections[name], nil
|
2019-06-27 00:27:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return starlark.None, nil
|
|
|
|
}
|
|
|
|
|
2019-07-03 01:05:35 +02:00
|
|
|
func (s *MapSchema) AttrNames() []string {
|
2019-06-27 09:48:37 +02:00
|
|
|
names := make([]string, len(s.schemas))
|
2019-06-27 00:27:39 +02:00
|
|
|
|
|
|
|
var i int
|
2019-06-27 09:48:37 +02:00
|
|
|
for k := range s.schemas {
|
2019-06-27 00:27:39 +02:00
|
|
|
parts := strings.SplitN(k, "_", 2)
|
|
|
|
names[i] = parts[1]
|
|
|
|
i++
|
|
|
|
}
|
|
|
|
|
|
|
|
return names
|
|
|
|
}
|