summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/root.go9
-rw-r--r--comm/commget.go13
-rw-r--r--comm/commget_test.go7
-rw-r--r--conf.yaml7
-rw-r--r--go.mod23
-rw-r--r--go.sum309
-rw-r--r--model/marshal_and_unmarshal.go (renamed from rules/marshal_and_unmarshal.go)58
-rw-r--r--model/marshal_and_unmarshal_test.go (renamed from rules/marshal_and_unmarshal_test.go)15
-rw-r--r--model/rule_model.go57
-rw-r--r--router/endpoint.go22
-rw-r--r--router/endpoint_test.go10
-rw-r--r--rules/commscore.go13
-rw-r--r--rules/rules.go24
-rw-r--r--rules/rules_test.go29
-rw-r--r--rules/rulestype_test.go48
-rw-r--r--rules/ruletypes.go138
-rw-r--r--static/rules/pathrules.json5
-rw-r--r--static/rules/websiterules.json6
-rw-r--r--yaml/yaml.go53
-rw-r--r--yaml/yaml_test.go64
20 files changed, 676 insertions, 234 deletions
diff --git a/cmd/root.go b/cmd/root.go
index a5a1ec0..87ec324 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -12,6 +12,7 @@ package cmd
import (
"commdetection/comm"
"commdetection/logger"
+ "commdetection/model"
"commdetection/rules"
"github.com/sirupsen/logrus"
@@ -34,7 +35,7 @@ var (
logLevel uint32
filters = []comm.Filter{}
- rs = rules.Rules{}
+ rs = model.Rules{}
)
// Execute executes the command
@@ -64,12 +65,12 @@ func root() {
for _, ev := range evaluations {
switch ev {
case "command":
- rs = rules.AddRule(rs, rules.Rule{
+ rs = rules.AddRule(rs, model.Rule{
Name: "Command",
RuleFunc: "EvaluateCommandRule",
})
case "path":
- rs = rules.AddRule(rs, rules.Rule{
+ rs = rules.AddRule(rs, model.Rule{
Name: "Path",
RuleFunc: "EvaluatePathRule",
})
@@ -91,7 +92,7 @@ func root() {
}
// StartEvaluateCommands starts evaluating commands using variables rootCmd provided
-func StartEvaluateCommands(filename string) []rules.CommScore {
+func StartEvaluateCommands(filename string) []model.CommScore {
// 从文件中获取路径,默认获取路径为/root/.bash_history
logger.Debugf("Start getting commmands from \"%s\"", filename)
commands := comm.GetCommands(filename, "")
diff --git a/comm/commget.go b/comm/commget.go
index 6d17a47..d868252 100644
--- a/comm/commget.go
+++ b/comm/commget.go
@@ -1,7 +1,7 @@
/*
* @Author: EnderByEndera
* @Date: 2020-12-02 17:08:59
- * @LastEditTime: 2020-12-30 12:19:36
+ * @LastEditTime: 2021-01-04 15:59:10
* @LastEditors: Please set LastEditors
* @Description: Get commands from file or network
* @FilePath: /commdetection/preprocessing/commget.go
@@ -20,6 +20,7 @@ import (
type Command struct {
CommName string `json:"commName"`
Args []string `json:"args"`
+ Flags []string `json:"flags,omitempty"`
}
// GetCommands returns a list of commands preprocessed which first get commands from file then net
@@ -60,20 +61,24 @@ func splitCommandsInLine(tComm []string) []Command {
newComm := Command{
CommName: "",
Args: []string{},
+ Flags: []string{},
}
for commNum, comm := range tComm {
if commNum == 0 {
newComm.CommName = comm
- } else if comm != "&&" {
- newComm.Args = append(newComm.Args, comm)
- } else {
+ } else if comm == "&&" { // comm is the separator of the whole commmand
commands = append(commands, splitCommandsInLine(tComm[commNum+1:])...)
break
+ } else if comm[0] != '-' { // comm is a flag
+ newComm.Args = append(newComm.Args, comm)
+ } else { // comm is just a normal argument
+ newComm.Flags = append(newComm.Flags, comm)
}
}
if !reflect.DeepEqual(newComm, Command{
CommName: "",
Args: []string{},
+ Flags: []string{},
}) {
commands = append([]Command{newComm}, commands...)
}
diff --git a/comm/commget_test.go b/comm/commget_test.go
index 30479a0..62f4a2b 100644
--- a/comm/commget_test.go
+++ b/comm/commget_test.go
@@ -1,7 +1,7 @@
/*
* @Author: your name
* @Date: 2020-12-02 17:09:14
- * @LastEditTime: 2020-12-23 11:46:52
+ * @LastEditTime: 2021-01-04 16:00:18
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: /commdetection/preprocessing/commget_test.go
@@ -60,14 +60,17 @@ func TestSplitCommandsInLine(t *testing.T) {
{
CommName: "ls",
Args: []string{},
+ Flags: []string{},
},
{
CommName: "cp",
- Args: []string{"-s", "abc"},
+ Args: []string{"abc"},
+ Flags: []string{"-s"},
},
{
CommName: "goc",
Args: []string{},
+ Flags: []string{},
},
}
if !reflect.DeepEqual(commands, predict) {
diff --git a/conf.yaml b/conf.yaml
index 5019957..dd6f143 100644
--- a/conf.yaml
+++ b/conf.yaml
@@ -1,7 +1,2 @@
-# The base path is the project's path or env variable COMMDEPATH
-paths:
- multirulespath: static/rules/rules.json
- commrulepath: static/rules/commrules.json
- pathrulepath: static/rules/pathrules.json
ginmode: release
-port: 8080 \ No newline at end of file
+port: 8000 \ No newline at end of file
diff --git a/go.mod b/go.mod
index f0d0aa2..3fa48bd 100644
--- a/go.mod
+++ b/go.mod
@@ -4,34 +4,51 @@ go 1.15
require (
github.com/ajg/form v1.5.1 // indirect
+ github.com/andybalholm/brotli v1.0.1 // indirect
+ github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef // indirect
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 // indirect
github.com/fatih/structs v1.1.0 // indirect
github.com/gavv/httpexpect v2.0.0+incompatible
github.com/gin-gonic/gin v1.6.3
+ github.com/go-playground/validator/v10 v10.4.1 // indirect
+ github.com/golang/protobuf v1.4.3 // indirect
+ github.com/google/go-cmp v0.5.4 // indirect
github.com/google/go-querystring v1.0.0 // indirect
+ github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/imkira/go-interpol v1.1.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
+ github.com/json-iterator/go v1.1.10 // indirect
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect
+ github.com/klauspost/compress v1.11.4 // indirect
github.com/kr/text v0.2.0 // indirect
+ github.com/leodido/go-urn v1.2.1 // indirect
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/moul/http2curl v1.0.0 // indirect
+ github.com/nxadm/tail v1.4.6 // indirect
github.com/onsi/ginkgo v1.14.2 // indirect
github.com/onsi/gomega v1.10.4 // indirect
github.com/sergi/go-diff v1.1.0 // indirect
github.com/sirupsen/logrus v1.7.0
+ github.com/smartystreets/assertions v1.2.0 // indirect
github.com/smartystreets/goconvey v1.6.4 // indirect
- github.com/spf13/cobra v0.0.3
+ github.com/spf13/cobra v1.1.1
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/testify v1.6.1 // indirect
- github.com/valyala/fasthttp v1.18.0 // indirect
+ github.com/ugorji/go v1.2.2 // indirect
+ github.com/valyala/fasthttp v1.19.0 // indirect
+ github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect
github.com/yudai/gojsondiff v1.0.0 // indirect
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
github.com/yudai/pp v2.0.1+incompatible // indirect
+ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect
golang.org/x/net v0.0.0-20201224014010-6772e930b67b // indirect
- golang.org/x/sys v0.0.0-20201218084310-7d0127a74742 // indirect
+ golang.org/x/sys v0.0.0-20201231184435-2d18734c6014 // indirect
+ golang.org/x/text v0.3.4 // indirect
+ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
+ google.golang.org/protobuf v1.25.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
diff --git a/go.sum b/go.sum
index 9db72bf..4b522e9 100644
--- a/go.sum
+++ b/go.sum
@@ -1,13 +1,56 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
+cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
+cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
+cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
+cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
+cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
+cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
+cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
+cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
+cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
+dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4=
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
+github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc=
+github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
+github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
+github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
+github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg=
+github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
+github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
+github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
+github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
+github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 h1:DddqAaWDpywytcG8w/qoQ5sAN8X12d3Z3koB0C3Rxsc=
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
+github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
@@ -15,10 +58,15 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/gavv/httpexpect v2.0.0+incompatible h1:1X9kcRshkSKEjNJJxX9Y9mQ5BRfbxU5kORdjhlA1yX8=
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
+github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
@@ -27,7 +75,19 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
+github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
+github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
@@ -35,32 +95,84 @@ github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:x
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
+github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
+github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
+github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
+github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 h1:l5lAOZEym3oK3SQ2HBHWsJUfbNBiTXJDeW2QDxw9AQ0=
+github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
+github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
+github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
+github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
+github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
+github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
+github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
+github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
+github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
+github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
+github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
+github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
+github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
+github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk=
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
+github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
+github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.10.7 h1:7rix8v8GpI3ZBb0nSozFRgbtXKv+hOe+qfEpZqybrAg=
github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.11.4 h1:kz40R/YWls3iqT9zX9AHN3WoVsrAWVyui5sxuLqiXqU=
+github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
@@ -71,18 +183,41 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
+github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
+github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
+github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
+github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
+github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
+github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
+github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
+github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
+github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs=
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
+github.com/nxadm/tail v1.4.6 h1:11TGpSHY7Esh/i/qnq02Jo5oVrI1Gue8Slbq0ujPZFQ=
+github.com/nxadm/tail v1.4.6/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
+github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M=
@@ -91,42 +226,87 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.4 h1:NiTx7EEvBzu9sFOD1zORteLSt3o8gnlvZZwSE9TnY9U=
github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ=
+github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
+github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
+github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
+github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
+github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
+github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
+github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
+github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4=
+github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
+github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
+github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
+github.com/ugorji/go v1.2.2 h1:60ZHIOcsJlo3bJm9CbTVu7OSqT2mxaEmyQbK2NwCkn0=
+github.com/ugorji/go v1.2.2/go.mod h1:bitgyERdV7L7Db/Z5gfd5v2NQMNhhiFiZwpgMw2SP7k=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
+github.com/ugorji/go/codec v1.2.2 h1:08Gah8d+dXj4cZNUHhtuD/S4PXD5WpVbj5B8/ClELAQ=
+github.com/ugorji/go/codec v1.2.2/go.mod h1:OM8g7OAy52uYl3Yk+RE/3AS1nXFn1Wh4PPLtupCxbuU=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.18.0 h1:IV0DdMlatq9QO1Cr6wGJPVW1sV1Q8HvZXAIcjorylyM=
github.com/valyala/fasthttp v1.18.0/go.mod h1:jjraHZVbKOXftJfsOYoAjaeygpj5hr8ermTRJNroD7A=
+github.com/valyala/fasthttp v1.19.0 h1:PfTS4PeH3xDr3WomrDS2ID8lU2GskK1xS3YG6gIpibU=
+github.com/valyala/fasthttp v1.19.0/go.mod h1:jjraHZVbKOXftJfsOYoAjaeygpj5hr8ermTRJNroD7A=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
+github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
+github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY=
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI=
github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA=
@@ -135,20 +315,81 @@ github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3Ifn
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI=
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
+go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
+go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
+go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
+golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
+golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
+golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
+golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
+golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
+golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
+golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
@@ -162,30 +403,92 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201218084310-7d0127a74742 h1:+CBz4km/0KPU3RGTwARGh/noP3bEwtHcq+0YcBQM2JQ=
golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201231184435-2d18734c6014 h1:joucsQqXmyBVxViHCPFjG3hx8JzIFSaym3l3MM/Jsdg=
+golang.org/x/sys v0.0.0-20201231184435-2d18734c6014/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
+golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
+google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
+google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
+google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
+google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
+google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -196,3 +499,9 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
diff --git a/rules/marshal_and_unmarshal.go b/model/marshal_and_unmarshal.go
index aafe0f9..710a0d7 100644
--- a/rules/marshal_and_unmarshal.go
+++ b/model/marshal_and_unmarshal.go
@@ -1,13 +1,13 @@
/*
* @Author: EnderByEndera
* @Date: 2020-12-16 13:57:06
- * @LastEditTime: 2020-12-28 17:12:09
+ * @LastEditTime: 2021-01-04 17:27:49
* @LastEditors: Please set LastEditors
* @Description: Includes various marshalling ways
* @FilePath: /commdetection/rules/marshalling.go
*/
-package rules
+package model
import (
"commdetection/logger"
@@ -22,14 +22,6 @@ import (
"strings"
)
-//TODO: Temporarily use the funcMap to map the stringVal and the funcRule, will use a func to map later
-var (
- ruleFuncMap = map[string]evaluation{
- "EvaluateCommandRule": EvaluateCommandRule,
- "EvaluatePathRule": EvaluatePathRule,
- }
-)
-
// getFuncName returns a function's name
func getFuncName(i interface{}, seps ...rune) string {
fn := runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
@@ -49,9 +41,9 @@ func getFuncName(i interface{}, seps ...rune) string {
// MarshalEvaluationRules marshals rules.Rules to json file
func MarshalEvaluationRules(rs Rules) (err error) {
- fileName := yaml.GetYamlPathsSetting("rules")
+ fileName := yaml.GetMultiRulesSetting()
if fileName == "" {
- fileName = filepath.Join(os.Getenv("COMMDEPATH"), "static", "rulesjson", "rules.json")
+ fileName = filepath.Join(os.Getenv("COMMDEPATH"), "static", "rules", "rules.json")
}
err = marshalSetting(fileName, rs)
return
@@ -59,9 +51,9 @@ func MarshalEvaluationRules(rs Rules) (err error) {
// UnmarshalEvaluationRules unmarshal rules from a json file
func UnmarshalEvaluationRules() (r Rules, err error) {
- fileName := yaml.GetYamlPathsSetting("rules")
+ fileName := yaml.GetMultiRulesSetting()
if fileName == "" {
- fileName = filepath.Join(os.Getenv("COMMDEPATH"), "static", "rulesjson", "rules.json")
+ fileName = filepath.Join(os.Getenv("COMMDEPATH"), "static", "rules", "rules.json")
}
err = unmarshalSetting(fileName, r)
if err != nil {
@@ -72,18 +64,18 @@ func UnmarshalEvaluationRules() (r Rules, err error) {
// MarshalSensitivePathSetting marshals spaths setting to a json file
func MarshalSensitivePathSetting(spaths SPaths) error {
- fileName := yaml.GetYamlPathsSetting("pathrules")
+ fileName := yaml.GetPathRulesSetting()
if fileName == "" {
- fileName = filepath.Join(os.Getenv("COMMDEPATH"), "static", "rulesjson", "pathrules.json")
+ fileName = filepath.Join(os.Getenv("COMMDEPATH"), "static", "rules", "pathrules.json")
}
return marshalSetting(fileName, spaths)
}
// UnmarshalSensitivePathSetting unmarshals spaths setting json file to spaths variable
func UnmarshalSensitivePathSetting() (spaths SPaths, err error) {
- fileName := yaml.GetYamlPathsSetting("pathrules")
+ fileName := yaml.GetPathRulesSetting()
if fileName == "" {
- fileName = filepath.Join(os.Getenv("COMMDEPATH"), "static", "rulesjson", "pathrules.json")
+ fileName = filepath.Join(os.Getenv("COMMDEPATH"), "static", "rules", "pathrules.json")
}
err = unmarshalSetting(fileName, &spaths)
if err != nil {
@@ -94,18 +86,18 @@ func UnmarshalSensitivePathSetting() (spaths SPaths, err error) {
// MarshalSensitiveCommSetting marshals scomms setting to a json file
func MarshalSensitiveCommSetting(scomms []SComm) error {
- fileName := yaml.GetYamlPathsSetting("commrules")
+ fileName := yaml.GetCommRulesSetting()
if fileName == "" {
- fileName = filepath.Join(os.Getenv("COMMDEPATH"), "static", "rulesjson", "commrules.json")
+ fileName = filepath.Join(os.Getenv("COMMDEPATH"), "static", "rules", "commrules.json")
}
return marshalSetting(fileName, scomms)
}
// UnmarshalSensitiveCommSetting unmarshals scomms setting json file to scomms variable
func UnmarshalSensitiveCommSetting() (scomms SComms, err error) {
- fileName := yaml.GetYamlPathsSetting("commrules")
+ fileName := yaml.GetCommRulesSetting()
if fileName == "" {
- fileName = filepath.Join(os.Getenv("COMMDEPATH"), "static", "rulesjson", "commrules.json")
+ fileName = filepath.Join(os.Getenv("COMMDEPATH"), "static", "rules", "commrules.json")
}
err = unmarshalSetting(fileName, &scomms)
if err != nil {
@@ -114,6 +106,28 @@ func UnmarshalSensitiveCommSetting() (scomms SComms, err error) {
return
}
+// MarshalUnsensitiveWebsiteSetting marshals ussites setting to a json file
+func MarshalUnsensitiveWebsiteSetting(ussites Ussites) error {
+ fileName := yaml.GetWebsiteRulesSetting()
+ if fileName == "" {
+ fileName = filepath.Join(os.Getenv("COMMDEPATH"), "static", "rules", "websiterules.json")
+ }
+ return marshalSetting(fileName, ussites)
+}
+
+// UnMarshalUnsensitiveWebsiteSetting unmarshals ussites setting json file to ussites variable
+func UnMarshalUnsensitiveWebsiteSetting() (ussites Ussites, err error) {
+ fileName := yaml.GetWebsiteRulesSetting()
+ if fileName == "" {
+ fileName = filepath.Join(os.Getenv("COMMDEPATH"), "static", "rules", "websiterules.json")
+ }
+ err = unmarshalSetting(fileName, &ussites)
+ if err != nil {
+ logger.Warnf("json file settings conversion to %s failed, please check json file %s is correct or not\n", reflect.TypeOf(ussites).Name(), fileName)
+ }
+ return
+}
+
func marshalSetting(fileName string, settings interface{}) error {
buf, err := json.Marshal(settings)
if err != nil {
diff --git a/rules/marshal_and_unmarshal_test.go b/model/marshal_and_unmarshal_test.go
index cb4408f..0bd8266 100644
--- a/rules/marshal_and_unmarshal_test.go
+++ b/model/marshal_and_unmarshal_test.go
@@ -1,13 +1,13 @@
/*
* @Author: EnderByEndera
* @Date: 2020-12-16 14:31:00
- * @LastEditTime: 2020-12-31 14:50:23
+ * @LastEditTime: 2021-01-04 18:45:21
* @LastEditors: Please set LastEditors
* @Description: Test marshalling.go
* @FilePath: /commdetection/rules/marshalling_test.go
*/
-package rules
+package model
import (
"encoding/json"
@@ -41,16 +41,7 @@ func TestUnmarshalSensitiveCommSetting(t *testing.T) {
if err != nil {
t.Error(err)
}
- predict := SComms{
- {
- Comm: "wget",
- Coefficient: 0.8,
- },
- {
- Comm: "apt",
- Coefficient: 1.0,
- },
- }
+ predict := SComms{{Comm: "wget", Coefficient: 0.8}, {Comm: "apt", Coefficient: 1}}
if !reflect.DeepEqual(scomms, predict) {
t.Errorf("results are not as predicted")
}
diff --git a/model/rule_model.go b/model/rule_model.go
new file mode 100644
index 0000000..81414a5
--- /dev/null
+++ b/model/rule_model.go
@@ -0,0 +1,57 @@
+/*
+ * @Author: EnderByEndera
+ * @Date: 2021-01-04 16:30:53
+ * @LastEditTime: 2021-01-04 18:38:56
+ * @LastEditors: Please set LastEditors
+ * @Description: This is the model file used for rules pack
+ * @FilePath: /commdetection/model/rule_model.go
+ */
+
+package model
+
+import (
+ "commdetection/comm"
+)
+
+// Rule defines a rule's func and its name
+type Rule struct {
+ Name string `json:"name"`
+ RuleFunc string `json:"rulefunc"`
+}
+
+// Rules is the slice of Rule
+type Rules []Rule
+
+// Evaluation is the template of the Evaluation function
+type Evaluation func(CommScore) CommScore
+
+// CommScore includes command name and its score
+type CommScore struct {
+ Command comm.Command `json:"command"`
+ Score float64 `json:"score"`
+}
+
+// SPath includes sensitive path dir and its sensitive coefficient
+type SPath struct {
+ Path string
+ Coefficient float64
+}
+
+// SPaths is the SPath's multiple type
+type SPaths []SPath
+
+// SComm includes sensitive command's name and its sensitive coefficient
+type SComm struct {
+ Comm string `json:"command"`
+ Coefficient float64 `json:"coefficient"`
+}
+
+// SComms is the SComm's multiple types
+type SComms []SComm
+
+// Ussites is the Unsensitive websites, a.k.a website whitelists
+// Coefficient defines the intent of lowering the score if the website arg is not in the ussites.Websites
+type Ussites struct {
+ Websites []string `json:"websites"`
+ Coefficient float64 `json:"coefficient"`
+}
diff --git a/router/endpoint.go b/router/endpoint.go
index 5b099e5..92d2245 100644
--- a/router/endpoint.go
+++ b/router/endpoint.go
@@ -1,7 +1,7 @@
/*
* @Author: EnderByEndera
* @Date: 2020-12-28 15:53:37
- * @LastEditTime: 2020-12-29 16:36:13
+ * @LastEditTime: 2021-01-04 16:46:56
* @LastEditors: Please set LastEditors
* @Description: endpoint.go contains all the endpoints
* @FilePath: /commdetection/router/endpoint.go
@@ -12,7 +12,7 @@ package router
import (
"commdetection/cmd"
"commdetection/logger"
- "commdetection/rules"
+ "commdetection/model"
"encoding/json"
"io/ioutil"
"net/http"
@@ -65,7 +65,7 @@ func startEvaluateEndpoint(c *gin.Context) {
// getCommrulesEndpoint gets all the command rules stored in the json file
// if error happened, handleErr will be executed
func getCommrulesEndpoint(c *gin.Context) {
- scomms, err := rules.UnmarshalSensitiveCommSetting()
+ scomms, err := model.UnmarshalSensitiveCommSetting()
if err != nil {
handleErr(c, err)
return
@@ -89,12 +89,12 @@ func getCommrulesEndpoint(c *gin.Context) {
// ]
// }
func setCommrulesEndpoint(c *gin.Context) {
- commrules := rules.SComms{}
+ commrules := model.SComms{}
if err := c.ShouldBind(&commrules); err != nil {
handleErr(c, err)
return
}
- if err := rules.MarshalSensitiveCommSetting(commrules); err != nil {
+ if err := model.MarshalSensitiveCommSetting(commrules); err != nil {
handleErr(c, err)
return
}
@@ -104,7 +104,7 @@ func setCommrulesEndpoint(c *gin.Context) {
}
func getPathrulesEndpoint(c *gin.Context) {
- spaths, err := rules.UnmarshalSensitivePathSetting()
+ spaths, err := model.UnmarshalSensitivePathSetting()
if err != nil {
handleErr(c, err)
return
@@ -128,12 +128,12 @@ func getPathrulesEndpoint(c *gin.Context) {
// ]
// }
func setPathrulesEndpoint(c *gin.Context) {
- pathrules := rules.SPaths{}
+ pathrules := model.SPaths{}
if err := c.ShouldBind(&pathrules); err != nil {
handleErr(c, err)
return
}
- if err := rules.MarshalSensitivePathSetting(pathrules); err != nil {
+ if err := model.MarshalSensitivePathSetting(pathrules); err != nil {
handleErr(c, err)
return
}
@@ -143,7 +143,7 @@ func setPathrulesEndpoint(c *gin.Context) {
}
func getEvaluationRulesEndpoint(c *gin.Context) {
- rs, err := rules.UnmarshalSensitivePathSetting()
+ rs, err := model.UnmarshalSensitivePathSetting()
if err != nil {
handleErr(c, err)
return
@@ -167,12 +167,12 @@ func getEvaluationRulesEndpoint(c *gin.Context) {
// ]
// }
func setEvaluationRulesEndpoint(c *gin.Context) {
- rs := rules.Rules{}
+ rs := model.Rules{}
if err := c.ShouldBind(&rs); err != nil {
handleErr(c, err)
return
}
- if err := rules.MarshalEvaluationRules(rs); err != nil {
+ if err := model.MarshalEvaluationRules(rs); err != nil {
handleErr(c, err)
return
}
diff --git a/router/endpoint_test.go b/router/endpoint_test.go
index 2975688..33872f0 100644
--- a/router/endpoint_test.go
+++ b/router/endpoint_test.go
@@ -1,7 +1,7 @@
/*
* @Author: your name
* @Date: 2020-12-28 16:05:24
- * @LastEditTime: 2020-12-29 15:39:34
+ * @LastEditTime: 2021-01-04 19:02:57
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: /commdetection/router/endpoint_test.go
@@ -11,7 +11,7 @@ package router
import (
"commdetection/cmd"
- "commdetection/rules"
+ "commdetection/model"
"net/http"
"net/http/httptest"
"testing"
@@ -22,7 +22,7 @@ import (
var (
e *httpexpect.Expect
url string
- testscomms = rules.SComms{
+ testscomms = model.SComms{
{
Comm: "sudo",
Coefficient: 0.1,
@@ -36,13 +36,13 @@ var (
Coefficient: 0.2,
},
}
- testspaths = rules.SPaths{
+ testspaths = model.SPaths{
{
Path: "/root/go/src/commdetection",
Coefficient: 0.5,
},
}
- testrs = rules.Rules{
+ testrs = model.Rules{
{
Name: "pathrule",
RuleFunc: "EvaluatePathRule",
diff --git a/rules/commscore.go b/rules/commscore.go
index b343f98..f94c693 100644
--- a/rules/commscore.go
+++ b/rules/commscore.go
@@ -1,7 +1,7 @@
/*
* @Author: EnderByEndera
* @Date: 2020-12-16 13:59:51
- * @LastEditTime: 2020-12-19 10:43:36
+ * @LastEditTime: 2021-01-04 16:41:41
* @LastEditors: Please set LastEditors
* @Description: Includes CommScore definition
* @FilePath: /commdetection/rules/commscore.go
@@ -11,18 +11,13 @@ package rules
import (
"commdetection/comm"
+ "commdetection/model"
)
-// CommScore includes command name and its score
-type CommScore struct {
- Command comm.Command `json:"command"`
- Score float64 `json:"score"`
-}
-
// InitCommScores initialize commscores from []Command
-func InitCommScores(commands []comm.Command) (commScores []CommScore) {
+func InitCommScores(commands []comm.Command) (commScores []model.CommScore) {
for _, command := range commands {
- commScores = append(commScores, CommScore{
+ commScores = append(commScores, model.CommScore{
Command: command,
Score: 100,
})
diff --git a/rules/rules.go b/rules/rules.go
index b7df3cd..8c3ec65 100644
--- a/rules/rules.go
+++ b/rules/rules.go
@@ -1,7 +1,7 @@
/*
* @Author: EnderByEndera
* @Date: 2020-12-04 15:03:00
- * @LastEditTime: 2020-12-29 14:29:31
+ * @LastEditTime: 2021-01-04 16:44:06
* @LastEditors: Please set LastEditors
* @Description: rules provide all the rules to check the commands' availability and set score of every command
* @FilePath: /commdetection/rules/commcheck.go
@@ -11,21 +11,11 @@ package rules
import (
"commdetection/logger"
+ "commdetection/model"
)
-// Rule defines a rule's func and its name
-type Rule struct {
- Name string `json:"name"`
- RuleFunc string `json:"rulefunc"`
-}
-
-// Rules is the slice of Rule
-type Rules []Rule
-
-type evaluation func(CommScore) CommScore
-
// AddRule adds one rule to the rules
-func AddRule(rs Rules, rule Rule) Rules {
+func AddRule(rs model.Rules, rule model.Rule) model.Rules {
for _, r := range rs {
if r.Name == rule.Name {
logger.Warnf("%s already existed", rule.Name)
@@ -37,7 +27,7 @@ func AddRule(rs Rules, rule Rule) Rules {
}
// DeleteRuleByName deletes one rule by the name of the rule
-func DeleteRuleByName(r Rules, ruleName string) Rules {
+func DeleteRuleByName(r model.Rules, ruleName string) model.Rules {
existed := false
for index, rule := range r {
if rule.Name == ruleName {
@@ -52,14 +42,14 @@ func DeleteRuleByName(r Rules, ruleName string) Rules {
}
// CreateRule creates one rule with name and rule func and return a Rule
-func CreateRule(name string, rule string) (r Rule) {
+func CreateRule(name string, rule string) (r model.Rule) {
r.Name = name
r.RuleFunc = rule
return
}
// EvaluateCommScore evaluates scores of the commands in the css
-func EvaluateCommScore(css []CommScore, rs Rules) []CommScore {
+func EvaluateCommScore(css []model.CommScore, rs model.Rules) []model.CommScore {
defer func() {
err := recover()
if err != nil {
@@ -72,7 +62,7 @@ func EvaluateCommScore(css []CommScore, rs Rules) []CommScore {
}
for index := 0; index < len(css); index++ {
for _, r := range rs {
- css[index] = ruleFuncMap[r.RuleFunc](css[index])
+ css[index] = RuleFuncMap[r.RuleFunc](css[index])
}
}
return css
diff --git a/rules/rules_test.go b/rules/rules_test.go
index a84f904..f29785f 100644
--- a/rules/rules_test.go
+++ b/rules/rules_test.go
@@ -1,7 +1,7 @@
/*
* @Author: EnderByEndera
* @Date: 2020-12-04 15:03:09
- * @LastEditTime: 2020-12-28 17:21:59
+ * @LastEditTime: 2021-01-04 16:43:21
* @LastEditors: Please set LastEditors
* @Description: Test commrules.go
* @FilePath: /commdetection/rules/commrules_test.go
@@ -10,13 +10,14 @@ package rules
import (
"commdetection/comm"
+ "commdetection/model"
"fmt"
"testing"
)
func TestRule(t *testing.T) {
t.Run("Test AddRule", func(t *testing.T) {
- r := Rules{
+ r := model.Rules{
{
Name: "RuleA",
RuleFunc: "EvaluateCommandRule",
@@ -26,11 +27,11 @@ func TestRule(t *testing.T) {
RuleFunc: "EvaluatePathRule",
},
}
- r = AddRule(r, Rule{
+ r = AddRule(r, model.Rule{
Name: "RuleC",
RuleFunc: "EvaluateCommandRule",
})
- predict := Rules{
+ predict := model.Rules{
{
Name: "RuleA",
RuleFunc: "EvaluateCommandRule",
@@ -56,12 +57,12 @@ func TestRule(t *testing.T) {
return
}
}
- cs := CommScore{
+ cs := model.CommScore{
Command: comm.Command{CommName: "wget"},
Score: 100,
}
for _, rule := range r {
- cs = ruleFuncMap[rule.RuleFunc](cs)
+ cs = RuleFuncMap[rule.RuleFunc](cs)
}
if cs.Score != 100*0.8*0.8 {
t.Errorf("results are not as predicted")
@@ -69,7 +70,7 @@ func TestRule(t *testing.T) {
})
t.Run("Test AddRule with the same name", func(t *testing.T) {
- r := Rules{
+ r := model.Rules{
{
Name: "RuleA",
RuleFunc: "EvaluateCommandRule",
@@ -79,7 +80,7 @@ func TestRule(t *testing.T) {
RuleFunc: "EvaluatePathRule",
},
}
- r = AddRule(r, Rule{
+ r = AddRule(r, model.Rule{
Name: "RuleA",
RuleFunc: "EvaluateCommandRule",
})
@@ -89,7 +90,7 @@ func TestRule(t *testing.T) {
})
t.Run("Test DeleteRuleByName", func(t *testing.T) {
- r := Rules{
+ r := model.Rules{
{
Name: "RuleA",
RuleFunc: "EvaluateCommandRule",
@@ -112,13 +113,13 @@ func TestRule(t *testing.T) {
})
t.Run("Test MarshallEvaluationRules", func(t *testing.T) {
- rs := Rules{
+ rs := model.Rules{
{
Name: "RuleA",
RuleFunc: "EvaluateCommandRule",
},
}
- err := MarshalEvaluationRules(rs)
+ err := model.MarshalEvaluationRules(rs)
if err != nil {
t.Error(err)
}
@@ -133,7 +134,7 @@ func TestInitCommScores(t *testing.T) {
}
func TestEvaluateCommScore(t *testing.T) {
- css := EvaluateCommScore([]CommScore{
+ css := EvaluateCommScore([]model.CommScore{
{
Command: comm.Command{
CommName: "wget",
@@ -142,8 +143,8 @@ func TestEvaluateCommScore(t *testing.T) {
Score: 100,
},
},
- Rules{
- Rule{
+ model.Rules{
+ {
Name: "RuleA",
RuleFunc: "EvaluateCommandRule",
},
diff --git a/rules/rulestype_test.go b/rules/rulestype_test.go
index df25ef7..9436e9d 100644
--- a/rules/rulestype_test.go
+++ b/rules/rulestype_test.go
@@ -1,7 +1,7 @@
/*
* @Author: EnderByEndera
* @Date: 2020-12-08 11:28:49
- * @LastEditTime: 2020-12-31 14:05:30
+ * @LastEditTime: 2021-01-04 19:06:53
* @LastEditors: Please set LastEditors
* @Description: Test UnmarshalSetting and MarshalSetting
* @FilePath: /commdetection/rules/rulestype_test.go
@@ -11,13 +11,14 @@ package rules
import (
"commdetection/comm"
+ "commdetection/model"
"log"
"testing"
)
func TestEvaluateCommandRule(t *testing.T) {
t.Run("Test Normal Command Rule Evaluation", func(t *testing.T) {
- cs := CommScore{
+ cs := model.CommScore{
Command: comm.Command{
CommName: "wget",
Args: []string{"https://127.0.0.1:8080"},
@@ -33,7 +34,7 @@ func TestEvaluateCommandRule(t *testing.T) {
func TestEvaluatePathRule(t *testing.T) {
t.Run("Test Normal Path Rule Evaluation", func(t *testing.T) {
- cs := CommScore{
+ cs := model.CommScore{
Command: comm.Command{
CommName: "wget",
Args: []string{"rules.json"},
@@ -49,15 +50,32 @@ func TestEvaluatePathRule(t *testing.T) {
})
}
+func TestEvaluateWebsiteRule(t *testing.T) {
+ t.Run("Test Evaluating Website Rule", func(t *testing.T) {
+ cs := model.CommScore{
+ Command: comm.Command{
+ CommName: "wget",
+ Args: []string{"https://golang.org/"},
+ Flags: []string{},
+ },
+ Score: 100.0,
+ }
+ cs = EvaluateWebsiteRule(cs)
+ if cs.Score == 100 {
+ return
+ }
+ t.Errorf("Wrong score: %.2f", cs.Score)
+ })
+}
+
func BenchmarkEvaluateCommandRule(b *testing.B) {
- cs := CommScore{
- Command: comm.Command{
- CommName: "wget",
- Args: []string{"https://127.0.0.1:8080"},
- },
- Score: 100,
+ comms := comm.GetCommands("/root/.bash_history", "")
+ comms = comm.FlushCommands(comms, []comm.Filter{comm.WhichCommandFilter})
+ css := InitCommScores(comms)
+ b.ResetTimer()
+ for _, cs := range css {
+ cs = EvaluateCommandRule(cs)
}
- cs = EvaluateCommandRule(cs)
}
func BenchmarkEvaluatePathRule(b *testing.B) {
@@ -69,3 +87,13 @@ func BenchmarkEvaluatePathRule(b *testing.B) {
cs = EvaluatePathRule(cs)
}
}
+
+func BenchmarkEvaluateWebsiteRule(b *testing.B) {
+ comms := comm.GetCommands("/root/.bash_history", "")
+ comms = comm.FlushCommands(comms, []comm.Filter{comm.WhichCommandFilter})
+ css := InitCommScores(comms)
+ b.ResetTimer()
+ for _, cs := range css {
+ cs = EvaluateWebsiteRule(cs)
+ }
+}
diff --git a/rules/ruletypes.go b/rules/ruletypes.go
index bdefecc..f6d8c2b 100644
--- a/rules/ruletypes.go
+++ b/rules/ruletypes.go
@@ -1,7 +1,7 @@
/*
* @Author: EnderByEndera
* @Date: 2020-12-08 10:59:19
- * @LastEditTime: 2021-01-04 11:21:49
+ * @LastEditTime: 2021-01-04 18:56:54
* @LastEditors: Please set LastEditors
* @Description: Unmarshal and marshal various types of settings and rules
* @FilePath: /commdetection/rules/ruletypes.go
@@ -11,70 +11,39 @@ package rules
import (
"commdetection/logger"
- "io/ioutil"
+ "commdetection/model"
+ "net/url"
+ "os"
"path/filepath"
+ "strings"
)
-// SPath includes sensitive path dir and its sensitive coefficient
-type SPath struct {
- Path string
- Coefficient float64
-}
-
-// SPaths is the SPath's multiple type
-type SPaths []SPath
-
-// SComm includes sensitive command's name and its sensitive coefficient
-type SComm struct {
- Comm string `json:"command"`
- Coefficient float64 `json:"coefficient"`
-}
-
-// SComms is the SComm's multiple types
-type SComms []SComm
+//TODO: Temporarily use the funcMap to map the stringVal and the funcRule, will use a func to map later
+var (
+ RuleFuncMap = map[string]model.Evaluation{
+ "EvaluateCommandRule": EvaluateCommandRule,
+ "EvaluatePathRule": EvaluatePathRule,
+ }
+)
// EvaluatePathRule defines a rule from json file to judge command score by
// whether sensitive path appears in the Command
-func EvaluatePathRule(cs CommScore) CommScore {
- spaths, err := UnmarshalSensitivePathSetting()
+func EvaluatePathRule(cs model.CommScore) model.CommScore {
+ spaths, err := model.UnmarshalSensitivePathSetting()
if err != nil {
logger.Warnf("cannot get sensitive paths from file, please check the file path")
return cs
}
for _, spath := range spaths {
- fileInfos, err := readAllFiles(spath.Path, []string{})
- if err != nil {
- logger.Warnf("Error occured during EvaluatePathRule, error is %s", err)
- break
- }
ratio := 0.0
- in := make(chan float64)
- out := make(chan float64)
- // Creates the outside go func
- go func(spath SPath) {
- r1 := 0.0
- for _, fileInfo := range fileInfos {
- // Creates the inside go func
- go func(fileInfo string) {
- r2 := 0.0
- for _, arg := range cs.Command.Args {
- baseArg, baseSPath := filepath.Base(arg), filepath.Base(fileInfo)
- if baseArg == baseSPath {
- r2 += float64(len(arg)) / float64(len(fileInfo))
- }
- }
- in <- r2
- }(fileInfo)
+ filepath.Walk(spath.Path, func(path string, info os.FileInfo, err error) error {
+ for _, arg := range cs.Command.Args {
+ if filepath.Base(arg) == info.Name() {
+ ratio += float64(len(info.Name())) / float64(len(arg))
+ }
}
- for range fileInfos {
- r1 += <-in
- }
- out <- r1
- }(spath)
-
- for range spaths {
- ratio += <-out
- }
+ return nil
+ })
// when ratio is larger than threshold 0.1
if ratio > 0.1 {
// execute evaluation formula
@@ -82,45 +51,62 @@ func EvaluatePathRule(cs CommScore) CommScore {
}
if cs.Score < 0 {
cs.Score = 0.0
+ return cs
}
}
return cs
}
-func readAllFiles(pathname string, s []string) ([]string, error) {
- fromSlash := filepath.FromSlash(pathname)
- rd, err := ioutil.ReadDir(fromSlash)
+// EvaluateCommandRule defines a rule from json file to judge command score by
+// whether sensitive command appears in the Command
+func EvaluateCommandRule(cs model.CommScore) model.CommScore {
+ scomms, err := model.UnmarshalSensitiveCommSetting()
if err != nil {
- logger.Warnln("read dir fail:", err)
- return s, err
+ logger.Warnln("cannot get sensitive paths from file, please check the file path")
+ return cs
}
- for _, fi := range rd {
- if fi.IsDir() {
- fullDir := filepath.Join(fromSlash, fi.Name())
- s, err = readAllFiles(fullDir, s)
- if err != nil {
- logger.Warnln("read dir fail:", err)
- return s, err
- }
- } else {
- fullName := filepath.Join(fromSlash, fi.Name())
- s = append(s, fullName)
+ for _, scomm := range scomms {
+ if scomm.Comm == cs.Command.CommName {
+ cs.Score *= scomm.Coefficient
}
}
- return s, nil
+ return cs
}
-// EvaluateCommandRule defines a rule from json file to judge command score by
-// whether sensitive command appears in the Command
-func EvaluateCommandRule(cs CommScore) CommScore {
- scomms, err := UnmarshalSensitiveCommSetting()
+// EvaluateWebsiteRule defines a rule from json file to judge commmand score
+//
+// 1. Check the arg of one command is a website or not
+//
+// 2. Check whether the website is in the whitelist, a.k.a ussites(unsensitive websites)
+//
+// 3. if in, the rule won't lower the score, if not, lower the score by coefficient defined in the ussites
+func EvaluateWebsiteRule(cs model.CommScore) model.CommScore {
+ ussites, err := model.UnMarshalUnsensitiveWebsiteSetting()
if err != nil {
logger.Warnln("cannot get sensitive paths from file, please check the file path")
return cs
}
- for _, scomm := range scomms {
- if scomm.Comm == cs.Command.CommName {
- cs.Score *= scomm.Coefficient
+ argsites := []*url.URL{}
+ // Check the arg of one command is a website or not
+ for _, arg := range cs.Command.Args {
+ u, err := url.Parse(arg)
+ if err == nil {
+ argsites = append(argsites, u)
+ }
+ }
+
+ // Start checking whether the argsites are in the websites or not
+ for _, argsite := range argsites {
+ // Get the host of one argsite and compare with website
+ included := false
+ // Check whether the argsite is in the websites
+ for _, website := range ussites.Websites {
+ if strings.Contains(website, argsite.Host) {
+ included = true
+ }
+ }
+ if !included {
+ cs.Score *= ussites.Coefficient
}
}
return cs
diff --git a/static/rules/pathrules.json b/static/rules/pathrules.json
index 4f8c9f0..7e04441 100644
--- a/static/rules/pathrules.json
+++ b/static/rules/pathrules.json
@@ -1 +1,4 @@
-[{"Path":"/root/go/src/commdetection","Coefficient":0.5}] \ No newline at end of file
+[{
+ "Path": "/root/go/src/commdetection",
+ "Coefficient": 0.5
+}] \ No newline at end of file
diff --git a/static/rules/websiterules.json b/static/rules/websiterules.json
new file mode 100644
index 0000000..f187ae6
--- /dev/null
+++ b/static/rules/websiterules.json
@@ -0,0 +1,6 @@
+{
+ "websites": [
+ "www.golang.org"
+ ],
+ "coefficient": 0.9
+} \ No newline at end of file
diff --git a/yaml/yaml.go b/yaml/yaml.go
index c0182c0..2b4cc3a 100644
--- a/yaml/yaml.go
+++ b/yaml/yaml.go
@@ -1,7 +1,7 @@
/*
* @Author: EnderByEndera
* @Date: 2020-12-09 16:44:44
- * @LastEditTime: 2020-12-29 16:11:40
+ * @LastEditTime: 2021-01-04 19:11:44
* @LastEditors: Please set LastEditors
* @Description: Init settings from yaml file
* @FilePath: /commdetection/init/init.go
@@ -23,10 +23,11 @@ import (
// Conf defines the configuration from the yaml file
type Conf struct {
Paths struct {
- MultiRulesPath string `yaml:"multirulespath"`
- CommRulePath string `yaml:"commrulepath"`
- PathRulePath string `yaml:"pathrulepath"`
- }
+ MultiRulesPath string `yaml:"multirulepath"`
+ CommRulePath string `yaml:"commrulepath"`
+ PathRulePath string `yaml:"pathrulepath"`
+ WebsiteRulesPath string `yaml:"webrulepath"`
+ } `yaml:"path"`
GinMode string `yaml:"ginmode"`
Port uint16 `yaml:"port"`
}
@@ -62,18 +63,34 @@ func GetGinMode() (string, error) {
return "debug", fmt.Errorf("GinMode reads failed. Cannot find %s in any of gin modes", conf.GinMode)
}
-// GetYamlPathsSetting gets the paths: settings from conf.yaml
-func GetYamlPathsSetting(settingName string) (c string) {
- switch settingName {
- case "commrules":
- c = filepath.Join(os.Getenv("COMMDEPATH"), conf.Paths.CommRulePath)
- case "pathrules":
- c = filepath.Join(os.Getenv("COMMDEPATH"), conf.Paths.PathRulePath)
- case "rules":
- c = filepath.Join(os.Getenv("COMMDEPATH"), conf.Paths.MultiRulesPath)
- default:
- c = os.Getenv("COMMDEPATH")
- logger.Warnln("Didn't get any setting, use default value: " + os.Getenv("COMMDEPATH"))
+// GetCommRulesSetting returns the path storing sensitive command rules
+func GetCommRulesSetting() string {
+ if conf.Paths.CommRulePath == "" {
+ return conf.Paths.CommRulePath
+ }
+ return filepath.Join(os.Getenv("COMMDEPATH"), conf.Paths.CommRulePath)
+}
+
+// GetPathRulesSetting returns the path storing sensitive path rules
+func GetPathRulesSetting() string {
+ if conf.Paths.CommRulePath == "" {
+ return conf.Paths.PathRulePath
+ }
+ return filepath.Join(os.Getenv("COMMDEPATH"), conf.Paths.PathRulePath)
+}
+
+// GetMultiRulesSetting returns the path storing rules of the sensitive rules like command rules or path rules
+func GetMultiRulesSetting() string {
+ if conf.Paths.MultiRulesPath == "" {
+ return conf.Paths.MultiRulesPath
+ }
+ return filepath.Join(os.Getenv("COMMDEPATH"), conf.Paths.MultiRulesPath)
+}
+
+// GetWebsiteRulesSetting returns the file path storing the net rules white list
+func GetWebsiteRulesSetting() string {
+ if conf.Paths.WebsiteRulesPath == "" {
+ return conf.Paths.WebsiteRulesPath
}
- return
+ return filepath.Join(os.Getenv("COMMDEPATH"), conf.Paths.WebsiteRulesPath)
}
diff --git a/yaml/yaml_test.go b/yaml/yaml_test.go
index 88fcff1..d8b58ad 100644
--- a/yaml/yaml_test.go
+++ b/yaml/yaml_test.go
@@ -1,7 +1,7 @@
/*
* @Author: EnderByEndera
* @Date: 2020-12-14 14:57:47
- * @LastEditTime: 2020-12-31 10:27:55
+ * @LastEditTime: 2021-01-04 15:34:16
* @LastEditors: Please set LastEditors
* @Description: test yaml.go
* @FilePath: /commdetection/yaml/yaml_test.go
@@ -10,32 +10,56 @@
package yaml
import (
- "fmt"
"os"
"path/filepath"
+ "strconv"
+ "strings"
"testing"
)
func TestGetYamlSetting(t *testing.T) {
- setting := GetYamlPathsSetting("commrules")
- if setting != filepath.Join(os.Getenv("COMMDEPATH"), "static", "rules", "commrules.json") {
- fmt.Println(setting)
- t.Errorf("get yaml setting failed")
- }
- setting = GetYamlPathsSetting("pathrules")
- if setting != filepath.Join(os.Getenv("COMMDEPATH"), "static", "rules", "pathrules.json") {
- fmt.Println(setting)
- t.Errorf("get yaml setting failed")
- }
- setting = GetYamlPathsSetting("rules")
- if setting != filepath.Join(os.Getenv("COMMDEPATH"), "static", "rules", "rules.json") {
- fmt.Println(setting)
- t.Errorf("get yaml setting failed")
- }
+ t.Run("Test GetPort", func(t *testing.T) {
+ setting := GetPort()
+ if !strings.HasPrefix(setting, ":") {
+ t.Errorf("Wrong setting: \"%s\"", setting)
+ }
+ if port, err := strconv.Atoi(setting[1:]); err != nil {
+ t.Error(err)
+ } else if port <= 0 || port >= 65536 {
+ t.Errorf("Wrong port: %d", port)
+ }
+ })
+ t.Run("Test GetGinmode", func(t *testing.T) {
+ setting, err := GetGinMode()
+ if err != nil {
+ t.Error(err)
+ }
+ if setting != "release" && setting != "debug" && setting != "test" {
+ t.Errorf("Wrong setting: %s", setting)
+ }
+ })
+ t.Run("Test GetCommrulesSetting", func(t *testing.T) {
+ setting := GetCommRulesSetting()
+ if setting != "" && !filepath.HasPrefix(setting, os.Getenv("COMMDEPATH")) {
+ t.Errorf("Wrong path: %s", setting)
+ }
+ })
+ t.Run("Test GetPathrulesSetting", func(t *testing.T) {
+ setting := GetPathRulesSetting()
+ if setting != "" && !filepath.HasPrefix(setting, os.Getenv("COMMDEPATH")) {
+ t.Errorf("Wrong path: %s", setting)
+ }
+ })
+ t.Run("Test GetMultirulesSetting", func(t *testing.T) {
+ setting := GetMultiRulesSetting()
+ if setting != "" && !filepath.HasPrefix(setting, os.Getenv("COMMDEPATH")) {
+ t.Errorf("Wrong path: %s", setting)
+ }
+ })
}
func BenchmarkGetYamlSetting(b *testing.B) {
- GetYamlPathsSetting("commrules")
- GetYamlPathsSetting("pathrules")
- GetYamlPathsSetting("rules")
+ GetCommRulesSetting()
+ GetMultiRulesSetting()
+ GetPathRulesSetting()
}