Skip to content

Commit 7fd8da9

Browse files
committed
feat: added plugin support with go-plugin
- initially implemented Output plugin - has a sample plugin in `examples/plugin`
1 parent 8eb364a commit 7fd8da9

File tree

6 files changed

+213
-3
lines changed

6 files changed

+213
-3
lines changed

cmd/plugin.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package cmd
2+
3+
import (
4+
"github.com/salsadigitalauorg/shipshape/pkg/plugin"
5+
"github.com/spf13/cobra"
6+
)
7+
8+
var pluginCmd = &cobra.Command{
9+
Use: "plugin",
10+
Short: "Manage shipshape plugins",
11+
Run: func(cmd *cobra.Command, args []string) {
12+
plugin.Run()
13+
},
14+
}
15+
16+
func init() {
17+
rootCmd.AddCommand(pluginCmd)
18+
}

examples/plugin/sample.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"os"
7+
8+
"github.com/hashicorp/go-hclog"
9+
"github.com/hashicorp/go-plugin"
10+
"github.com/salsadigitalauorg/shipshape/pkg/output"
11+
shipshape_plugin "github.com/salsadigitalauorg/shipshape/pkg/plugin"
12+
"github.com/salsadigitalauorg/shipshape/pkg/result"
13+
)
14+
15+
type SampleOutput struct {
16+
logger hclog.Logger
17+
}
18+
19+
func (o *SampleOutput) Output(rl *result.ResultList) ([]byte, error) {
20+
o.logger.Debug("message from SampleOutput.Output")
21+
b := bytes.Buffer{}
22+
fmt.Fprintln(&b, "ResultList:", *rl)
23+
return b.Bytes(), nil
24+
}
25+
26+
func main() {
27+
logger := hclog.New(&hclog.LoggerOptions{
28+
Level: hclog.Trace,
29+
Output: os.Stderr,
30+
JSONFormat: true,
31+
})
32+
33+
outputter := &SampleOutput{
34+
logger: logger,
35+
}
36+
// pluginMap is the map of plugins we can dispense.
37+
var pluginMap = map[string]plugin.Plugin{
38+
"outputter": &output.OutputterPlugin{Impl: outputter},
39+
}
40+
41+
logger.Debug("message from plugin", "foo", "bar")
42+
43+
plugin.Serve(&plugin.ServeConfig{
44+
HandshakeConfig: shipshape_plugin.Handshake,
45+
Plugins: pluginMap,
46+
})
47+
}

