Skip to content

Commit 8d307aa

Browse files
committed
🎂
0 parents  commit 8d307aa

File tree

11 files changed

+625
-0
lines changed

11 files changed

+625
-0
lines changed

go.mod

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module github.com/terraform-linters/tflint-plugin-sdk
2+
3+
go 1.13
4+
5+
require (
6+
github.com/hashicorp/go-hclog v0.10.1
7+
github.com/hashicorp/go-plugin v1.0.1
8+
github.com/hashicorp/hcl/v2 v2.0.0
9+
github.com/zclconf/go-cty v1.1.0
10+
)

go.sum

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8=
2+
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
3+
github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM=
4+
github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0=
5+
github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
6+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
7+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
8+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9+
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
10+
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
11+
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
12+
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
13+
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
14+
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
15+
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
16+
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
17+
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
18+
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
19+
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
20+
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
21+
github.com/hashicorp/go-hclog v0.10.1 h1:uyt/l0dWjJ879yiAu+T7FG3/6QX+zwm4bQ8P7XsYt3o=
22+
github.com/hashicorp/go-hclog v0.10.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
23+
github.com/hashicorp/go-plugin v1.0.1 h1:4OtAfUGbnKC6yS48p0CtMX2oFYtzFZVv6rok3cRWgnE=
24+
github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY=
25+
github.com/hashicorp/hcl/v2 v2.0.0 h1:efQznTz+ydmQXq3BOnRa3AXzvCeTq1P4dKj/z5GLlY8=
26+
github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90=
27+
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M=
28+
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
29+
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
30+
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
31+
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
32+
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
33+
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
34+
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4=
35+
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
36+
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
37+
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
38+
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
39+
github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
40+
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
41+
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 h1:7GoSOOW2jpsfkntVKaS2rAr1TJqfcxotyaUcuxoZSzg=
42+
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
43+
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
44+
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
45+
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
46+
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
47+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
48+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
49+
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
50+
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
51+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
52+
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
53+
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
54+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
55+
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
56+
github.com/zclconf/go-cty v1.1.0 h1:uJwc9HiBOCpoKIObTQaLR+tsEXx1HBHnOsOOpcdhZgw=
57+
github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s=
58+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
59+
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
60+
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
61+
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
62+
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
63+
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
64+
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
65+
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
66+
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
67+
golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
68+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
69+
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
70+
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
71+
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
72+
golang.org/x/sys v0.0.0-20191008105621-543471e840be h1:QAcqgptGM8IQBC9K/RC4o+O9YmqEm0diQn9QmZw/0mU=
73+
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
74+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
75+
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
76+
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
77+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
78+
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
79+
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
80+
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
81+
google.golang.org/grpc v1.14.0 h1:ArxJuB1NWfPY6r9Gp9gqwplT0Ge7nqv9msgu03lHLmo=
82+
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
83+
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

plugin/client.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package plugin
2+
3+
import (
4+
"net/rpc"
5+
"os"
6+
"os/exec"
7+
8+
"github.com/hashicorp/go-hclog"
9+
plugin "github.com/hashicorp/go-plugin"
10+
"github.com/terraform-linters/tflint-plugin-sdk/tflint"
11+
)
12+
13+
// Client is an RPC client for use by the host
14+
type Client struct {
15+
rpcClient *rpc.Client
16+
broker *plugin.MuxBroker
17+
}
18+
19+
// ClientOpts is an option for initializing the RPC client
20+
type ClientOpts struct {
21+
Cmd *exec.Cmd
22+
}
23+
24+
// NewClient is a wrapper of plugin.NewClient
25+
func NewClient(opts *ClientOpts) *plugin.Client {
26+
return plugin.NewClient(&plugin.ClientConfig{
27+
HandshakeConfig: handshakeConfig,
28+
Plugins: map[string]plugin.Plugin{
29+
"ruleset": &RuleSetPlugin{},
30+
},
31+
Cmd: opts.Cmd,
32+
Logger: hclog.New(&hclog.LoggerOptions{
33+
Name: "plugin",
34+
Output: os.Stderr,
35+
Level: hclog.LevelFromString(os.Getenv("TFLINT_LOG")),
36+
}),
37+
})
38+
}
39+
40+
// RuleSetName queries the RPC server for RuleSetName
41+
func (c *Client) RuleSetName() (string, error) {
42+
var resp string
43+
err := c.rpcClient.Call("Plugin.RuleSetName", new(interface{}), &resp)
44+
return resp, err
45+
}
46+
47+
// RuleSetVersion queries the RPC server for RuleSetVersion
48+
func (c *Client) RuleSetVersion() (string, error) {
49+
var resp string
50+
err := c.rpcClient.Call("Plugin.RuleSetVersion", new(interface{}), &resp)
51+
return resp, err
52+
}
53+
54+
// RuleNames queries the RPC server for RuleNames
55+
func (c *Client) RuleNames() ([]string, error) {
56+
var resp []string
57+
err := c.rpcClient.Call("Plugin.RuleNames", new(interface{}), &resp)
58+
return resp, err
59+
}
60+
61+
// ApplyConfig queries the RPC server for ApplyConfig
62+
func (c *Client) ApplyConfig(config *tflint.Config) error {
63+
return c.rpcClient.Call("Plugin.ApplyConfig", config, new(interface{}))
64+
}
65+
66+
// Check queries the RPC server for Check
67+
// For bi-directional communication, you can pass a server that accepts Runner's queries
68+
func (c *Client) Check(server tflint.Server) error {
69+
brokerID := c.broker.NextId()
70+
go c.broker.AcceptAndServe(brokerID, server)
71+
72+
return c.rpcClient.Call("Plugin.Check", brokerID, new(interface{}))
73+
}

