]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/helper/plugin/grpc_provisioner.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / helper / plugin / grpc_provisioner.go
1 package plugin
2
3 import (
4 "log"
5
6 "github.com/hashicorp/terraform/helper/schema"
7 proto "github.com/hashicorp/terraform/internal/tfplugin5"
8 "github.com/hashicorp/terraform/plugin/convert"
9 "github.com/hashicorp/terraform/terraform"
10 "github.com/zclconf/go-cty/cty"
11 ctyconvert "github.com/zclconf/go-cty/cty/convert"
12 "github.com/zclconf/go-cty/cty/msgpack"
13 context "golang.org/x/net/context"
14 )
15
16 // NewGRPCProvisionerServerShim wraps a terraform.ResourceProvisioner in a
17 // proto.ProvisionerServer implementation. If the provided provisioner is not a
18 // *schema.Provisioner, this will return nil,
19 func NewGRPCProvisionerServerShim(p terraform.ResourceProvisioner) *GRPCProvisionerServer {
20 sp, ok := p.(*schema.Provisioner)
21 if !ok {
22 return nil
23 }
24 return &GRPCProvisionerServer{
25 provisioner: sp,
26 }
27 }
28
29 type GRPCProvisionerServer struct {
30 provisioner *schema.Provisioner
31 }
32
33 func (s *GRPCProvisionerServer) GetSchema(_ context.Context, req *proto.GetProvisionerSchema_Request) (*proto.GetProvisionerSchema_Response, error) {
34 resp := &proto.GetProvisionerSchema_Response{}
35
36 resp.Provisioner = &proto.Schema{
37 Block: convert.ConfigSchemaToProto(schema.InternalMap(s.provisioner.Schema).CoreConfigSchema()),
38 }
39
40 return resp, nil
41 }
42
43 func (s *GRPCProvisionerServer) ValidateProvisionerConfig(_ context.Context, req *proto.ValidateProvisionerConfig_Request) (*proto.ValidateProvisionerConfig_Response, error) {
44 resp := &proto.ValidateProvisionerConfig_Response{}
45
46 cfgSchema := schema.InternalMap(s.provisioner.Schema).CoreConfigSchema()
47
48 configVal, err := msgpack.Unmarshal(req.Config.Msgpack, cfgSchema.ImpliedType())
49 if err != nil {
50 resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
51 return resp, nil
52 }
53
54 config := terraform.NewResourceConfigShimmed(configVal, cfgSchema)
55
56 warns, errs := s.provisioner.Validate(config)
57 resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, convert.WarnsAndErrsToProto(warns, errs))
58
59 return resp, nil
60 }
61
62 // stringMapFromValue converts a cty.Value to a map[stirng]string.
63 // This will panic if the val is not a cty.Map(cty.String).
64 func stringMapFromValue(val cty.Value) map[string]string {
65 m := map[string]string{}
66 if val.IsNull() || !val.IsKnown() {
67 return m
68 }
69
70 for it := val.ElementIterator(); it.Next(); {
71 ak, av := it.Element()
72 name := ak.AsString()
73
74 if !av.IsKnown() || av.IsNull() {
75 continue
76 }
77
78 av, _ = ctyconvert.Convert(av, cty.String)
79 m[name] = av.AsString()
80 }
81
82 return m
83 }
84
85 // uiOutput implements the terraform.UIOutput interface to adapt the grpc
86 // stream to the legacy Provisioner.Apply method.
87 type uiOutput struct {
88 srv proto.Provisioner_ProvisionResourceServer
89 }
90
91 func (o uiOutput) Output(s string) {
92 err := o.srv.Send(&proto.ProvisionResource_Response{
93 Output: s,
94 })
95 if err != nil {
96 log.Printf("[ERROR] %s", err)
97 }
98 }
99
100 func (s *GRPCProvisionerServer) ProvisionResource(req *proto.ProvisionResource_Request, srv proto.Provisioner_ProvisionResourceServer) error {
101 // We send back a diagnostics over the stream if there was a
102 // provisioner-side problem.
103 srvResp := &proto.ProvisionResource_Response{}
104
105 cfgSchema := schema.InternalMap(s.provisioner.Schema).CoreConfigSchema()
106 cfgVal, err := msgpack.Unmarshal(req.Config.Msgpack, cfgSchema.ImpliedType())
107 if err != nil {
108 srvResp.Diagnostics = convert.AppendProtoDiag(srvResp.Diagnostics, err)
109 srv.Send(srvResp)
110 return nil
111 }
112 resourceConfig := terraform.NewResourceConfigShimmed(cfgVal, cfgSchema)
113
114 connVal, err := msgpack.Unmarshal(req.Connection.Msgpack, cty.Map(cty.String))
115 if err != nil {
116 srvResp.Diagnostics = convert.AppendProtoDiag(srvResp.Diagnostics, err)
117 srv.Send(srvResp)
118 return nil
119 }
120
121 conn := stringMapFromValue(connVal)
122
123 instanceState := &terraform.InstanceState{
124 Ephemeral: terraform.EphemeralState{
125 ConnInfo: conn,
126 },
127 Meta: make(map[string]interface{}),
128 }
129
130 err = s.provisioner.Apply(uiOutput{srv}, instanceState, resourceConfig)
131 if err != nil {
132 srvResp.Diagnostics = convert.AppendProtoDiag(srvResp.Diagnostics, err)
133 srv.Send(srvResp)
134 }
135 return nil
136 }
137
138 func (s *GRPCProvisionerServer) Stop(_ context.Context, req *proto.Stop_Request) (*proto.Stop_Response, error) {
139 resp := &proto.Stop_Response{}
140
141 err := s.provisioner.Stop()
142 if err != nil {
143 resp.Error = err.Error()
144 }
145
146 return resp, nil
147 }