diff options
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/helper/plugin/grpc_provisioner.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/helper/plugin/grpc_provisioner.go | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/helper/plugin/grpc_provisioner.go b/vendor/github.com/hashicorp/terraform/helper/plugin/grpc_provisioner.go new file mode 100644 index 0000000..14494e4 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/helper/plugin/grpc_provisioner.go | |||
@@ -0,0 +1,147 @@ | |||
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 | } | ||