plugin/plugin.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package plugin
2+
3+
import (
4+
"encoding/gob"
5+
"net/rpc"
6+
7+
plugin "github.com/hashicorp/go-plugin"
8+
"github.com/hashicorp/hcl/v2"
9+
"github.com/hashicorp/hcl/v2/hclsyntax"
10+
"github.com/terraform-linters/tflint-plugin-sdk/tflint"
11+
)
12+
13+
// handShakeConfig is used for UX. ProcotolVersion will be updated by incompatible changes
14+
var handshakeConfig = plugin.HandshakeConfig{
15+
ProtocolVersion: 1,
16+
MagicCookieKey: "TFLINT_RULESET_PLUGIN",
17+
MagicCookieValue: "5adSn1bX8nrDfgBqiAqqEkC6OE1h3iD8SqbMc5UUONx8x3xCF0KlPDsBRNDjoYDP",
18+
}
19+
20+
// RuleSetPlugin is a wrapper to satisfy the interface of go-plugin
21+
type RuleSetPlugin struct {
22+
impl tflint.RuleSet
23+
}
24+
25+
// Server returns an RPC server acting as a plugin
26+
func (p *RuleSetPlugin) Server(b *plugin.MuxBroker) (interface{}, error) {
27+
return &Server{impl: p.impl, broker: b}, nil
28+
}
29+
30+
// Client returns an RPC client for use by the host
31+
func (RuleSetPlugin) Client(b *plugin.MuxBroker, c *rpc.Client) (interface{}, error) {
32+
return &Client{rpcClient: c, broker: b}, nil
33+
}
34+
35+
// In order to communicate the interface correctly with RPC,
36+
// the type of the related structure is registered in gob at the initial time.
37+
func init() {
38+
gob.Register(&hclsyntax.TemplateExpr{})
39+
gob.Register(&hclsyntax.LiteralValueExpr{})
40+
gob.Register(&hclsyntax.ScopeTraversalExpr{})
41+
gob.Register(hcl.TraverseRoot{})
42+
gob.Register(hcl.TraverseAttr{})
43+
}

plugin/server.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package plugin
2+
3+
import (
4+
plugin "github.com/hashicorp/go-plugin"
5+
"github.com/terraform-linters/tflint-plugin-sdk/tflint"
6+
)
7+
8+
// Server is an RPC server acting as a plugin
9+
type Server struct {
10+
impl tflint.RuleSet
11+
broker *plugin.MuxBroker
12+
}
13+
14+
// ServeOpts is an option for serving a plugin
15+
// Each plugin can pass a RuleSet that represents its own functionality
16+
type ServeOpts struct {
17+
RuleSet tflint.RuleSet
18+
}
19+
20+
// Serve is a wrapper of plugin.Serve. This is entrypoint of all plugins
21+
func Serve(opts *ServeOpts) {
22+
plugin.Serve(&plugin.ServeConfig{
23+
HandshakeConfig: handshakeConfig,
24+
Plugins: map[string]plugin.Plugin{
25+
"ruleset": &RuleSetPlugin{impl: opts.RuleSet},
26+
},
27+
})
28+
}
29+
30+
// RuleSetName replies its own the result of RuleSetName
31+
func (s *Server) RuleSetName(args interface{}, resp *string) error {
32+
*resp = s.impl.RuleSetName()
33+
return nil
34+
}
35+
36+
// RuleSetVersion replies its own the result of RuleSetVersion
37+
func (s *Server) RuleSetVersion(args interface{}, resp *string) error {
38+
*resp = s.impl.RuleSetVersion()
39+
return nil
40+
}
41+
42+
// RuleNames replies its own the result of RuleNames
43+
func (s *Server) RuleNames(args interface{}, resp *[]string) error {
44+
*resp = s.impl.RuleNames()
45+
return nil
46+
}
47+
48+
// ApplyConfig applies the passed config to its own plugin implementation
49+
func (s *Server) ApplyConfig(config *tflint.Config, resp *interface{}) error {
50+
s.impl.ApplyConfig(config)
51+
return nil
52+
}
53+
54+
// Check initializes an RPC client that can query to the host process and pass it to the Check method
55+
func (s *Server) Check(brokerID uint32, resp *interface{}) error {
56+
conn, err := s.broker.Dial(brokerID)
57+
if err != nil {
58+
return err
59+
}
60+
61+
return s.impl.Check(tflint.NewClient(conn))
62+
}

0 commit comments

Comments
 (0)