go.mod

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ require (
1010
github.com/go-sql-driver/mysql v1.6.0
1111
github.com/goccy/go-json v0.10.2
1212
github.com/gocolly/colly v1.2.0
13+
github.com/hashicorp/go-plugin v1.6.1
1314
github.com/hashicorp/go-version v1.6.0
1415
github.com/hasura/go-graphql-client v0.9.2
1516
github.com/jmespath/go-jmespath v0.4.0
@@ -22,7 +23,7 @@ require (
2223
github.com/spf13/cobra v1.8.0
2324
github.com/stretchr/testify v1.9.0
2425
github.com/vmware-labs/yaml-jsonpath v0.3.2
25-
golang.org/x/oauth2 v0.6.0
26+
golang.org/x/oauth2 v0.11.0
2627
gopkg.in/yaml.v3 v3.0.1
2728
)
2829

@@ -36,18 +37,25 @@ require (
3637
github.com/davecgh/go-spew v1.1.1 // indirect
3738
github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960 // indirect
3839
github.com/dustin/go-humanize v1.0.1 // indirect
40+
github.com/fatih/color v1.7.0 // indirect
3941
github.com/go-playground/validator/v10 v10.4.1 // indirect
4042
github.com/gobwas/glob v0.2.3 // indirect
4143
github.com/gogo/protobuf v1.3.2 // indirect
4244
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
4345
github.com/golang/protobuf v1.5.4 // indirect
4446
github.com/google/uuid v1.6.0 // indirect
47+
github.com/hashicorp/go-hclog v0.14.1 // indirect
48+
github.com/hashicorp/yamux v0.1.1 // indirect
4549
github.com/inconshreveable/mousetrap v1.1.0 // indirect
4650
github.com/json-iterator/go v1.1.12 // indirect
4751
github.com/kennygrant/sanitize v1.2.4 // indirect
4852
github.com/klauspost/compress v1.17.9 // indirect
53+
github.com/mattn/go-colorable v0.1.4 // indirect
54+
github.com/mattn/go-isatty v0.0.12 // indirect
55+
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 // indirect
4956
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
5057
github.com/modern-go/reflect2 v1.0.2 // indirect
58+
github.com/oklog/run v1.0.0 // indirect
5159
github.com/pkg/errors v0.9.1 // indirect
5260
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect
5361
github.com/spf13/pflag v1.0.5 // indirect
@@ -57,6 +65,8 @@ require (
5765
golang.org/x/sys v0.22.0 // indirect
5866
golang.org/x/text v0.15.0 // indirect
5967
google.golang.org/appengine v1.6.7 // indirect
68+
google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b // indirect
69+
google.golang.org/grpc v1.59.0 // indirect
6070
google.golang.org/protobuf v1.33.0 // indirect
6171
nhooyr.io/websocket v1.8.7 // indirect
6272
)

go.sum

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ github.com/antchfx/xmlquery v1.3.11 h1:8aRK7l3+dJjL8ZmwgVzG5AXysrP7Mss2424tfntKW
1212
github.com/antchfx/xmlquery v1.3.11/go.mod h1:ywPcYkN0GvURUxXpUujaMVvuLSOYQBzoSfHKfAYezCE=
1313
github.com/antchfx/xpath v1.2.1 h1:qhp4EW6aCOVr5XIkT+l6LJ9ck/JsUH/yyauNgTQkBF8=
1414
github.com/antchfx/xpath v1.2.1/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
15+
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
16+
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
1517
github.com/containerd/typeurl/v2 v2.1.1 h1:3Q4Pt7i8nYwy2KmQWIw2+1hTvwTE/6w9FqcttATPO/4=
1618
github.com/containerd/typeurl/v2 v2.1.1/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0=
1719
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
@@ -27,6 +29,8 @@ github.com/drone/envsubst v1.0.3 h1:PCIBwNDYjs50AsLZPYdfhSATKaRg/FJmDc2D6+C2x8g=
2729
github.com/drone/envsubst v1.0.3/go.mod h1:N2jZmlMufstn1KEqvbHjw40h1KyTmnVzHcSc9bFiJ2g=
2830
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
2931
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
32+
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
33+
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
3034
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
3135
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
3236
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
@@ -92,14 +96,22 @@ github.com/graph-gophers/graphql-go v1.5.0 h1:fDqblo50TEpD0LY7RXk/LFVYEVqo3+tXMN
9296
github.com/graph-gophers/graphql-go v1.5.0/go.mod h1:YtmJZDLbF1YYNrlNAuiO5zAStUWc3XZT07iGsVqe1Os=
9397
github.com/graph-gophers/graphql-transport-ws v0.0.2 h1:DbmSkbIGzj8SvHei6n8Mh9eLQin8PtA8xY9eCzjRpvo=
9498
github.com/graph-gophers/graphql-transport-ws v0.0.2/go.mod h1:5BVKvFzOd2BalVIBFfnfmHjpJi/MZ5rOj8G55mXvZ8g=
99+
github.com/hashicorp/go-hclog v0.14.1 h1:nQcJDQwIAGnmoUWp8ubocEX40cCml/17YkF6csQLReU=
100+
github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
101+
github.com/hashicorp/go-plugin v1.6.1 h1:P7MR2UP6gNKGPp+y7EZw2kOiq4IR9WiqLvp0XOsVdwI=
102+
github.com/hashicorp/go-plugin v1.6.1/go.mod h1:XPHFku2tFo3o3QKFgSYo+cghcUhw1NA1hZyMK0PWAw0=
95103
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
96104
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
105+
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
106+
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
97107
github.com/hasura/go-graphql-client v0.9.2 h1:4FyAeVOu+GcS1BaoELWNyxzaLY7s+g72LLH+qYItdEY=
98108
github.com/hasura/go-graphql-client v0.9.2/go.mod h1:AarJlxO1I59MPqU/TC7gQP0BMFgPEqUTt5LYPvykasw=
99109
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
100110
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
101111
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
102112
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
113+
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
114+
github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo=
103115
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
104116
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
105117
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
@@ -125,11 +137,17 @@ github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
125137
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
126138
github.com/lib/pq v1.10.1 h1:6VXZrLU0jHBYyAqrSPa+MgPfnSvTPuMgK+k0o5kVFWo=
127139
github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
140+
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
141+
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
142+
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
143+
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
128144
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
129145
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
130146
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
131147
github.com/minio/selfupdate v0.4.0 h1:A7t07pN4Ch1tBTIRStW0KhUVyykz+2muCqFsITQeEW8=
132148
github.com/minio/selfupdate v0.4.0/go.mod h1:mcDkzMgq8PRcpCRJo/NlPY7U45O5dfYl2Y0Rg7IustY=
149+
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 h1:7GoSOOW2jpsfkntVKaS2rAr1TJqfcxotyaUcuxoZSzg=
150+
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
133151
github.com/moby/buildkit v0.15.1 h1:J6wrew7hphKqlq1wuu6yaUb/1Ra7gEzDAovylGztAKM=
134152
github.com/moby/buildkit v0.15.1/go.mod h1:Yis8ZMUJTHX9XhH9zVyK2igqSHV3sxi3UN0uztZocZk=
135153
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -140,6 +158,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
140158
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
141159
github.com/nikolalohinski/gonja/v2 v2.1.5 h1:oD8R+GpKMw6Xex9hmWvCQiWlvHfnbmSmu3F5nZ5eRI4=
142160
github.com/nikolalohinski/gonja/v2 v2.1.5/go.mod h1:l9DuWJvT/BddBr2SsmEimESD6msSqRw7u5HzI2Um+sc=
161+
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
162+
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
143163
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
144164
github.com/onsi/ginkgo v1.10.2 h1:uqH7bpe+ERSiDa34FDOF7RikN6RzXgduUF8yarlZp94=
145165
github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@@ -167,6 +187,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
167187
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
168188
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
169189
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
190+
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
170191
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
171192
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
172193
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
@@ -209,15 +230,17 @@ golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qx
209230
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
210231
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
211232
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
212-
golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw=
213-
golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=
233+
golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU=
234+
golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk=
214235
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
215236
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
216237
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
217238
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
218239
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
219240
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
241+
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
220242
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
243+
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
221244
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
222245
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
223246
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -248,6 +271,10 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
248271
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
249272
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
250273
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
274+
google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b h1:ZlWIi1wSK56/8hn4QcBp/j9M7Gt3U/3hZw3mC7vDICo=
275+
google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:swOH3j0KzcDDgGUWr+SNpyTen5YrXjS3eyPzFYKc6lc=
276+
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
277+
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
251278
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
252279
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
253280
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=

pkg/output/rpc.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package output
2+
3+
import (
4+
"net/rpc"
5+
6+
"github.com/hashicorp/go-plugin"
7+
"github.com/salsadigitalauorg/shipshape/pkg/result"
8+
)
9+
10+
// OutputterRPC is the client side implementation of the interface which is used
11+
// by the host to send data to the plugin and receive the result.
12+
type OutputterRPC struct{ client *rpc.Client }
13+
14+
func (or *OutputterRPC) Output(rl *result.ResultList) ([]byte, error) {
15+
var resp []byte
16+
err := or.client.Call("Plugin.Output", rl, &resp)
17+
return resp, err
18+
}
19+
20+
// OutputterRPCServer is the server representation of our interface which is
21+
// used by the plugin to receive data from the host and return the result.
22+
type OutputterRPCServer struct {
23+
Impl Outputter
24+
}
25+
26+
func (os *OutputterRPCServer) Output(rl *result.ResultList, resp *[]byte) error {
27+
b, err := os.Impl.Output(rl)
28+
*resp = b
29+
return err
30+
}
31+
32+
// OutputterPlugin is what exposes the Outputter interface as a plugin.
33+
type OutputterPlugin struct {
34+
Impl Outputter
35+
}
36+
37+
func (p *OutputterPlugin) Server(*plugin.MuxBroker) (interface{}, error) {
38+
return &OutputterRPCServer{Impl: p.Impl}, nil
39+
}
40+
41+
func (OutputterPlugin) Client(b *plugin.MuxBroker, c *rpc.Client) (interface{}, error) {
42+
return &OutputterRPC{client: c}, nil
43+
}

pkg/plugin/plugin.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package plugin
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"os"
7+
"os/exec"
8+
9+
"github.com/hashicorp/go-hclog"
10+
"github.com/hashicorp/go-plugin"
11+
"github.com/salsadigitalauorg/shipshape/pkg/output"
12+
"github.com/salsadigitalauorg/shipshape/pkg/result"
13+
)
14+
15+
var Handshake = plugin.HandshakeConfig{
16+
ProtocolVersion: 1,
17+
MagicCookieKey: "SHIPSHAPE_PLUGIN",
18+
MagicCookieValue: "28d1923e-f22f-41b7-9699-cdbf4a8e2faa",
19+
}
20+
21+
// pluginMap is the map of plugins we can dispense.
22+
var pluginMap = map[string]plugin.Plugin{
23+
"outputter": &output.OutputterPlugin{},
24+
}
25+
26+
func Run() {
27+
// Create an hclog.Logger
28+
logger := hclog.New(&hclog.LoggerOptions{
29+
Name: "plugin",
30+
Output: os.Stdout,
31+
Level: hclog.Debug,
32+
})
33+
34+
// We're a host! Start by launching the plugin process.
35+
client := plugin.NewClient(&plugin.ClientConfig{
36+
HandshakeConfig: Handshake,
37+
Plugins: pluginMap,
38+
Cmd: exec.Command("./build/plugin-sample"),
39+
Logger: logger,
40+
})
41+
defer client.Kill()
42+
43+
// Connect via RPC
44+
rpcClient, err := client.Client()
45+
if err != nil {
46+
log.Fatal(err)
47+
}
48+
49+
// Request the plugin
50+
raw, err := rpcClient.Dispense("outputter")
51+
if err != nil {
52+
log.Fatal(err)
53+
}
54+
55+
outputter := raw.(output.Outputter)
56+
b, err := outputter.Output(&result.ResultList{
57+
Policies: map[string][]string{"policy1": {"rule1", "rule2"}},
58+
Results: []result.Result{{Name: "result1", Passes: []string{"rule1"}}},
59+
})
60+
if err != nil {
61+
log.Fatal(err)
62+
}
63+
64+
fmt.Println("output from plugin:", string(b))
65+
}

0 commit comments

Comments
 (0)