mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-06 16:06:56 +00:00
Merge branch 'master' into update_doc
This commit is contained in:
commit
9eae338b58
107 changed files with 1370 additions and 731 deletions
1
Makefile
1
Makefile
|
@ -21,6 +21,7 @@ LD_FLAGS="-s -w -X $(PACKAGE)/pkg/version.BuildVersion=$(GIT_VERSION) -X $(PACKA
|
|||
|
||||
KYVERNO_PATH:= cmd/kyverno
|
||||
build: kyverno
|
||||
PWD := $(CURDIR)
|
||||
|
||||
##################################
|
||||
# INIT CONTAINER
|
||||
|
|
|
@ -46,13 +46,13 @@ func main() {
|
|||
|
||||
requests := []request{
|
||||
// Resource
|
||||
request{mutatingWebhookConfigKind, config.MutatingWebhookConfigurationName},
|
||||
request{mutatingWebhookConfigKind, config.MutatingWebhookConfigurationDebugName},
|
||||
{mutatingWebhookConfigKind, config.MutatingWebhookConfigurationName},
|
||||
{mutatingWebhookConfigKind, config.MutatingWebhookConfigurationDebugName},
|
||||
// Policy
|
||||
request{validatingWebhookConfigKind, config.PolicyValidatingWebhookConfigurationName},
|
||||
request{validatingWebhookConfigKind, config.PolicyValidatingWebhookConfigurationDebugName},
|
||||
request{mutatingWebhookConfigKind, config.PolicyMutatingWebhookConfigurationName},
|
||||
request{mutatingWebhookConfigKind, config.PolicyMutatingWebhookConfigurationDebugName},
|
||||
{validatingWebhookConfigKind, config.PolicyValidatingWebhookConfigurationName},
|
||||
{validatingWebhookConfigKind, config.PolicyValidatingWebhookConfigurationDebugName},
|
||||
{mutatingWebhookConfigKind, config.PolicyMutatingWebhookConfigurationName},
|
||||
{mutatingWebhookConfigKind, config.PolicyMutatingWebhookConfigurationDebugName},
|
||||
}
|
||||
|
||||
done := make(chan struct{})
|
||||
|
|
|
@ -116,7 +116,7 @@ func main() {
|
|||
10*time.Second)
|
||||
|
||||
// Configuration Data
|
||||
// dyamically load the configuration from configMap
|
||||
// dynamically load the configuration from configMap
|
||||
// - resource filters
|
||||
// if the configMap is update, the configuration will be updated :D
|
||||
configData := config.NewConfigData(
|
||||
|
@ -143,7 +143,7 @@ func main() {
|
|||
// POLICY CONTROLLER
|
||||
// - reconciliation policy and policy violation
|
||||
// - process policy on existing resources
|
||||
// - status aggregator: recieves stats when a policy is applied
|
||||
// - status aggregator: receives stats when a policy is applied
|
||||
// & updates the policy status
|
||||
pc, err := policy.NewPolicyController(pclient,
|
||||
client,
|
||||
|
|
|
@ -148,5 +148,15 @@ spec:
|
|||
- As the userInformation is only avaiable in the incoming api-request, a policy using userInfo filters and variables reffering to `{{request.userInfo}}` can only be processed in foreground mode.
|
||||
- When a new policy is created, the policy validation will throw an error if using `userInfo` with a policy defined in background mode.
|
||||
|
||||
|
||||
# Auto generating rules for pod controllers
|
||||
Writing policies on pods helps address all pod creation flows, but results in errors not being reported when a pod controller object is created. Kyverno solves this issue, by automatically generating rules for pod controllers from a rule written for a pod.
|
||||
|
||||
This behavior is controlled by the pod-policies.kyverno.io/autogen-controllers annotation. By default, Kyverno inserts an annotation `pod-policies.kyverno.io/autogen-controllers=all`, to generate an additional rule that is applied to pod controllers: DaemonSet, Deployment, Job, StatefulSet.
|
||||
|
||||
Change the annotation `pod-policies.kyverno.io/autogen-controllers` to customize the applicable pod controllers of the auto-gen rule. For example, Kyverno generates the rule for `Deployment` if the annotation of policy is defined as `pod-policies.kyverno.io/autogen-controllers=Deployment`. If `name` or `labelSelector` is specified in the match / exclude block, Kyverno skips generating pod controllers rule as these filters may not be applicable to pod controllers.
|
||||
|
||||
To disable auto-generating rules for pod controllers, set `pod-policies.kyverno.io/autogen-controllers=none`.
|
||||
|
||||
---
|
||||
<small>*Read Next >> [Validate](/documentation/writing-policies-validate.md)*</small>
|
1
go.mod
1
go.mod
|
@ -14,6 +14,7 @@ require (
|
|||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af
|
||||
github.com/json-iterator/go v1.1.9 // indirect
|
||||
github.com/minio/minio v0.0.0-20200114012931-30922148fbb5
|
||||
github.com/ory/go-acc v0.1.0 // indirect
|
||||
github.com/spf13/cobra v0.0.5
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5
|
||||
|
|
484
go.sum
484
go.sum
|
@ -1,19 +1,35 @@
|
|||
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.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts=
|
||||
cloud.google.com/go v0.41.0/go.mod h1:OauMR7DV8fzvZIl2qg6rkaIhD/vmgk4iwEw/h6ercmg=
|
||||
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/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/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.5.0/go.mod h1:ImxhfLRpxoYiSq891pBrLVhN+qmP8BTVvdH2YLs7Gl0=
|
||||
git.apache.org/thrift.git v0.12.0/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||
github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4=
|
||||
github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-autorest v11.7.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
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/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/Shopify/sarama v1.24.1/go.mod h1:fGP8eQ6PugKEI0iUETYYtnP6d1pH/bdDMTel1X5ajsU=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||
github.com/ajg/form v0.0.0-20160822230020-523a5da1a92f/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||
github.com/alecthomas/participle v0.2.1/go.mod h1:SW6HZGeZgSIpcUWX3fXpfZhuaWHnmoD5KCVaqSaNTkk=
|
||||
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=
|
||||
|
@ -22,21 +38,35 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5
|
|||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/aws/aws-sdk-go v1.20.21/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.23.19/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-xray-sdk-go v0.9.4/go.mod h1:XtMKdBQfpVut+tJEwI7+dJFRxxRdxHDyVNp2tHXRq04=
|
||||
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
|
||||
github.com/bcicen/jstream v0.0.0-20190220045926-16c1f8af81c2/go.mod h1:RDu/qcrnpEdJC/p8tx34+YBFqqX71lB7dOX9QE+ZC4M=
|
||||
github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
|
||||
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/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
||||
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
||||
github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cheggaaa/pb v1.0.28/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
|
||||
github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575/go.mod h1:9d6lWj8KzO/fd/NrVaLscBKmPigpZpn5YawRPw+e3Yo=
|
||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/codegangsta/negroni v1.0.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0=
|
||||
github.com/containerd/continuity v0.0.0-20181203112020-004b46473808/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/coredns/coredns v1.4.0/go.mod h1:zASH/MVDgR6XZTbxvOnsZfffS+31vg6Ackf/wo1+AM0=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/etcd v3.3.12+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
|
@ -51,8 +81,12 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||
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/djherbis/atime v1.0.0/go.mod h1:5W+KBIuTwVGcqjIfaTwt+KSYX1o6uep8dtevevQP/f8=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/dustin/go-humanize v0.0.0-20180713052910-9f541cc9db5d/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
|
@ -60,41 +94,220 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1
|
|||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
|
||||
github.com/elazarl/goproxy v0.0.0-20181003060214-f58a169a71a5/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M=
|
||||
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/structs v1.0.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
|
||||
github.com/go-bindata/go-bindata v3.1.1+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
|
||||
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-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
|
||||
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
||||
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
|
||||
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
|
||||
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/gobuffalo/buffalo v0.12.8-0.20181004233540-fac9bb505aa8/go.mod h1:sLyT7/dceRXJUxSsE813JTQtA3Eb1vjxWfo/N//vXIY=
|
||||
github.com/gobuffalo/buffalo v0.13.0/go.mod h1:Mjn1Ba9wpIbpbrD+lIDMy99pQ0H0LiddMIIDGse7qT4=
|
||||
github.com/gobuffalo/buffalo-plugins v1.0.2/go.mod h1:pOp/uF7X3IShFHyobahTkTLZaeUXwb0GrUTb9ngJWTs=
|
||||
github.com/gobuffalo/buffalo-plugins v1.0.4/go.mod h1:pWS1vjtQ6uD17MVFWf7i3zfThrEKWlI5+PYLw/NaDB4=
|
||||
github.com/gobuffalo/buffalo-plugins v1.4.3/go.mod h1:uCzTY0woez4nDMdQjkcOYKanngeUVRO2HZi7ezmAjWY=
|
||||
github.com/gobuffalo/buffalo-plugins v1.5.1/go.mod h1:jbmwSZK5+PiAP9cC09VQOrGMZFCa/P0UMlIS3O12r5w=
|
||||
github.com/gobuffalo/buffalo-plugins v1.6.4/go.mod h1:/+N1aophkA2jZ1ifB2O3Y9yGwu6gKOVMtUmJnbg+OZI=
|
||||
github.com/gobuffalo/buffalo-plugins v1.6.5/go.mod h1:0HVkbgrVs/MnPZ/FOseDMVanCTm2RNcdM0PuXcL1NNI=
|
||||
github.com/gobuffalo/buffalo-plugins v1.6.7/go.mod h1:ZGZRkzz2PiKWHs0z7QsPBOTo2EpcGRArMEym6ghKYgk=
|
||||
github.com/gobuffalo/buffalo-plugins v1.6.9/go.mod h1:yYlYTrPdMCz+6/+UaXg5Jm4gN3xhsvsQ2ygVatZV5vw=
|
||||
github.com/gobuffalo/buffalo-plugins v1.6.11/go.mod h1:eAA6xJIL8OuynJZ8amXjRmHND6YiusVAaJdHDN1Lu8Q=
|
||||
github.com/gobuffalo/buffalo-plugins v1.8.2/go.mod h1:9te6/VjEQ7pKp7lXlDIMqzxgGpjlKoAcAANdCgoR960=
|
||||
github.com/gobuffalo/buffalo-plugins v1.8.3/go.mod h1:IAWq6vjZJVXebIq2qGTLOdlXzmpyTZ5iJG5b59fza5U=
|
||||
github.com/gobuffalo/buffalo-plugins v1.9.4/go.mod h1:grCV6DGsQlVzQwk6XdgcL3ZPgLm9BVxlBmXPMF8oBHI=
|
||||
github.com/gobuffalo/buffalo-plugins v1.10.0/go.mod h1:4osg8d9s60txLuGwXnqH+RCjPHj9K466cDFRl3PErHI=
|
||||
github.com/gobuffalo/buffalo-plugins v1.11.0/go.mod h1:rtIvAYRjYibgmWhnjKmo7OadtnxuMG5ZQLr25ozAzjg=
|
||||
github.com/gobuffalo/buffalo-pop v1.0.5/go.mod h1:Fw/LfFDnSmB/vvQXPvcXEjzP98Tc+AudyNWUBWKCwQ8=
|
||||
github.com/gobuffalo/envy v1.6.4/go.mod h1:Abh+Jfw475/NWtYMEt+hnJWRiC8INKWibIMyNt1w2Mc=
|
||||
github.com/gobuffalo/envy v1.6.5/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ=
|
||||
github.com/gobuffalo/envy v1.6.6/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ=
|
||||
github.com/gobuffalo/envy v1.6.7/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ=
|
||||
github.com/gobuffalo/envy v1.6.8/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ=
|
||||
github.com/gobuffalo/envy v1.6.9/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ=
|
||||
github.com/gobuffalo/envy v1.6.10/go.mod h1:X0CFllQjTV5ogsnUrg+Oks2yTI+PU2dGYBJOEI2D1Uo=
|
||||
github.com/gobuffalo/envy v1.6.11/go.mod h1:Fiq52W7nrHGDggFPhn2ZCcHw4u/rqXkqo+i7FB6EAcg=
|
||||
github.com/gobuffalo/envy v1.6.12/go.mod h1:qJNrJhKkZpEW0glh5xP2syQHH5kgdmgsKss2Kk8PTP0=
|
||||
github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
|
||||
github.com/gobuffalo/events v1.0.3/go.mod h1:Txo8WmqScapa7zimEQIwgiJBvMECMe9gJjsKNPN3uZw=
|
||||
github.com/gobuffalo/events v1.0.7/go.mod h1:z8txf6H9jWhQ5Scr7YPLWg/cgXBRj8Q4uYI+rsVCCSQ=
|
||||
github.com/gobuffalo/events v1.0.8/go.mod h1:A5KyqT1sA+3GJiBE4QKZibse9mtOcI9nw8gGrDdqYGs=
|
||||
github.com/gobuffalo/events v1.1.3/go.mod h1:9yPGWYv11GENtzrIRApwQRMYSbUgCsZ1w6R503fCfrk=
|
||||
github.com/gobuffalo/events v1.1.4/go.mod h1:09/YRRgZHEOts5Isov+g9X2xajxdvOAcUuAHIX/O//A=
|
||||
github.com/gobuffalo/events v1.1.5/go.mod h1:3YUSzgHfYctSjEjLCWbkXP6djH2M+MLaVRzb4ymbAK0=
|
||||
github.com/gobuffalo/events v1.1.7/go.mod h1:6fGqxH2ing5XMb3EYRq9LEkVlyPGs4oO/eLzh+S8CxY=
|
||||
github.com/gobuffalo/events v1.1.8/go.mod h1:UFy+W6X6VbCWS8k2iT81HYX65dMtiuVycMy04cplt/8=
|
||||
github.com/gobuffalo/events v1.1.9/go.mod h1:/0nf8lMtP5TkgNbzYxR6Bl4GzBy5s5TebgNTdRfRbPM=
|
||||
github.com/gobuffalo/fizz v1.0.12/go.mod h1:C0sltPxpYK8Ftvf64kbsQa2yiCZY4RZviurNxXdAKwc=
|
||||
github.com/gobuffalo/flect v0.0.0-20180907193754-dc14d8acaf9f/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA=
|
||||
github.com/gobuffalo/flect v0.0.0-20181002182613-4571df4b1daf/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA=
|
||||
github.com/gobuffalo/flect v0.0.0-20181007231023-ae7ed6bfe683/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA=
|
||||
github.com/gobuffalo/flect v0.0.0-20181018182602-fd24a256709f/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA=
|
||||
github.com/gobuffalo/flect v0.0.0-20181019110701-3d6f0b585514/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA=
|
||||
github.com/gobuffalo/flect v0.0.0-20181024204909-8f6be1a8c6c2/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA=
|
||||
github.com/gobuffalo/flect v0.0.0-20181104133451-1f6e9779237a/go.mod h1:rCiQgmAE4axgBNl3jZWzS5rETRYTGOsrixTRaCPzNdA=
|
||||
github.com/gobuffalo/flect v0.0.0-20181114183036-47375f6d8328/go.mod h1:0HvNbHdfh+WOvDSIASqJOSxTOWSxCCUF++k/Y53v9rI=
|
||||
github.com/gobuffalo/flect v0.0.0-20181210151238-24a2b68e0316/go.mod h1:en58vff74S9b99Eg42Dr+/9yPu437QjlNsO/hBYPuOk=
|
||||
github.com/gobuffalo/flect v0.0.0-20190104192022-4af577e09bf2/go.mod h1:en58vff74S9b99Eg42Dr+/9yPu437QjlNsO/hBYPuOk=
|
||||
github.com/gobuffalo/flect v0.0.0-20190117212819-a62e61d96794/go.mod h1:397QT6v05LkZkn07oJXXT6y9FCfwC8Pug0WA2/2mE9k=
|
||||
github.com/gobuffalo/genny v0.0.0-20180924032338-7af3a40f2252/go.mod h1:tUTQOogrr7tAQnhajMSH6rv1BVev34H2sa1xNHMy94g=
|
||||
github.com/gobuffalo/genny v0.0.0-20181003150629-3786a0744c5d/go.mod h1:WAd8HmjMVrnkAZbmfgH5dLBUchsZfqzp/WS5sQz+uTM=
|
||||
github.com/gobuffalo/genny v0.0.0-20181005145118-318a41a134cc/go.mod h1:WAd8HmjMVrnkAZbmfgH5dLBUchsZfqzp/WS5sQz+uTM=
|
||||
github.com/gobuffalo/genny v0.0.0-20181007153042-b8de7d566757/go.mod h1:+oG5Ljrw04czAHbPXREwaFojJbpUvcIy4DiOnbEJFTA=
|
||||
github.com/gobuffalo/genny v0.0.0-20181012161047-33e5f43d83a6/go.mod h1:+oG5Ljrw04czAHbPXREwaFojJbpUvcIy4DiOnbEJFTA=
|
||||
github.com/gobuffalo/genny v0.0.0-20181017160347-90a774534246/go.mod h1:+oG5Ljrw04czAHbPXREwaFojJbpUvcIy4DiOnbEJFTA=
|
||||
github.com/gobuffalo/genny v0.0.0-20181024195656-51392254bf53/go.mod h1:o9GEH5gn5sCKLVB5rHFC4tq40rQ3VRUzmx6WwmaqISE=
|
||||
github.com/gobuffalo/genny v0.0.0-20181025145300-af3f81d526b8/go.mod h1:uZ1fFYvdcP8mu0B/Ynarf6dsGvp7QFIpk/QACUuFUVI=
|
||||
github.com/gobuffalo/genny v0.0.0-20181027191429-94d6cfb5c7fc/go.mod h1:x7SkrQQBx204Y+O9EwRXeszLJDTaWN0GnEasxgLrQTA=
|
||||
github.com/gobuffalo/genny v0.0.0-20181027195209-3887b7171c4f/go.mod h1:JbKx8HSWICu5zyqWOa0dVV1pbbXOHusrSzQUprW6g+w=
|
||||
github.com/gobuffalo/genny v0.0.0-20181106193839-7dcb0924caf1/go.mod h1:x61yHxvbDCgQ/7cOAbJCacZQuHgB0KMSzoYcw5debjU=
|
||||
github.com/gobuffalo/genny v0.0.0-20181107223128-f18346459dbe/go.mod h1:utQD3aKKEsdb03oR+Vi/6ztQb1j7pO10N3OBoowRcSU=
|
||||
github.com/gobuffalo/genny v0.0.0-20181114215459-0a4decd77f5d/go.mod h1:kN2KZ8VgXF9VIIOj/GM0Eo7YK+un4Q3tTreKOf0q1ng=
|
||||
github.com/gobuffalo/genny v0.0.0-20181119162812-e8ff4adce8bb/go.mod h1:BA9htSe4bZwBDJLe8CUkoqkypq3hn3+CkoHqVOW718E=
|
||||
github.com/gobuffalo/genny v0.0.0-20181127225641-2d959acc795b/go.mod h1:l54xLXNkteX/PdZ+HlgPk1qtcrgeOr3XUBBPDbH+7CQ=
|
||||
github.com/gobuffalo/genny v0.0.0-20181128191930-77e34f71ba2a/go.mod h1:FW/D9p7cEEOqxYA71/hnrkOWm62JZ5ZNxcNIVJEaWBU=
|
||||
github.com/gobuffalo/genny v0.0.0-20181203165245-fda8bcce96b1/go.mod h1:wpNSANu9UErftfiaAlz1pDZclrYzLtO5lALifODyjuM=
|
||||
github.com/gobuffalo/genny v0.0.0-20181203201232-849d2c9534ea/go.mod h1:wpNSANu9UErftfiaAlz1pDZclrYzLtO5lALifODyjuM=
|
||||
github.com/gobuffalo/genny v0.0.0-20181206121324-d6fb8a0dbe36/go.mod h1:wpNSANu9UErftfiaAlz1pDZclrYzLtO5lALifODyjuM=
|
||||
github.com/gobuffalo/genny v0.0.0-20181207164119-84844398a37d/go.mod h1:y0ysCHGGQf2T3vOhCrGHheYN54Y/REj0ayd0Suf4C/8=
|
||||
github.com/gobuffalo/genny v0.0.0-20181211165820-e26c8466f14d/go.mod h1:sHnK+ZSU4e2feXP3PA29ouij6PUEiN+RCwECjCTB3yM=
|
||||
github.com/gobuffalo/genny v0.0.0-20190104222617-a71664fc38e7/go.mod h1:QPsQ1FnhEsiU8f+O0qKWXz2RE4TiDqLVChWkBuh1WaY=
|
||||
github.com/gobuffalo/genny v0.0.0-20190112155932-f31a84fcacf5/go.mod h1:CIaHCrSIuJ4il6ka3Hub4DR4adDrGoXGEEt2FbBxoIo=
|
||||
github.com/gobuffalo/github_flavored_markdown v1.0.4/go.mod h1:uRowCdK+q8d/RF0Kt3/DSalaIXbb0De/dmTqMQdkQ4I=
|
||||
github.com/gobuffalo/github_flavored_markdown v1.0.5/go.mod h1:U0643QShPF+OF2tJvYNiYDLDGDuQmJZXsf/bHOJPsMY=
|
||||
github.com/gobuffalo/github_flavored_markdown v1.0.7/go.mod h1:w93Pd9Lz6LvyQXEG6DktTPHkOtCbr+arAD5mkwMzXLI=
|
||||
github.com/gobuffalo/httptest v1.0.2/go.mod h1:7T1IbSrg60ankme0aDLVnEY0h056g9M1/ZvpVThtB7E=
|
||||
github.com/gobuffalo/licenser v0.0.0-20180924033006-eae28e638a42/go.mod h1:Ubo90Np8gpsSZqNScZZkVXXAo5DGhTb+WYFIjlnog8w=
|
||||
github.com/gobuffalo/licenser v0.0.0-20181025145548-437d89de4f75/go.mod h1:x3lEpYxkRG/XtGCUNkio+6RZ/dlOvLzTI9M1auIwFcw=
|
||||
github.com/gobuffalo/licenser v0.0.0-20181027200154-58051a75da95/go.mod h1:BzhaaxGd1tq1+OLKObzgdCV9kqVhbTulxOpYbvMQWS0=
|
||||
github.com/gobuffalo/licenser v0.0.0-20181109171355-91a2a7aac9a7/go.mod h1:m+Ygox92pi9bdg+gVaycvqE8RVSjZp7mWw75+K5NPHk=
|
||||
github.com/gobuffalo/licenser v0.0.0-20181128165715-cc7305f8abed/go.mod h1:oU9F9UCE+AzI/MueCKZamsezGOOHfSirltllOVeRTAE=
|
||||
github.com/gobuffalo/licenser v0.0.0-20181203160806-fe900bbede07/go.mod h1:ph6VDNvOzt1CdfaWC+9XwcBnlSTBz2j49PBwum6RFaU=
|
||||
github.com/gobuffalo/licenser v0.0.0-20181211173111-f8a311c51159/go.mod h1:ve/Ue99DRuvnTaLq2zKa6F4KtHiYf7W046tDjuGYPfM=
|
||||
github.com/gobuffalo/logger v0.0.0-20181022175615-46cfb361fc27/go.mod h1:8sQkgyhWipz1mIctHF4jTxmJh1Vxhp7mP8IqbljgJZo=
|
||||
github.com/gobuffalo/logger v0.0.0-20181027144941-73d08d2bb969/go.mod h1:7uGg2duHKpWnN4+YmyKBdLXfhopkAdVM6H3nKbyFbz8=
|
||||
github.com/gobuffalo/logger v0.0.0-20181027193913-9cf4dd0efe46/go.mod h1:7uGg2duHKpWnN4+YmyKBdLXfhopkAdVM6H3nKbyFbz8=
|
||||
github.com/gobuffalo/logger v0.0.0-20181109185836-3feeab578c17/go.mod h1:oNErH0xLe+utO+OW8ptXMSA5DkiSEDW1u3zGIt8F9Ew=
|
||||
github.com/gobuffalo/logger v0.0.0-20181117211126-8e9b89b7c264/go.mod h1:5etB91IE0uBlw9k756fVKZJdS+7M7ejVhmpXXiSFj0I=
|
||||
github.com/gobuffalo/logger v0.0.0-20181127160119-5b956e21995c/go.mod h1:+HxKANrR9VGw9yN3aOAppJKvhO05ctDi63w4mDnKv2U=
|
||||
github.com/gobuffalo/makr v1.1.5/go.mod h1:Y+o0btAH1kYAMDJW/TX3+oAXEu0bmSLLoC9mIFxtzOw=
|
||||
github.com/gobuffalo/mapi v1.0.0/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
|
||||
github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
|
||||
github.com/gobuffalo/meta v0.0.0-20181018155829-df62557efcd3/go.mod h1:XTTOhwMNryif3x9LkTTBO/Llrveezd71u3quLd0u7CM=
|
||||
github.com/gobuffalo/meta v0.0.0-20181018192820-8c6cef77dab3/go.mod h1:E94EPzx9NERGCY69UWlcj6Hipf2uK/vnfrF4QD0plVE=
|
||||
github.com/gobuffalo/meta v0.0.0-20181025145500-3a985a084b0a/go.mod h1:YDAKBud2FP7NZdruCSlmTmDOZbVSa6bpK7LJ/A/nlKg=
|
||||
github.com/gobuffalo/meta v0.0.0-20181114191255-b130ebedd2f7/go.mod h1:K6cRZ29ozr4Btvsqkjvg5nDFTLOgTqf03KA70Ks0ypE=
|
||||
github.com/gobuffalo/meta v0.0.0-20181127070345-0d7e59dd540b/go.mod h1:RLO7tMvE0IAKAM8wny1aN12pvEKn7EtkBLkUZR00Qf8=
|
||||
github.com/gobuffalo/meta v0.0.0-20190120163247-50bbb1fa260d/go.mod h1:KKsH44nIK2gA8p0PJmRT9GvWJUdphkDUA8AJEvFWiqM=
|
||||
github.com/gobuffalo/mw-basicauth v1.0.3/go.mod h1:dg7+ilMZOKnQFHDefUzUHufNyTswVUviCBgF244C1+0=
|
||||
github.com/gobuffalo/mw-contenttype v0.0.0-20180802152300-74f5a47f4d56/go.mod h1:7EvcmzBbeCvFtQm5GqF9ys6QnCxz2UM1x0moiWLq1No=
|
||||
github.com/gobuffalo/mw-csrf v0.0.0-20180802151833-446ff26e108b/go.mod h1:sbGtb8DmDZuDUQoxjr8hG1ZbLtZboD9xsn6p77ppcHo=
|
||||
github.com/gobuffalo/mw-forcessl v0.0.0-20180802152810-73921ae7a130/go.mod h1:JvNHRj7bYNAMUr/5XMkZaDcw3jZhUZpsmzhd//FFWmQ=
|
||||
github.com/gobuffalo/mw-i18n v0.0.0-20180802152014-e3060b7e13d6/go.mod h1:91AQfukc52A6hdfIfkxzyr+kpVYDodgAeT5cjX1UIj4=
|
||||
github.com/gobuffalo/mw-paramlogger v0.0.0-20181005191442-d6ee392ec72e/go.mod h1:6OJr6VwSzgJMqWMj7TYmRUqzNe2LXu/W1rRW4MAz/ME=
|
||||
github.com/gobuffalo/mw-tokenauth v0.0.0-20181001105134-8545f626c189/go.mod h1:UqBF00IfKvd39ni5+yI5MLMjAf4gX7cDKN/26zDOD6c=
|
||||
github.com/gobuffalo/packd v0.0.0-20181027182251-01ad393492c8/go.mod h1:SmdBdhj6uhOsg1Ui4SFAyrhuc7U4VCildosO5IDJ3lc=
|
||||
github.com/gobuffalo/packd v0.0.0-20181027190505-aafc0d02c411/go.mod h1:SmdBdhj6uhOsg1Ui4SFAyrhuc7U4VCildosO5IDJ3lc=
|
||||
github.com/gobuffalo/packd v0.0.0-20181027194105-7ae579e6d213/go.mod h1:SmdBdhj6uhOsg1Ui4SFAyrhuc7U4VCildosO5IDJ3lc=
|
||||
github.com/gobuffalo/packd v0.0.0-20181031195726-c82734870264/go.mod h1:Yf2toFaISlyQrr5TfO3h6DB9pl9mZRmyvBGQb/aQ/pI=
|
||||
github.com/gobuffalo/packd v0.0.0-20181104210303-d376b15f8e96/go.mod h1:Yf2toFaISlyQrr5TfO3h6DB9pl9mZRmyvBGQb/aQ/pI=
|
||||
github.com/gobuffalo/packd v0.0.0-20181111195323-b2e760a5f0ff/go.mod h1:Yf2toFaISlyQrr5TfO3h6DB9pl9mZRmyvBGQb/aQ/pI=
|
||||
github.com/gobuffalo/packd v0.0.0-20181114190715-f25c5d2471d7/go.mod h1:Yf2toFaISlyQrr5TfO3h6DB9pl9mZRmyvBGQb/aQ/pI=
|
||||
github.com/gobuffalo/packd v0.0.0-20181124090624-311c6248e5fb/go.mod h1:Foenia9ZvITEvG05ab6XpiD5EfBHPL8A6hush8SJ0o8=
|
||||
github.com/gobuffalo/packd v0.0.0-20181207120301-c49825f8f6f4/go.mod h1:LYc0TGKFBBFTRC9dg2pcRcMqGCTMD7T2BIMP7OBuQAA=
|
||||
github.com/gobuffalo/packd v0.0.0-20181212173646-eca3b8fd6687/go.mod h1:LYc0TGKFBBFTRC9dg2pcRcMqGCTMD7T2BIMP7OBuQAA=
|
||||
github.com/gobuffalo/packr v1.13.7/go.mod h1:KkinLIn/n6+3tVXMwg6KkNvWwVsrRAz4ph+jgpk3Z24=
|
||||
github.com/gobuffalo/packr v1.15.0/go.mod h1:t5gXzEhIviQwVlNx/+3SfS07GS+cZ2hn76WLzPp6MGI=
|
||||
github.com/gobuffalo/packr v1.15.1/go.mod h1:IeqicJ7jm8182yrVmNbM6PR4g79SjN9tZLH8KduZZwE=
|
||||
github.com/gobuffalo/packr v1.19.0/go.mod h1:MstrNkfCQhd5o+Ct4IJ0skWlxN8emOq8DsoT1G98VIU=
|
||||
github.com/gobuffalo/packr v1.20.0/go.mod h1:JDytk1t2gP+my1ig7iI4NcVaXr886+N0ecUga6884zw=
|
||||
github.com/gobuffalo/packr v1.21.0/go.mod h1:H00jGfj1qFKxscFJSw8wcL4hpQtPe1PfU2wa6sg/SR0=
|
||||
github.com/gobuffalo/packr v1.22.0/go.mod h1:Qr3Wtxr3+HuQEwWqlLnNW4t1oTvK+7Gc/Rnoi/lDFvA=
|
||||
github.com/gobuffalo/packr/v2 v2.0.0-rc.8/go.mod h1:y60QCdzwuMwO2R49fdQhsjCPv7tLQFR0ayzxxla9zes=
|
||||
github.com/gobuffalo/packr/v2 v2.0.0-rc.9/go.mod h1:fQqADRfZpEsgkc7c/K7aMew3n4aF1Kji7+lIZeR98Fc=
|
||||
github.com/gobuffalo/packr/v2 v2.0.0-rc.10/go.mod h1:4CWWn4I5T3v4c1OsJ55HbHlUEKNWMITG5iIkdr4Px4w=
|
||||
github.com/gobuffalo/packr/v2 v2.0.0-rc.11/go.mod h1:JoieH/3h3U4UmatmV93QmqyPUdf4wVM9HELaHEu+3fk=
|
||||
github.com/gobuffalo/packr/v2 v2.0.0-rc.12/go.mod h1:FV1zZTsVFi1DSCboO36Xgs4pzCZBjB/tDV9Cz/lSaR8=
|
||||
github.com/gobuffalo/packr/v2 v2.0.0-rc.13/go.mod h1:2Mp7GhBFMdJlOK8vGfl7SYtfMP3+5roE39ejlfjw0rA=
|
||||
github.com/gobuffalo/packr/v2 v2.0.0-rc.14/go.mod h1:06otbrNvDKO1eNQ3b8hst+1010UooI2MFg+B2Ze4MV8=
|
||||
github.com/gobuffalo/packr/v2 v2.0.0-rc.15/go.mod h1:IMe7H2nJvcKXSF90y4X1rjYIRlNMJYCxEhssBXNZwWs=
|
||||
github.com/gobuffalo/plush v3.7.16+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI=
|
||||
github.com/gobuffalo/plush v3.7.20+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI=
|
||||
github.com/gobuffalo/plush v3.7.21+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI=
|
||||
github.com/gobuffalo/plush v3.7.22+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI=
|
||||
github.com/gobuffalo/plush v3.7.23+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI=
|
||||
github.com/gobuffalo/plush v3.7.30+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI=
|
||||
github.com/gobuffalo/plush v3.7.31+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI=
|
||||
github.com/gobuffalo/plush v3.7.32+incompatible/go.mod h1:rQ4zdtUUyZNqULlc6bqd5scsPfLKfT0+TGMChgduDvI=
|
||||
github.com/gobuffalo/plushgen v0.0.0-20181128164830-d29dcb966cb2/go.mod h1:r9QwptTFnuvSaSRjpSp4S2/4e2D3tJhARYbvEBcKSb4=
|
||||
github.com/gobuffalo/plushgen v0.0.0-20181203163832-9fc4964505c2/go.mod h1:opEdT33AA2HdrIwK1aibqnTJDVVKXC02Bar/GT1YRVs=
|
||||
github.com/gobuffalo/plushgen v0.0.0-20181207152837-eedb135bd51b/go.mod h1:Lcw7HQbEVm09sAQrCLzIxuhFbB3nAgp4c55E+UlynR0=
|
||||
github.com/gobuffalo/plushgen v0.0.0-20190104222512-177cd2b872b3/go.mod h1:tYxCozi8X62bpZyKXYHw1ncx2ZtT2nFvG42kuLwYjoc=
|
||||
github.com/gobuffalo/pop v4.8.2+incompatible/go.mod h1:DwBz3SD5SsHpTZiTubcsFWcVDpJWGsxjVjMPnkiThWg=
|
||||
github.com/gobuffalo/pop v4.8.3+incompatible/go.mod h1:DwBz3SD5SsHpTZiTubcsFWcVDpJWGsxjVjMPnkiThWg=
|
||||
github.com/gobuffalo/pop v4.8.4+incompatible/go.mod h1:DwBz3SD5SsHpTZiTubcsFWcVDpJWGsxjVjMPnkiThWg=
|
||||
github.com/gobuffalo/release v1.0.35/go.mod h1:VtHFAKs61vO3wboCec5xr9JPTjYyWYcvaM3lclkc4x4=
|
||||
github.com/gobuffalo/release v1.0.38/go.mod h1:VtHFAKs61vO3wboCec5xr9JPTjYyWYcvaM3lclkc4x4=
|
||||
github.com/gobuffalo/release v1.0.42/go.mod h1:RPs7EtafH4oylgetOJpGP0yCZZUiO4vqHfTHJjSdpug=
|
||||
github.com/gobuffalo/release v1.0.52/go.mod h1:RPs7EtafH4oylgetOJpGP0yCZZUiO4vqHfTHJjSdpug=
|
||||
github.com/gobuffalo/release v1.0.53/go.mod h1:FdF257nd8rqhNaqtDWFGhxdJ/Ig4J7VcS3KL7n/a+aA=
|
||||
github.com/gobuffalo/release v1.0.54/go.mod h1:Pe5/RxRa/BE8whDpGfRqSI7D1a0evGK1T4JDm339tJc=
|
||||
github.com/gobuffalo/release v1.0.61/go.mod h1:mfIO38ujUNVDlBziIYqXquYfBF+8FDHUjKZgYC1Hj24=
|
||||
github.com/gobuffalo/release v1.0.72/go.mod h1:NP5NXgg/IX3M5XmHmWR99D687/3Dt9qZtTK/Lbwc1hU=
|
||||
github.com/gobuffalo/release v1.1.1/go.mod h1:Sluak1Xd6kcp6snkluR1jeXAogdJZpFFRzTYRs/2uwg=
|
||||
github.com/gobuffalo/release v1.1.3/go.mod h1:CuXc5/m+4zuq8idoDt1l4va0AXAn/OSs08uHOfMVr8E=
|
||||
github.com/gobuffalo/release v1.1.6/go.mod h1:18naWa3kBsqO0cItXZNJuefCKOENpbbUIqRL1g+p6z0=
|
||||
github.com/gobuffalo/shoulders v1.0.1/go.mod h1:V33CcVmaQ4gRUmHKwq1fiTXuf8Gp/qjQBUL5tHPmvbA=
|
||||
github.com/gobuffalo/syncx v0.0.0-20181120191700-98333ab04150/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
|
||||
github.com/gobuffalo/syncx v0.0.0-20181120194010-558ac7de985f/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
|
||||
github.com/gobuffalo/tags v2.0.11+incompatible/go.mod h1:9XmhOkyaB7UzvuY4UoZO4s67q8/xRMVJEaakauVQYeY=
|
||||
github.com/gobuffalo/tags v2.0.14+incompatible/go.mod h1:9XmhOkyaB7UzvuY4UoZO4s67q8/xRMVJEaakauVQYeY=
|
||||
github.com/gobuffalo/tags v2.0.15+incompatible/go.mod h1:9XmhOkyaB7UzvuY4UoZO4s67q8/xRMVJEaakauVQYeY=
|
||||
github.com/gobuffalo/uuid v2.0.3+incompatible/go.mod h1:ErhIzkRhm0FtRuiE/PeORqcw4cVi1RtSpnwYrxuvkfE=
|
||||
github.com/gobuffalo/uuid v2.0.4+incompatible/go.mod h1:ErhIzkRhm0FtRuiE/PeORqcw4cVi1RtSpnwYrxuvkfE=
|
||||
github.com/gobuffalo/uuid v2.0.5+incompatible/go.mod h1:ErhIzkRhm0FtRuiE/PeORqcw4cVi1RtSpnwYrxuvkfE=
|
||||
github.com/gobuffalo/validate v2.0.3+incompatible/go.mod h1:N+EtDe0J8252BgfzQUChBgfd6L93m9weay53EWFVsMM=
|
||||
github.com/gobuffalo/x v0.0.0-20181003152136-452098b06085/go.mod h1:WevpGD+5YOreDJznWevcn8NTmQEW5STSBgIkpkjzqXc=
|
||||
github.com/gobuffalo/x v0.0.0-20181007152206-913e47c59ca7/go.mod h1:9rDPXaB3kXdKWzMc4odGQQdG2e2DIEmANy5aSJ9yesY=
|
||||
github.com/gofrs/uuid v3.1.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
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/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/golang/gddo v0.0.0-20180828051604-96d2a289f41e/go.mod h1:xEhNfoBDX1hzLm2Nf80qUvZ2sVwoMZ8d6IE2SrsQfh4=
|
||||
github.com/golang/gddo v0.0.0-20190904175337-72a348e765d2/go.mod h1:xEhNfoBDX1hzLm2Nf80qUvZ2sVwoMZ8d6IE2SrsQfh4=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
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/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7 h1:5ZkaAPbicIKTF2I64qf5Fh8Aa83Q/dnOafMYV0OMwjA=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/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 v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
|
@ -104,6 +317,7 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
|
|||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
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 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
|
||||
|
@ -113,16 +327,31 @@ github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
|
|||
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/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.0 h1:Jf4mxPC/ziBnoPIdpQdPJ9OeiomAUHLvxmPRSPH9m4s=
|
||||
github.com/google/uuid v1.1.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
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/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk=
|
||||
github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181004151105-1babbf986f6f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20190328170749-bb2674552d8f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1/go.mod h1:YeAe0gNeiNT5hoiZRI4yiOky6jVdNvfO2N6Kav/HmxY=
|
||||
github.com/gorilla/rpc v1.2.0/go.mod h1:V4h9r+4sF5HnzqbwIez0fKSpANP0zlYd3qR7p36jkTQ=
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/gorilla/sessions v1.1.2/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w=
|
||||
github.com/gorilla/sessions v1.1.3/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/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.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
|
@ -149,6 +378,7 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
|
|||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
|
||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/raft v1.1.1-0.20190703171940-f639636d18e0/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8=
|
||||
github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk=
|
||||
|
@ -156,22 +386,34 @@ github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoI
|
|||
github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M=
|
||||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=
|
||||
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
|
||||
github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
|
||||
github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmoiron/sqlx v0.0.0-20180614180643-0dae4fefe7c0/go.mod h1:IiEW3SEiiErVyFdH8NTuWjSifiEQKUoyK3LNqr2kCHU=
|
||||
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
|
||||
github.com/joho/godotenv v1.2.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
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/karrick/godirwalk v1.7.5/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34=
|
||||
github.com/karrick/godirwalk v1.7.7/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34=
|
||||
github.com/karrick/godirwalk v1.7.8/go.mod h1:2c9FRhkDxdIbgkOnCEvnSWs71Bhugbl46shStcFDJ34=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
|
@ -182,27 +424,60 @@ github.com/klauspost/cpuid v1.2.2/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgo
|
|||
github.com/klauspost/pgzip v1.2.1/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/klauspost/readahead v1.3.1/go.mod h1:AH9juHzNH7xqdqFHrMRSHeH2Ps+vFf+kblDqzPFiLJg=
|
||||
github.com/klauspost/reedsolomon v1.9.3/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
|
||||
github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/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 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kurin/blazer v0.5.4-0.20190613185654-cf2f27cc0be3/go.mod h1:4FCXMUWo9DllR2Do4TtBd377ezyAJ51vB5uTBjt0pGU=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/luna-duclos/instrumentedsql v1.1.2/go.mod h1:4LGbEqDnopzNAiyxPPDXhLspyunZxgPTMJBKtC6U0BQ=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20180730094502-03f2033d19d5/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/markbates/deplist v1.0.4/go.mod h1:gRRbPbbuA8TmMiRvaOzUlRfzfjeCCBqX2A6arxN01MM=
|
||||
github.com/markbates/deplist v1.0.5/go.mod h1:gRRbPbbuA8TmMiRvaOzUlRfzfjeCCBqX2A6arxN01MM=
|
||||
github.com/markbates/going v1.0.2/go.mod h1:UWCk3zm0UKefHZ7l8BNqi26UyiEMniznk8naLdTcy6c=
|
||||
github.com/markbates/grift v1.0.4/go.mod h1:wbmtW74veyx+cgfwFhlnnMWqhoz55rnHR47oMXzsyVs=
|
||||
github.com/markbates/hmax v1.0.0/go.mod h1:cOkR9dktiESxIMu+65oc/r/bdY4bE8zZw3OLhLx0X2c=
|
||||
github.com/markbates/inflect v1.0.0/go.mod h1:oTeZL2KHA7CUX6X+fovmK9OvIOFuqu0TwdQrZjLTh88=
|
||||
github.com/markbates/inflect v1.0.1/go.mod h1:uv3UVNBe5qBIfCm8O8Q+DW+S1EopeyINj+Ikhc7rnCk=
|
||||
github.com/markbates/inflect v1.0.3/go.mod h1:1fR9+pO2KHEO9ZRtto13gDwwZaAKstQzferVeWqbgNs=
|
||||
github.com/markbates/inflect v1.0.4/go.mod h1:1fR9+pO2KHEO9ZRtto13gDwwZaAKstQzferVeWqbgNs=
|
||||
github.com/markbates/oncer v0.0.0-20180924031910-e862a676800b/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
|
||||
github.com/markbates/oncer v0.0.0-20180924034138-723ad0170a46/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
|
||||
github.com/markbates/oncer v0.0.0-20181014194634-05fccaae8fc4/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
|
||||
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
|
||||
github.com/markbates/refresh v1.4.10/go.mod h1:NDPHvotuZmTmesXxr95C9bjlw1/0frJwtME2dzcVKhc=
|
||||
github.com/markbates/safe v1.0.0/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
|
||||
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
|
||||
github.com/markbates/sigtx v1.0.0/go.mod h1:QF1Hv6Ic6Ca6W+T+DL0Y/ypborFKyvUY9HmuCD4VeTc=
|
||||
github.com/markbates/willie v1.0.9/go.mod h1:fsrFVWl91+gXpx/6dv715j7i11fYPfZ9ZGfH0DQzY7w=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190805055040-f9202b1cfdeb/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
|
||||
github.com/miekg/dns v1.1.8/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/minio/cli v1.22.0/go.mod h1:bYxnK0uS629N3Bq+AOZZ+6lwF77Sodk4+UL9vNuXhOY=
|
||||
github.com/minio/gokrb5/v7 v7.2.5/go.mod h1:z6fE6twrvMN004M+KRTHnmtfpxsBIztP0PVsak0/4f8=
|
||||
|
@ -217,10 +492,13 @@ github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl
|
|||
github.com/minio/sio v0.2.0/go.mod h1:nKM5GIWSrqbOZp0uhyj6M1iA0X6xQzSGtYSaTKSCut0=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||
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 v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/mitchellh/mapstructure v1.0.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
|
@ -230,6 +508,9 @@ github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lN
|
|||
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/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||
github.com/monoculum/formam v0.0.0-20180901015400-4e68be1d79ba/go.mod h1:RKgILGEJq24YyJ2ban8EO0RUVSJlF1pGsEvoLEACr/Q=
|
||||
github.com/moul/http2curl v0.0.0-20170919181001-9ac6cf4d929b/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
|
||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nats-io/gnatsd v1.4.1/go.mod h1:nqco77VO78hLCJpIcVfygDP2rPGfsEHkGTUk94uh5DQ=
|
||||
|
@ -246,20 +527,51 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi
|
|||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/nats-io/stan.go v0.4.5/go.mod h1:Ji7mK6gRZJSH1nc3ZJH6vi7zn/QnZhpR9Arm4iuzsUQ=
|
||||
github.com/ncw/directio v1.0.5/go.mod h1:rX/pKEYkOXBGOggmcyJeJGloCkleSvphPx2eV3t6ROk=
|
||||
github.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q=
|
||||
github.com/nsqio/go-nsq v1.0.7/go.mod h1:XP5zaUs3pqf+Q71EqUJs3HYfBIqfK6G83WQMdNN+Ito=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/oleiade/reflections v1.0.0/go.mod h1:RbATFBbKYkVdqmSFtx13Bb/tVhR0lgOBXunWTZKeL4w=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c h1:Hww8mOyEKTeON4bZn7FrlLismspbPc1teNRUVH7wLQ8=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c h1:eSfnfIuwhxZyULg1NNuZycJcYkjYVGYe7FczwQReM6U=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs=
|
||||
github.com/ory/fosite v0.29.0/go.mod h1:0atSZmXO7CAcs6NPMI/Qtot8tmZYj04Nddoold4S2h0=
|
||||
github.com/ory/go-acc v0.0.0-20181118080137-ddc355013f90/go.mod h1:sxnvPCxChFuSmTJGj8FdMupeq1BezCiEpDjTUXQ4hf4=
|
||||
github.com/ory/go-acc v0.1.0 h1:ibxdv3n2k4cqh0VXWa9RHARtbR7tcT7jsnSnmGZkDIM=
|
||||
github.com/ory/go-acc v0.1.0/go.mod h1:0omgy2aa3nDBJ45VAKeLHH8ccPBudxLeic4xiDRtug0=
|
||||
github.com/ory/go-convenience v0.1.0/go.mod h1:uEY/a60PL5c12nYz4V5cHY03IBmwIAEm8TWB0yn9KNs=
|
||||
github.com/ory/gojsonreference v0.0.0-20190720135523-6b606c2d8ee8/go.mod h1:wsH1C4nIeeQClDtD5AH7kF1uTS6zWyqfjVDTmB0Em7A=
|
||||
github.com/ory/gojsonschema v1.1.1-0.20190919112458-f254ca73d5e9/go.mod h1:BNZpdJgB74KOLSsWFvzw6roXg1I6O51WO8roMmW+T7Y=
|
||||
github.com/ory/herodot v0.6.2/go.mod h1:3BOneqcyBsVybCPAJoi92KN2BpJHcmDqAMcAAaJiJow=
|
||||
github.com/ory/viper v1.5.6/go.mod h1:TYmpFpKLxjQwvT4f0QPpkOn4sDXU1kDgAwJpgLYiQ28=
|
||||
github.com/ory/x v0.0.85 h1:AslLr2Efv6f7AT1tzn0RuX+sOri6h74phSh5lSeMqC4=
|
||||
github.com/ory/x v0.0.85/go.mod h1:s44V8t3xyjWZREcU+mWlp4h302rTuM4aLXcW+y5FbQ8=
|
||||
github.com/parnurzeal/gorequest v0.2.15/go.mod h1:3Kh2QUMJoqw3icWAecsyzkpY7UzRfDhbRdTjtNwNiUE=
|
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pborman/getopt v0.0.0-20180729010549-6fdd0a2c7117/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
|
||||
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg=
|
||||
github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pierrec/lz4 v2.2.6+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
|
@ -267,43 +579,85 @@ github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndr
|
|||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
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-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
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-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/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/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20190704165056-9c2d0518ed81/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.0.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/rubenv/sql-migrate v0.0.0-20190212093014-1007f53448d7/go.mod h1:WS0rl9eEliYI8DPnr3TOwz4439pay+qNgzJoVya/DmY=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
|
||||
github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4=
|
||||
github.com/santhosh-tekuri/jsonschema/v2 v2.1.0/go.mod h1:yzJzKUGV4RbWqWIBBP4wSOBqavX5saE02yirLS0OTyg=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/secure-io/sio-go v0.3.0/go.mod h1:D3KmXgKETffyYxBdFRN+Hpd2WzhzqS0EQwT3XWsAcBU=
|
||||
github.com/segmentio/analytics-go v3.0.1+incompatible/go.mod h1:C7CYBtQWk4vRk2RyLu0qOcbHJ18E3F1HV2C/8JvKN48=
|
||||
github.com/segmentio/backo-go v0.0.0-20160424052352-204274ad699c/go.mod h1:kJ9mm9YmoWSkk+oQ+5Cj8DEoRCX2JT6As4kEtIIOp1M=
|
||||
github.com/serenize/snaker v0.0.0-20171204205717-a683aaf2d516/go.mod h1:Yow6lPLSAXx2ifx470yD/nUe22Dv5vBvxK/UK9UUTVs=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shirou/gopsutil v2.18.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
|
||||
github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU=
|
||||
github.com/shurcooL/highlight_go v0.0.0-20170515013102-78fb10f4a5f8/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag=
|
||||
github.com/shurcooL/octicon v0.0.0-20180602230221-c42b0e3b24d9/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ=
|
||||
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.1.0/go.mod h1:zrgwTnHtNr00buQ1vSptGe8m1f/BbgsPukg8qsT7A+A=
|
||||
github.com/sirupsen/logrus v1.1.1/go.mod h1:zrgwTnHtNr00buQ1vSptGe8m1f/BbgsPukg8qsT7A+A=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/skyrings/skyring-common v0.0.0-20160929130248-d1c0bb1cbd5e/go.mod h1:d8hQseuYt4rJoOo21lFzYJdhMjmDqLY++ayArbgYjWI=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v0.0.0-20190401211740-f487f9de1cd3/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM=
|
||||
github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
|
||||
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
|
||||
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/afero v1.2.0/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=
|
||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
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.2.1/go.mod h1:P4AexN0a+C9tGAnUFNwDMYYZv3pjFuvmeiMyKRaNVlI=
|
||||
github.com/spf13/viper v1.3.1/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
|
@ -312,63 +666,113 @@ github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRci
|
|||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
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/subosito/gotenv v1.1.1/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5 h1:hNna6Fi0eP1f2sMBe/rJicDmaHmoXGe1Ta84FPYHLuE=
|
||||
github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5/go.mod h1:f1SCnEOt6sc3fOJfPQDRDzHOtSXuTtnz0ImG9kPRDV0=
|
||||
github.com/tidwall/gjson v1.3.2/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
|
||||
github.com/tidwall/gjson v1.3.5/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
|
||||
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tidwall/sjson v1.0.4/go.mod h1:bURseu1nuBkFpIES5cz6zBtjmYeOQmEESshn7VpF15Y=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||
github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
|
||||
github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ugorji/go v1.1.5-pre/go.mod h1:FwP/aQVg39TXzItUBMwnWp9T9gPQnXw4Poh4/oBQZ/0=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/ugorji/go/codec v1.1.5-pre/go.mod h1:tULtS6Gy1AE1yCENaw4Vb//HLH5njI2tfCQDUqRd8fI=
|
||||
github.com/unrolled/secure v0.0.0-20180918153822-f340ee86eb8b/go.mod h1:mnPT77IAdsi/kV7+Es7y+pXALeV3h7G6dQF6mNYjcLA=
|
||||
github.com/unrolled/secure v0.0.0-20181005190816-ff9db2ff917f/go.mod h1:mnPT77IAdsi/kV7+Es7y+pXALeV3h7G6dQF6mNYjcLA=
|
||||
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
|
||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c/go.mod h1:UrdRz5enIKZ63MEE3IF9l2/ebyx59GyGgPi+tICQdmM=
|
||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.3/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.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
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-20180830192347-182538f80094/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181001203147-e3636079e1a4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181015023909-0c41d7ab0a0e/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181024171144-74cb1d3d52f4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181025113841-85e1b3f9139a/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181106171534-e4dc69e5b2fd/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190102171810-8d7daa0c54b3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc/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-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200109152110-61a87790db17 h1:nVJ3guKA9qdkEQ3TUdXI9QSINo2CUPM/cySEvw2w8I0=
|
||||
golang.org/x/crypto v0.0.0-20200109152110-61a87790db17/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
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/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180816102801-aaf60122140d/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-20180921000356-2f5d2388922f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180926154720-4dfa2610cdf3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181017193950-04a2e542c03f/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-20181102091132-c10e9556a7bc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181106065722-10aee1819953/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-20181207154023-610586996380/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-20190125091013-d26f9f9a57f3/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-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
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-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181003184128-c57b0facaced/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-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -377,23 +781,46 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
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-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180816055513-1c9583448a9c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
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-20180831094639-fa5fdf94c789/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-20180906133057-8cf3aee42992/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-20180921163948-d47a0f339242/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180927150500-dad3d9fb7b6e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181005133103-4497e2df6f9e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181011152604-fa43e7bc11ba/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181022134430-8a28ead16f52/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181024145615-5cd93ef61a7c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181025063200-d989b31c8746/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181026064943-731415f00dce/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-20181106135930-3a76605856fd/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-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181206074257-70b957f3b65e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190102155601-82a175fd1598/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190116161447-11f53e031339/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190130150945-aca44879d564/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-20190222072716-a9d3bda3a223/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-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/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-20190523142557-0e01d883c5c5/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-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1 h1:gZpLHxUX5BdYLA08Lj4YCJNN/jk7KtquiArPoeX0WvA=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -408,36 +835,87 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqG
|
|||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/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-20181003024731-2f84ea8ef872/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181006002542-f60d9635b16a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181008205924-a2b3f7f249e9/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181013182035-5e66757b835f/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181017214349-06f26fdaaa28/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181024171208-a2dc47679d30/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181026183834-f60e5f99f081/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181105230042-78dc5bac0cac/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181107215632-34b416bd17b3/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181114190951-94339b83286c/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181119130350-139d099f6620/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181127195227-b4e97c0ed882/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181127232545-e782529d0ddd/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181203210056-e5f3ab76ea4b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181205224935-3576414c54a4/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181206194817-bcd4e47d0288/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181207183836-8bc39b988060/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181212172921-837e80568c09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190102213336-ca9055ed7d04/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190104182027-498d95493402/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190111214448-fc1d57b08d7b/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-20190118193359-16909d206f00/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-20190624190245-7f2218787638/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-20190711191110-9a621aea19f8/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.5.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/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
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.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
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-20190404172233-64821d5d2107/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-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190513181449-d00d292a067c/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||
google.golang.org/genproto v0.0.0-20190626174449-989357319d63/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||
google.golang.org/genproto v0.0.0-20190708153700-3bdd9d9f5532/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||
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/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
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.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
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/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
||||
gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
|
@ -448,9 +926,13 @@ gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mN
|
|||
gopkg.in/jcmturner/gokrb5.v7 v7.2.3/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
|
||||
gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
|
||||
gopkg.in/ldap.v3 v3.0.3/go.mod h1:oxD7NyBuxchC+SgJDE1Q5Od05eGt29SDQVBmV+HYbzw=
|
||||
gopkg.in/mail.v2 v2.0.0-20180731213649-a0242b2233b4/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw=
|
||||
gopkg.in/olivere/elastic.v5 v5.0.80/go.mod h1:uhHoB4o3bvX5sorxBU29rPcmBQdV2Qfg0FBrx5D6pV0=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/square/go-jose.v2 v2.1.9/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
|
||||
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=
|
||||
|
@ -462,6 +944,7 @@ gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
|||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
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=
|
||||
k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b h1:aBGgKJUM9Hk/3AE8WaZIApnTxG35kbuQba2w+SXqezo=
|
||||
k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
|
||||
|
@ -478,6 +961,7 @@ k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a h1:UcxjrRMyNx/i/y8G7kPvLy
|
|||
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
|
||||
k8s.io/utils v0.0.0-20200109141947-94aeca20bf09 h1:sz6xjn8QP74104YNmJpzLbJ+a3ZtHt0tkD0g8vpdWNw=
|
||||
k8s.io/utils v0.0.0-20200109141947-94aeca20bf09/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
||||
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
|
|
|
@ -22,8 +22,11 @@ func Resource(resource string) schema.GroupResource {
|
|||
}
|
||||
|
||||
var (
|
||||
// SchemeBuilder builds the scheme
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
|
||||
// AddToScheme adds all types of this clientset into the given scheme
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// Adds the list of known types to Scheme.
|
||||
|
|
|
@ -43,7 +43,7 @@ type RequestInfo struct {
|
|||
type GenerateRequestStatus struct {
|
||||
State GenerateRequestState `json:"state"`
|
||||
Message string `json:"message,omitempty"`
|
||||
// This will track the resoruces that are generated by the generate Policy
|
||||
// This will track the resources that are generated by the generate Policy
|
||||
// Will be used during clean up resources
|
||||
GeneratedResources []ResourceSpec `json:"generatedResources,omitempty"`
|
||||
}
|
||||
|
@ -143,19 +143,25 @@ type Rule struct {
|
|||
Generation Generation `json:"generate,omitempty"`
|
||||
}
|
||||
|
||||
//Condition defines the evaluation condition
|
||||
type Condition struct {
|
||||
Key interface{} `json:"key"`
|
||||
Operator ConditionOperator `json:"operator"`
|
||||
Value interface{} `json:"value"`
|
||||
}
|
||||
|
||||
// ConditionOperator defines the type for condition operator
|
||||
type ConditionOperator string
|
||||
|
||||
const (
|
||||
Equal ConditionOperator = "Equal"
|
||||
//Equal for Equal operator
|
||||
Equal ConditionOperator = "Equal"
|
||||
//NotEqual for NotEqual operator
|
||||
NotEqual ConditionOperator = "NotEqual"
|
||||
In ConditionOperator = "In"
|
||||
NotIn ConditionOperator = "NotIn"
|
||||
//In for In operator
|
||||
In ConditionOperator = "In"
|
||||
//NotIn for NotIn operator
|
||||
NotIn ConditionOperator = "NotIn"
|
||||
)
|
||||
|
||||
//MatchResources contains resource description of the resources that the rule is to apply on
|
||||
|
@ -235,7 +241,7 @@ type PolicyStatus struct {
|
|||
// average time required to process the policy Validation rules on a resource
|
||||
AvgExecutionTimeGeneration string `json:"averageGenerationRulesExecutionTime"`
|
||||
// statistics per rule
|
||||
Rules []RuleStats `json:"ruleStatus`
|
||||
Rules []RuleStats `json:"ruleStatus"`
|
||||
}
|
||||
|
||||
//RuleStats provides status per rule
|
||||
|
@ -254,7 +260,7 @@ type RuleStats struct {
|
|||
|
||||
// PolicyList is a list of Policy resources
|
||||
|
||||
// PolicyViolation stores the information regarinding the resources for which a policy failed to apply
|
||||
// PolicyViolationTemplate stores the information regarinding the resources for which a policy failed to apply
|
||||
type PolicyViolationTemplate struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
|
|
@ -2,6 +2,7 @@ package v1
|
|||
|
||||
import "reflect"
|
||||
|
||||
//HasMutateOrValidateOrGenerate checks for rule types
|
||||
func (p ClusterPolicy) HasMutateOrValidateOrGenerate() bool {
|
||||
for _, rule := range p.Spec.Rules {
|
||||
if rule.HasMutate() || rule.HasValidate() || rule.HasGenerate() {
|
||||
|
@ -11,14 +12,17 @@ func (p ClusterPolicy) HasMutateOrValidateOrGenerate() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
//HasMutate checks for mutate rule
|
||||
func (r Rule) HasMutate() bool {
|
||||
return !reflect.DeepEqual(r.Mutation, Mutation{})
|
||||
}
|
||||
|
||||
//HasValidate checks for validate rule
|
||||
func (r Rule) HasValidate() bool {
|
||||
return !reflect.DeepEqual(r.Validation, Validation{})
|
||||
}
|
||||
|
||||
//HasGenerate checks for generate rule
|
||||
func (r Rule) HasGenerate() bool {
|
||||
return !reflect.DeepEqual(r.Generation, Generation{})
|
||||
}
|
||||
|
|
|
@ -18,24 +18,27 @@ const (
|
|||
DefaultResync time.Duration = 60 * time.Second
|
||||
)
|
||||
|
||||
// LastReqTime
|
||||
// LastReqTime stores the lastrequest times for incoming api-requests
|
||||
type LastReqTime struct {
|
||||
t time.Time
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
//Time returns the lastrequest time
|
||||
func (t *LastReqTime) Time() time.Time {
|
||||
t.mu.RLock()
|
||||
defer t.mu.RUnlock()
|
||||
return t.t
|
||||
}
|
||||
|
||||
//SetTime stes the lastrequest time
|
||||
func (t *LastReqTime) SetTime(tm time.Time) {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
t.t = tm
|
||||
}
|
||||
|
||||
//NewLastReqTime returns a new instance of LastRequestTime store
|
||||
func NewLastReqTime() *LastReqTime {
|
||||
return &LastReqTime{
|
||||
t: time.Now(),
|
||||
|
@ -62,9 +65,8 @@ func (t *LastReqTime) Run(pLister kyvernolister.ClusterPolicyLister, eventGen ev
|
|||
glog.V(2).Infof("starting default resync for webhook checker with resync time %d nanoseconds", defaultResync)
|
||||
maxDeadline := deadline * time.Duration(MaxRetryCount)
|
||||
ticker := time.NewTicker(defaultResync)
|
||||
var statuscontrol StatusInterface
|
||||
/// interface to update and increment kyverno webhook status via annotations
|
||||
statuscontrol = NewVerifyControl(client, eventGen)
|
||||
statuscontrol := NewVerifyControl(client, eventGen)
|
||||
// send the initial update status
|
||||
if checkIfPolicyWithMutateAndGenerateExists(pLister) {
|
||||
if err := statuscontrol.SuccessStatus(); err != nil {
|
||||
|
@ -73,8 +75,8 @@ func (t *LastReqTime) Run(pLister kyvernolister.ClusterPolicyLister, eventGen ev
|
|||
}
|
||||
|
||||
defer ticker.Stop()
|
||||
// - has recieved request -> set webhookstatus as "True"
|
||||
// - no requests recieved
|
||||
// - has received request -> set webhookstatus as "True"
|
||||
// - no requests received
|
||||
// -> if greater than deadline, send update request
|
||||
// -> if greater than maxDeadline, send failed status update
|
||||
for {
|
||||
|
@ -88,8 +90,8 @@ func (t *LastReqTime) Run(pLister kyvernolister.ClusterPolicyLister, eventGen ev
|
|||
// get current time
|
||||
timeDiff := time.Since(t.Time())
|
||||
if timeDiff > maxDeadline {
|
||||
glog.Infof("failed to recieve any request for more than %v ", maxDeadline)
|
||||
glog.Info("Admission Control failing: Webhook is not recieving requests forwarded by api-server as per webhook configurations")
|
||||
glog.Infof("failed to receive any request for more than %v ", maxDeadline)
|
||||
glog.Info("Admission Control failing: Webhook is not receiving requests forwarded by api-server as per webhook configurations")
|
||||
// set the status unavailable
|
||||
if err := statuscontrol.FailedStatus(); err != nil {
|
||||
glog.Error(err)
|
||||
|
@ -97,7 +99,7 @@ func (t *LastReqTime) Run(pLister kyvernolister.ClusterPolicyLister, eventGen ev
|
|||
continue
|
||||
}
|
||||
if timeDiff > deadline {
|
||||
glog.Info("Admission Control failing: Webhook is not recieving requests forwarded by api-server as per webhook configurations")
|
||||
glog.Info("Admission Control failing: Webhook is not receiving requests forwarded by api-server as per webhook configurations")
|
||||
// send request to update the kyverno deployment
|
||||
if err := statuscontrol.IncrementAnnotation(); err != nil {
|
||||
glog.Error(err)
|
||||
|
|
|
@ -53,6 +53,9 @@ type PolicyViolationNamespaceListerExpansion interface{}
|
|||
// as the lister is specific to a gvk we can harcode the values here
|
||||
func (pvl *clusterPolicyViolationLister) ListResources(selector labels.Selector) (ret []*kyvernov1.ClusterPolicyViolation, err error) {
|
||||
policyviolations, err := pvl.List(selector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for index := range policyviolations {
|
||||
policyviolations[index].SetGroupVersionKind(kyvernov1.SchemeGroupVersion.WithKind("ClusterPolicyViolation"))
|
||||
}
|
||||
|
|
|
@ -8,73 +8,87 @@ import (
|
|||
clientcmd "k8s.io/client-go/tools/clientcmd"
|
||||
)
|
||||
|
||||
const (
|
||||
// These constants MUST be equal to the corresponding names in service definition in definitions/install.yaml
|
||||
KubePolicyNamespace = "kyverno"
|
||||
WebhookServiceName = "kyverno-svc"
|
||||
// These constants MUST be equal to the corresponding names in service definition in definitions/install.yaml
|
||||
|
||||
MutatingWebhookConfigurationName = "kyverno-resource-mutating-webhook-cfg"
|
||||
const (
|
||||
//KubePolicyNamespace default kyverno namespace
|
||||
KubePolicyNamespace = "kyverno"
|
||||
//WebhookServiceName default kyverno webhook service name
|
||||
WebhookServiceName = "kyverno-svc"
|
||||
|
||||
//MutatingWebhookConfigurationName default resource mutating webhook configuration name
|
||||
MutatingWebhookConfigurationName = "kyverno-resource-mutating-webhook-cfg"
|
||||
//MutatingWebhookConfigurationDebugName default resource mutating webhook configuration name for debug mode
|
||||
MutatingWebhookConfigurationDebugName = "kyverno-resource-mutating-webhook-cfg-debug"
|
||||
MutatingWebhookName = "nirmata.kyverno.resource.mutating-webhook"
|
||||
//MutatingWebhookName default resource mutating webhook name
|
||||
MutatingWebhookName = "nirmata.kyverno.resource.mutating-webhook"
|
||||
|
||||
// ValidatingWebhookConfigurationName = "kyverno-validating-webhook-cfg"
|
||||
// ValidatingWebhookConfigurationDebug = "kyverno-validating-webhook-cfg-debug"
|
||||
// ValidatingWebhookName = "nirmata.kyverno.policy-validating-webhook"
|
||||
|
||||
VerifyMutatingWebhookConfigurationName = "kyverno-verify-mutating-webhook-cfg"
|
||||
//VerifyMutatingWebhookConfigurationName default verify mutating webhook configuration name
|
||||
VerifyMutatingWebhookConfigurationName = "kyverno-verify-mutating-webhook-cfg"
|
||||
//VerifyMutatingWebhookConfigurationDebugName default verify mutating webhook configuration name for debug mode
|
||||
VerifyMutatingWebhookConfigurationDebugName = "kyverno-verify-mutating-webhook-cfg-debug"
|
||||
VerifyMutatingWebhookName = "nirmata.kyverno.verify-mutating-webhook"
|
||||
//VerifyMutatingWebhookName default verify mutating webhook name
|
||||
VerifyMutatingWebhookName = "nirmata.kyverno.verify-mutating-webhook"
|
||||
|
||||
PolicyValidatingWebhookConfigurationName = "kyverno-policy-validating-webhook-cfg"
|
||||
//PolicyValidatingWebhookConfigurationName default policy validating webhook configuration name
|
||||
PolicyValidatingWebhookConfigurationName = "kyverno-policy-validating-webhook-cfg"
|
||||
//PolicyValidatingWebhookConfigurationDebugName default policy validating webhook configuration name for debug mode
|
||||
PolicyValidatingWebhookConfigurationDebugName = "kyverno-policy-validating-webhook-cfg-debug"
|
||||
PolicyValidatingWebhookName = "nirmata.kyverno.policy-validating-webhook"
|
||||
//PolicyValidatingWebhookName default policy validating webhook name
|
||||
PolicyValidatingWebhookName = "nirmata.kyverno.policy-validating-webhook"
|
||||
|
||||
PolicyMutatingWebhookConfigurationName = "kyverno-policy-mutating-webhook-cfg"
|
||||
//PolicyMutatingWebhookConfigurationName default policy mutating webhook configuration name
|
||||
PolicyMutatingWebhookConfigurationName = "kyverno-policy-mutating-webhook-cfg"
|
||||
//PolicyMutatingWebhookConfigurationDebugName default policy mutating webhook configuration name for debug mode
|
||||
PolicyMutatingWebhookConfigurationDebugName = "kyverno-policy-mutating-webhook-cfg-debug"
|
||||
PolicyMutatingWebhookName = "nirmata.kyverno.policy-mutating-webhook"
|
||||
//PolicyMutatingWebhookName default policy mutating webhook name
|
||||
PolicyMutatingWebhookName = "nirmata.kyverno.policy-mutating-webhook"
|
||||
|
||||
// Due to kubernetes issue, we must use next literal constants instead of deployment TypeMeta fields
|
||||
// Issue: https://github.com/kubernetes/kubernetes/pull/63972
|
||||
// When the issue is closed, we should use TypeMeta struct instead of this constants
|
||||
DeploymentKind = "Deployment"
|
||||
DeploymentAPIVersion = "extensions/v1beta1"
|
||||
|
||||
// DeploymentKind define the default deployment resource kind
|
||||
DeploymentKind = "Deployment"
|
||||
|
||||
// DeploymentAPIVersion define the default deployment resource apiVersion
|
||||
DeploymentAPIVersion = "extensions/v1beta1"
|
||||
// KubePolicyDeploymentName define the default deployment namespace
|
||||
KubePolicyDeploymentName = "kyverno"
|
||||
)
|
||||
|
||||
var (
|
||||
MutatingWebhookServicePath = "/mutate"
|
||||
ValidatingWebhookServicePath = "/validate"
|
||||
//MutatingWebhookServicePath is the path for mutation webhook
|
||||
MutatingWebhookServicePath = "/mutate"
|
||||
//ValidatingWebhookServicePath is the path for validation webhook
|
||||
ValidatingWebhookServicePath = "/validate"
|
||||
//PolicyValidatingWebhookServicePath is the path for policy validation webhook(used to validate policy resource)
|
||||
PolicyValidatingWebhookServicePath = "/policyvalidate"
|
||||
PolicyMutatingWebhookServicePath = "/policymutate"
|
||||
VerifyMutatingWebhookServicePath = "/verifymutate"
|
||||
|
||||
SupportedKinds = []string{
|
||||
"ConfigMap",
|
||||
"CronJob",
|
||||
"DaemonSet",
|
||||
"Deployment",
|
||||
"Endpoints",
|
||||
"HorizontalPodAutoscaler",
|
||||
"Ingress",
|
||||
"Job",
|
||||
"LimitRange",
|
||||
"Namespace",
|
||||
"NetworkPolicy",
|
||||
"PersistentVolumeClaim",
|
||||
"PodDisruptionBudget",
|
||||
"PodTemplate",
|
||||
"ResourceQuota",
|
||||
"Secret",
|
||||
"Service",
|
||||
"StatefulSet",
|
||||
}
|
||||
//PolicyMutatingWebhookServicePath is the path for policy mutation webhook(used to default)
|
||||
PolicyMutatingWebhookServicePath = "/policymutate"
|
||||
//VerifyMutatingWebhookServicePath is the path for verify webhook(used to veryfing if admission control is enabled and active)
|
||||
VerifyMutatingWebhookServicePath = "/verifymutate"
|
||||
)
|
||||
|
||||
//LogDefaults sets default glog flags
|
||||
//LogDefaultFlags sets default glog flags
|
||||
func LogDefaultFlags() {
|
||||
flag.Set("logtostderr", "true")
|
||||
flag.Set("stderrthreshold", "WARNING")
|
||||
var err error
|
||||
err = flag.Set("logtostderr", "true")
|
||||
if err != nil {
|
||||
glog.Fatalf("failed to set flag 'logtostderr' to 'true':%v", err)
|
||||
}
|
||||
err = flag.Set("stderrthreshold", "WARNING")
|
||||
if err != nil {
|
||||
glog.Fatalf("failed to set flag 'stderrthreshold' to 'WARNING':%v", err)
|
||||
}
|
||||
flag.Set("v", "2")
|
||||
if err != nil {
|
||||
glog.Fatalf("failed to set flag 'v' to '2':%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
//CreateClientConfig creates client config
|
||||
|
|
|
@ -19,8 +19,8 @@ import (
|
|||
// read the conifgMap with name in env:INIT_CONFIG
|
||||
// this configmap stores the resources that are to be filtered
|
||||
const cmNameEnv string = "INIT_CONFIG"
|
||||
const cmDataField string = "resourceFilters"
|
||||
|
||||
// ConfigData stores the configuration
|
||||
type ConfigData struct {
|
||||
client kubernetes.Interface
|
||||
// configMap Name
|
||||
|
@ -120,7 +120,7 @@ func (cd *ConfigData) deleteCM(obj interface{}) {
|
|||
if cm.Name != cd.cmName {
|
||||
return
|
||||
}
|
||||
// remove the configuration paramaters
|
||||
// remove the configuration parameters
|
||||
cd.unload(*cm)
|
||||
}
|
||||
|
||||
|
@ -183,7 +183,7 @@ type k8Resource struct {
|
|||
Name string
|
||||
}
|
||||
|
||||
//ParseKinds parses the kinds if a single string contains comma seperated kinds
|
||||
//ParseKinds parses the kinds if a single string contains comma separated kinds
|
||||
// {"1,2,3","4","5"} => {"1","2","3","4","5"}
|
||||
func parseKinds(list string) []k8Resource {
|
||||
resources := []k8Resource{}
|
||||
|
|
|
@ -119,7 +119,7 @@ func (c *Client) submitAndApproveCertificateRequest(req *certificates.Certificat
|
|||
func (c *Client) fetchCertificateFromRequest(req *certificates.CertificateSigningRequest, maxWaitSeconds uint8) ([]byte, error) {
|
||||
// TODO: react of SIGINT and SIGTERM
|
||||
timeStart := time.Now()
|
||||
for time.Now().Sub(timeStart) < time.Duration(maxWaitSeconds)*time.Second {
|
||||
for time.Since(timeStart) < time.Duration(maxWaitSeconds)*time.Second {
|
||||
unstrR, err := c.GetResource(CSRs, "", req.ObjectMeta.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -29,7 +29,6 @@ import (
|
|||
//Client enables interaction with k8 resource
|
||||
type Client struct {
|
||||
client dynamic.Interface
|
||||
cachedClient discovery.CachedDiscoveryInterface
|
||||
clientConfig *rest.Config
|
||||
kclient kubernetes.Interface
|
||||
DiscoveryClient IDiscovery
|
||||
|
@ -63,6 +62,7 @@ func NewClient(config *rest.Config, resync time.Duration, stopCh <-chan struct{}
|
|||
return &client, nil
|
||||
}
|
||||
|
||||
//NewDynamicSharedInformerFactory returns a new instance of DynamicSharedInformerFactory
|
||||
func (c *Client) NewDynamicSharedInformerFactory(defaultResync time.Duration) dynamicinformer.DynamicSharedInformerFactory {
|
||||
return dynamicinformer.NewDynamicSharedInformerFactory(c.client, defaultResync)
|
||||
}
|
||||
|
@ -210,29 +210,17 @@ func convertToCSR(obj *unstructured.Unstructured) (*certificates.CertificateSign
|
|||
return &csr, nil
|
||||
}
|
||||
|
||||
// Waits until namespace is created with maximum duration maxWaitTimeForNamespaceCreation
|
||||
func (c *Client) waitUntilNamespaceIsCreated(name string) error {
|
||||
timeStart := time.Now()
|
||||
|
||||
var lastError error
|
||||
for time.Now().Sub(timeStart) < namespaceCreationMaxWaitTime {
|
||||
_, lastError = c.GetResource(Namespaces, "", name)
|
||||
if lastError == nil {
|
||||
break
|
||||
}
|
||||
time.Sleep(namespaceCreationWaitInterval)
|
||||
}
|
||||
return lastError
|
||||
}
|
||||
|
||||
//IDiscovery provides interface to mange Kind and GVR mapping
|
||||
type IDiscovery interface {
|
||||
GetGVRFromKind(kind string) schema.GroupVersionResource
|
||||
}
|
||||
|
||||
// SetDiscovery sets the discovery client implementation
|
||||
func (c *Client) SetDiscovery(discoveryClient IDiscovery) {
|
||||
c.DiscoveryClient = discoveryClient
|
||||
}
|
||||
|
||||
//ServerPreferredResources stores the cachedClient instance for discovery client
|
||||
type ServerPreferredResources struct {
|
||||
cachedClient discovery.CachedDiscoveryInterface
|
||||
}
|
||||
|
|
|
@ -27,10 +27,10 @@ type fixture struct {
|
|||
func newFixture(t *testing.T) *fixture {
|
||||
// init groupversion
|
||||
regResource := []schema.GroupVersionResource{
|
||||
schema.GroupVersionResource{Group: "group", Version: "version", Resource: "thekinds"},
|
||||
schema.GroupVersionResource{Group: "group2", Version: "version", Resource: "thekinds"},
|
||||
schema.GroupVersionResource{Group: "", Version: "v1", Resource: "namespaces"},
|
||||
schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"},
|
||||
{Group: "group", Version: "version", Resource: "thekinds"},
|
||||
{Group: "group2", Version: "version", Resource: "thekinds"},
|
||||
{Group: "", Version: "v1", Resource: "namespaces"},
|
||||
{Group: "apps", Version: "v1", Resource: "deployments"},
|
||||
}
|
||||
|
||||
objects := []runtime.Object{newUnstructured("group/version", "TheKind", "ns-foo", "name-foo"),
|
||||
|
|
|
@ -2,7 +2,6 @@ package client
|
|||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
@ -12,8 +11,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
// Kind names are case sensitive
|
||||
//CSRs CertificateSigningRequest
|
||||
// CSRs CertificateSigningRequest
|
||||
CSRs string = "CertificateSigningRequest"
|
||||
// Secrets Secret
|
||||
Secrets string = "Secret"
|
||||
|
@ -22,13 +20,11 @@ const (
|
|||
// Namespaces Namespace
|
||||
Namespaces string = "Namespace"
|
||||
)
|
||||
const namespaceCreationMaxWaitTime time.Duration = 30 * time.Second
|
||||
const namespaceCreationWaitInterval time.Duration = 100 * time.Millisecond
|
||||
|
||||
//---testing utilities
|
||||
//NewMockClient ---testing utilities
|
||||
func NewMockClient(scheme *runtime.Scheme, objects ...runtime.Object) (*Client, error) {
|
||||
client := fake.NewSimpleDynamicClient(scheme, objects...)
|
||||
// the typed and dynamic client are initalized with similar resources
|
||||
// the typed and dynamic client are initialized with similar resources
|
||||
kclient := kubernetesfake.NewSimpleClientset(objects...)
|
||||
return &Client{
|
||||
client: client,
|
||||
|
@ -41,15 +37,15 @@ func NewMockClient(scheme *runtime.Scheme, objects ...runtime.Object) (*Client,
|
|||
func NewFakeDiscoveryClient(registeredResouces []schema.GroupVersionResource) *fakeDiscoveryClient {
|
||||
// Load some-preregistd resources
|
||||
res := []schema.GroupVersionResource{
|
||||
schema.GroupVersionResource{Version: "v1", Resource: "configmaps"},
|
||||
schema.GroupVersionResource{Version: "v1", Resource: "endpoints"},
|
||||
schema.GroupVersionResource{Version: "v1", Resource: "namespaces"},
|
||||
schema.GroupVersionResource{Version: "v1", Resource: "resourcequotas"},
|
||||
schema.GroupVersionResource{Version: "v1", Resource: "secrets"},
|
||||
schema.GroupVersionResource{Version: "v1", Resource: "serviceaccounts"},
|
||||
schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "daemonsets"},
|
||||
schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "deployments"},
|
||||
schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: "statefulsets"},
|
||||
{Version: "v1", Resource: "configmaps"},
|
||||
{Version: "v1", Resource: "endpoints"},
|
||||
{Version: "v1", Resource: "namespaces"},
|
||||
{Version: "v1", Resource: "resourcequotas"},
|
||||
{Version: "v1", Resource: "secrets"},
|
||||
{Version: "v1", Resource: "serviceaccounts"},
|
||||
{Group: "apps", Version: "v1", Resource: "daemonsets"},
|
||||
{Group: "apps", Version: "v1", Resource: "deployments"},
|
||||
{Group: "apps", Version: "v1", Resource: "statefulsets"},
|
||||
}
|
||||
registeredResouces = append(registeredResouces, res...)
|
||||
return &fakeDiscoveryClient{registeredResouces: registeredResouces}
|
||||
|
@ -91,22 +87,3 @@ func newUnstructuredWithSpec(apiVersion, kind, namespace, name string, spec map[
|
|||
u.Object["spec"] = spec
|
||||
return u
|
||||
}
|
||||
|
||||
func retry(attempts int, sleep time.Duration, fn func() error) error {
|
||||
if err := fn(); err != nil {
|
||||
if s, ok := err.(stop); ok {
|
||||
return s.error
|
||||
}
|
||||
if attempts--; attempts > 0 {
|
||||
time.Sleep(sleep)
|
||||
return retry(attempts, 2*sleep, fn)
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Custom error
|
||||
type stop struct {
|
||||
error
|
||||
}
|
||||
|
|
|
@ -19,8 +19,8 @@ func CreateElementHandler(element string, pattern interface{}, path string) Vali
|
|||
switch {
|
||||
case IsConditionAnchor(element):
|
||||
return NewConditionAnchorHandler(element, pattern, path)
|
||||
case IsExistanceAnchor(element):
|
||||
return NewExistanceHandler(element, pattern, path)
|
||||
case IsExistenceAnchor(element):
|
||||
return NewExistenceHandler(element, pattern, path)
|
||||
case IsEqualityAnchor(element):
|
||||
return NewEqualityHandler(element, pattern, path)
|
||||
case IsNegationAnchor(element):
|
||||
|
@ -156,30 +156,30 @@ func (ch ConditionAnchorHandler) Handle(handler resourceElementHandler, resource
|
|||
return "", nil
|
||||
}
|
||||
|
||||
//NewExistanceHandler returns existence handler
|
||||
func NewExistanceHandler(anchor string, pattern interface{}, path string) ValidationHandler {
|
||||
return ExistanceHandler{
|
||||
//NewExistenceHandler returns existence handler
|
||||
func NewExistenceHandler(anchor string, pattern interface{}, path string) ValidationHandler {
|
||||
return ExistenceHandler{
|
||||
anchor: anchor,
|
||||
pattern: pattern,
|
||||
path: path,
|
||||
}
|
||||
}
|
||||
|
||||
//ExistanceHandler provides handlers to process exitence anchor handler
|
||||
type ExistanceHandler struct {
|
||||
//ExistenceHandler provides handlers to process exitence anchor handler
|
||||
type ExistenceHandler struct {
|
||||
anchor string
|
||||
pattern interface{}
|
||||
path string
|
||||
}
|
||||
|
||||
//Handle processes the existence anchor handler
|
||||
func (eh ExistanceHandler) Handle(handler resourceElementHandler, resourceMap map[string]interface{}, originPattern interface{}) (string, error) {
|
||||
// skip is used by existance anchor to not process further if condition is not satisfied
|
||||
func (eh ExistenceHandler) Handle(handler resourceElementHandler, resourceMap map[string]interface{}, originPattern interface{}) (string, error) {
|
||||
// skip is used by existence anchor to not process further if condition is not satisfied
|
||||
anchorKey := removeAnchor(eh.anchor)
|
||||
currentPath := eh.path + anchorKey + "/"
|
||||
// check if anchor is present in resource
|
||||
if value, ok := resourceMap[anchorKey]; ok {
|
||||
// Existance anchor can only exist on resource value type of list
|
||||
// Existence anchor can only exist on resource value type of list
|
||||
switch typedResource := value.(type) {
|
||||
case []interface{}:
|
||||
typedPattern, ok := eh.pattern.([]interface{})
|
||||
|
@ -194,8 +194,8 @@ func (eh ExistanceHandler) Handle(handler resourceElementHandler, resourceMap ma
|
|||
}
|
||||
return validateExistenceListResource(handler, typedResource, typedPatternMap, originPattern, currentPath)
|
||||
default:
|
||||
glog.Error("Invalid type: Existance ^ () anchor can be used only on list/array type resource")
|
||||
return currentPath, fmt.Errorf("Invalid resource type %T: Existance ^ () anchor can be used only on list/array type resource", value)
|
||||
glog.Error("Invalid type: Existence ^ () anchor can be used only on list/array type resource")
|
||||
return currentPath, fmt.Errorf("Invalid resource type %T: Existence ^ () anchor can be used only on list/array type resource", value)
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
|
@ -213,15 +213,16 @@ func validateExistenceListResource(handler resourceElementHandler, resourceList
|
|||
return "", nil
|
||||
}
|
||||
}
|
||||
// none of the existance checks worked, so thats a failure sceanario
|
||||
// none of the existence checks worked, so thats a failure sceanario
|
||||
return path, fmt.Errorf("Existence anchor validation failed at path %s", path)
|
||||
}
|
||||
|
||||
//GetAnchorsResourcesFromMap returns map of anchors
|
||||
func GetAnchorsResourcesFromMap(patternMap map[string]interface{}) (map[string]interface{}, map[string]interface{}) {
|
||||
anchors := map[string]interface{}{}
|
||||
resources := map[string]interface{}{}
|
||||
for key, value := range patternMap {
|
||||
if IsConditionAnchor(key) || IsExistanceAnchor(key) || IsEqualityAnchor(key) || IsNegationAnchor(key) {
|
||||
if IsConditionAnchor(key) || IsExistenceAnchor(key) || IsEqualityAnchor(key) || IsNegationAnchor(key) {
|
||||
anchors[key] = value
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package anchor
|
||||
|
||||
// Anchor function type
|
||||
// IsAnchor is a function handler
|
||||
type IsAnchor func(str string) bool
|
||||
|
||||
//IsConditionAnchor checks for condition anchor
|
||||
func IsConditionAnchor(str string) bool {
|
||||
if len(str) < 2 {
|
||||
return false
|
||||
|
@ -11,6 +12,7 @@ func IsConditionAnchor(str string) bool {
|
|||
return (str[0] == '(' && str[len(str)-1] == ')')
|
||||
}
|
||||
|
||||
//IsNegationAnchor checks for negation anchor
|
||||
func IsNegationAnchor(str string) bool {
|
||||
left := "X("
|
||||
right := ")"
|
||||
|
@ -21,6 +23,7 @@ func IsNegationAnchor(str string) bool {
|
|||
return (str[:len(left)] == left && str[len(str)-len(right):] == right)
|
||||
}
|
||||
|
||||
// IsAddingAnchor checks for addition anchor
|
||||
func IsAddingAnchor(key string) bool {
|
||||
const left = "+("
|
||||
const right = ")"
|
||||
|
@ -32,6 +35,7 @@ func IsAddingAnchor(key string) bool {
|
|||
return left == key[:len(left)] && right == key[len(key)-len(right):]
|
||||
}
|
||||
|
||||
// IsEqualityAnchor checks for equality anchor
|
||||
func IsEqualityAnchor(str string) bool {
|
||||
left := "=("
|
||||
right := ")"
|
||||
|
@ -42,7 +46,8 @@ func IsEqualityAnchor(str string) bool {
|
|||
return (str[:len(left)] == left && str[len(str)-len(right):] == right)
|
||||
}
|
||||
|
||||
func IsExistanceAnchor(str string) bool {
|
||||
//IsExistenceAnchor checks for existence anchor
|
||||
func IsExistenceAnchor(str string) bool {
|
||||
left := "^("
|
||||
right := ")"
|
||||
|
||||
|
@ -53,15 +58,14 @@ func IsExistanceAnchor(str string) bool {
|
|||
return (str[:len(left)] == left && str[len(str)-len(right):] == right)
|
||||
}
|
||||
|
||||
|
||||
func removeAnchor(key string) string {
|
||||
if IsConditionAnchor(key) {
|
||||
return key[1 : len(key)-1]
|
||||
}
|
||||
|
||||
if IsExistanceAnchor(key) || IsAddingAnchor(key) || IsEqualityAnchor(key) || IsNegationAnchor(key) {
|
||||
if IsExistenceAnchor(key) || IsAddingAnchor(key) || IsEqualityAnchor(key) || IsNegationAnchor(key) {
|
||||
return key[2 : len(key)-1]
|
||||
}
|
||||
|
||||
return key
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,18 +41,18 @@ func TestWrappedWithParentheses_Empty(t *testing.T) {
|
|||
assert.Assert(t, !IsConditionAnchor(str))
|
||||
}
|
||||
|
||||
func TestIsExistanceAnchor_Yes(t *testing.T) {
|
||||
assert.Assert(t, IsExistanceAnchor("^(abc)"))
|
||||
func TestIsExistenceAnchor_Yes(t *testing.T) {
|
||||
assert.Assert(t, IsExistenceAnchor("^(abc)"))
|
||||
}
|
||||
|
||||
func TestIsExistanceAnchor_NoRightBracket(t *testing.T) {
|
||||
assert.Assert(t, !IsExistanceAnchor("^(abc"))
|
||||
func TestIsExistenceAnchor_NoRightBracket(t *testing.T) {
|
||||
assert.Assert(t, !IsExistenceAnchor("^(abc"))
|
||||
}
|
||||
|
||||
func TestIsExistanceAnchor_OnlyHat(t *testing.T) {
|
||||
assert.Assert(t, !IsExistanceAnchor("^abc"))
|
||||
func TestIsExistenceAnchor_OnlyHat(t *testing.T) {
|
||||
assert.Assert(t, !IsExistenceAnchor("^abc"))
|
||||
}
|
||||
|
||||
func TestIsExistanceAnchor_ConditionAnchor(t *testing.T) {
|
||||
assert.Assert(t, !IsExistanceAnchor("(abc)"))
|
||||
func TestIsExistenceAnchor_ConditionAnchor(t *testing.T) {
|
||||
assert.Assert(t, !IsExistenceAnchor("(abc)"))
|
||||
}
|
||||
|
|
|
@ -10,15 +10,15 @@ import (
|
|||
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
||||
)
|
||||
|
||||
//Interface ... normal functions
|
||||
//Interface to manage context operations
|
||||
type Interface interface {
|
||||
// merges the json with context
|
||||
//AddJSON merges the json with context
|
||||
AddJSON(dataRaw []byte) error
|
||||
// merges resource json under request.object
|
||||
//AddResource merges resource json under request.object
|
||||
AddResource(dataRaw []byte) error
|
||||
// merges userInfo json under kyverno.userInfo
|
||||
//AddUserInfo merges userInfo json under kyverno.userInfo
|
||||
AddUserInfo(userInfo kyverno.UserInfo) error
|
||||
// merges serrviceaccount
|
||||
//AddSA merges serrviceaccount
|
||||
AddSA(userName string) error
|
||||
EvalInterface
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ func (ctx *Context) AddJSON(dataRaw []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
//Add data at path: request.object
|
||||
//AddResource data at path: request.object
|
||||
func (ctx *Context) AddResource(dataRaw []byte) error {
|
||||
|
||||
// unmarshall the resource struct
|
||||
|
@ -86,6 +86,7 @@ func (ctx *Context) AddResource(dataRaw []byte) error {
|
|||
return ctx.AddJSON(objRaw)
|
||||
}
|
||||
|
||||
//AddUserInfo adds userInfo at path request.userInfo
|
||||
func (ctx *Context) AddUserInfo(userRequestInfo kyverno.RequestInfo) error {
|
||||
modifiedResource := struct {
|
||||
Request interface{} `json:"request"`
|
||||
|
@ -101,7 +102,7 @@ func (ctx *Context) AddUserInfo(userRequestInfo kyverno.RequestInfo) error {
|
|||
return ctx.AddJSON(objRaw)
|
||||
}
|
||||
|
||||
// removes prefix 'system:serviceaccount:' and namespace, then loads only username
|
||||
//AddSA removes prefix 'system:serviceaccount:' and namespace, then loads only SA name and SA namespace
|
||||
func (ctx *Context) AddSA(userName string) error {
|
||||
saPrefix := "system:serviceaccount:"
|
||||
var sa string
|
||||
|
@ -121,7 +122,7 @@ func (ctx *Context) AddSA(userName string) error {
|
|||
saNamespace = groups[0]
|
||||
}
|
||||
|
||||
glog.Infof("Loading variable serviceAccountName with value: %s", saName)
|
||||
glog.V(4).Infof("Loading variable serviceAccountName with value: %s", saName)
|
||||
saNameObj := struct {
|
||||
SA string `json:"serviceAccountName"`
|
||||
}{
|
||||
|
@ -136,7 +137,7 @@ func (ctx *Context) AddSA(userName string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
glog.Infof("Loading variable serviceAccountNamespace with value: %s", saNamespace)
|
||||
glog.V(4).Infof("Loading variable serviceAccountNamespace with value: %s", saNamespace)
|
||||
saNsObj := struct {
|
||||
SA string `json:"serviceAccountNamespace"`
|
||||
}{
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
)
|
||||
|
||||
func Test_addResourceAndUserContext(t *testing.T) {
|
||||
var err error
|
||||
rawResource := []byte(`
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
|
@ -54,7 +55,10 @@ func Test_addResourceAndUserContext(t *testing.T) {
|
|||
|
||||
var expectedResult string
|
||||
ctx := NewContext()
|
||||
ctx.AddResource(rawResource)
|
||||
err = ctx.AddResource(rawResource)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
result, err := ctx.Query("request.object.apiVersion")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -65,7 +69,10 @@ func Test_addResourceAndUserContext(t *testing.T) {
|
|||
t.Error("exected result does not match")
|
||||
}
|
||||
|
||||
ctx.AddUserInfo(userRequestInfo)
|
||||
err = ctx.AddUserInfo(userRequestInfo)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
result, err = ctx.Query("request.object.apiVersion")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -86,7 +93,10 @@ func Test_addResourceAndUserContext(t *testing.T) {
|
|||
t.Error("exected result does not match")
|
||||
}
|
||||
// Add service account Name
|
||||
ctx.AddSA(userRequestInfo.AdmissionUserInfo.Username)
|
||||
err = ctx.AddSA(userRequestInfo.AdmissionUserInfo.Username)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
result, err = ctx.Query("serviceAccountName")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
|
|
@ -13,11 +13,11 @@ import (
|
|||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
||||
// GenerateNew
|
||||
// Generate checks for validity of generate rule on the resource
|
||||
// 1. validate variables to be susbtitute in the general ruleInfo (match,exclude,condition)
|
||||
// - the caller has to check the ruleResponse to determine whether the path exist
|
||||
// 2. returns the list of rules that are applicable on this policy and resource, if 1 succeed
|
||||
func GenerateNew(policyContext PolicyContext) (resp response.EngineResponse) {
|
||||
func Generate(policyContext PolicyContext) (resp response.EngineResponse) {
|
||||
policy := policyContext.Policy
|
||||
resource := policyContext.NewResource
|
||||
admissionInfo := policyContext.AdmissionInfo
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
"github.com/nirmata/kyverno/pkg/engine/variables"
|
||||
)
|
||||
|
||||
// processOverlay processes mutation overlay on the resource
|
||||
// ProcessOverlay processes mutation overlay on the resource
|
||||
func ProcessOverlay(ctx context.EvalInterface, rule kyverno.Rule, resource unstructured.Unstructured) (resp response.RuleResponse, patchedResource unstructured.Unstructured) {
|
||||
startTime := time.Now()
|
||||
glog.V(4).Infof("started applying overlay rule %q (%v)", rule.Name, startTime)
|
||||
|
@ -111,7 +111,7 @@ func ProcessOverlay(ctx context.EvalInterface, rule kyverno.Rule, resource unstr
|
|||
return resp, resource
|
||||
}
|
||||
|
||||
// rule application succesfuly
|
||||
// rule application successfully
|
||||
resp.Success = true
|
||||
resp.Message = fmt.Sprintf("successfully processed overlay")
|
||||
resp.Patches = patches
|
||||
|
@ -150,7 +150,7 @@ func mutateResourceWithOverlay(resource, pattern interface{}) ([][]byte, error)
|
|||
|
||||
// applyOverlay detects type of current item and goes down through overlay and resource trees applying overlay
|
||||
func applyOverlay(resource, overlay interface{}, path string) ([][]byte, error) {
|
||||
var appliedPatches [][]byte
|
||||
|
||||
// resource item exists but has different type - replace
|
||||
// all subtree within this path by overlay
|
||||
if reflect.TypeOf(resource) != reflect.TypeOf(overlay) {
|
||||
|
@ -159,8 +159,7 @@ func applyOverlay(resource, overlay interface{}, path string) ([][]byte, error)
|
|||
return nil, err
|
||||
}
|
||||
|
||||
appliedPatches = append(appliedPatches, patch)
|
||||
//TODO : check if return is needed ?
|
||||
return [][]byte{patch}, nil
|
||||
}
|
||||
return applyOverlayForSameTypes(resource, overlay, path)
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ func checkConditions(resource, overlay interface{}, path string) (string, overla
|
|||
|
||||
// resource item exists but has different type
|
||||
// return false if anchor exists in overlay
|
||||
// conditon never be true in this case
|
||||
// condition never be true in this case
|
||||
if reflect.TypeOf(resource) != reflect.TypeOf(overlay) {
|
||||
if hasNestedAnchors(overlay) {
|
||||
glog.V(4).Infof("Found anchor on different types of element at path %s: overlay %T, resource %T", path, overlay, resource)
|
||||
|
|
|
@ -19,6 +19,7 @@ func applyPatch(resource []byte, patchRaw []byte) ([]byte, error) {
|
|||
return utils.ApplyPatches(resource, patchesList)
|
||||
}
|
||||
|
||||
//ProcessPatches applies the patches on the resource and returns the patched resource
|
||||
func ProcessPatches(rule kyverno.Rule, resource unstructured.Unstructured) (resp response.RuleResponse, patchedResource unstructured.Unstructured) {
|
||||
startTime := time.Now()
|
||||
glog.V(4).Infof("started JSON patch rule %q (%v)", rule.Name, startTime)
|
||||
|
@ -82,9 +83,9 @@ func ProcessPatches(rule kyverno.Rule, resource unstructured.Unstructured) (resp
|
|||
return resp, resource
|
||||
}
|
||||
|
||||
// JSON patches processed succesfully
|
||||
// JSON patches processed successfully
|
||||
resp.Success = true
|
||||
resp.Message = fmt.Sprintf("succesfully process JSON patches")
|
||||
resp.Message = fmt.Sprintf("successfully process JSON patches")
|
||||
resp.Patches = patches
|
||||
return resp, patchedResource
|
||||
}
|
||||
|
|
|
@ -174,10 +174,6 @@ func assertEqDataImpl(t *testing.T, expected, actual []byte, formatModifier stri
|
|||
}
|
||||
}
|
||||
|
||||
func assertEqData(t *testing.T, expected, actual []byte) {
|
||||
assertEqDataImpl(t, expected, actual, "%x")
|
||||
}
|
||||
|
||||
func assertEqStringAndData(t *testing.T, str string, data []byte) {
|
||||
assertEqDataImpl(t, []byte(str), data, "%s")
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ func removeAnchor(key string) string {
|
|||
return key[1 : len(key)-1]
|
||||
}
|
||||
|
||||
if anchor.IsExistanceAnchor(key) || anchor.IsAddingAnchor(key) || anchor.IsEqualityAnchor(key) || anchor.IsNegationAnchor(key) {
|
||||
if anchor.IsExistenceAnchor(key) || anchor.IsAddingAnchor(key) || anchor.IsEqualityAnchor(key) || anchor.IsNegationAnchor(key) {
|
||||
return key[2 : len(key)-1]
|
||||
}
|
||||
|
||||
|
|
|
@ -17,9 +17,12 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
PodControllers = "DaemonSet,Deployment,Job,StatefulSet"
|
||||
//PodControllers stores the list of Pod-controllers in csv string
|
||||
PodControllers = "DaemonSet,Deployment,Job,StatefulSet"
|
||||
//PodControllersAnnotation defines the annotation key for Pod-Controllers
|
||||
PodControllersAnnotation = "pod-policies.kyverno.io/autogen-controllers"
|
||||
PodTemplateAnnotation = "pod-policies.kyverno.io/autogen-applied"
|
||||
//PodTemplateAnnotation defines the annotation key for Pod-Template
|
||||
PodTemplateAnnotation = "pod-policies.kyverno.io/autogen-applied"
|
||||
)
|
||||
|
||||
// Mutate performs mutation. Overlay first and then mutation patches
|
||||
|
@ -34,7 +37,7 @@ func Mutate(policyContext PolicyContext) (resp response.EngineResponse) {
|
|||
defer endMutateResultResponse(&resp, startTime)
|
||||
|
||||
incrementAppliedRuleCount := func() {
|
||||
// rules applied succesfully count
|
||||
// rules applied successfully count
|
||||
resp.PolicyResponse.RulesAppliedCount++
|
||||
}
|
||||
|
||||
|
@ -80,7 +83,7 @@ func Mutate(policyContext PolicyContext) (resp response.EngineResponse) {
|
|||
if rule.Mutation.Overlay != nil {
|
||||
var ruleResponse response.RuleResponse
|
||||
ruleResponse, patchedResource = mutate.ProcessOverlay(ctx, rule, patchedResource)
|
||||
if ruleResponse.Success == true {
|
||||
if ruleResponse.Success {
|
||||
// - variable substitution path is not present
|
||||
if ruleResponse.PathNotPresent {
|
||||
glog.V(4).Infof(ruleResponse.Message)
|
||||
|
|
|
@ -114,7 +114,7 @@ func Test_variableSubstitutionPathNotExist(t *testing.T) {
|
|||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "substitue-variable"
|
||||
"name": "substitute-variable"
|
||||
},
|
||||
"spec": {
|
||||
"rules": [
|
||||
|
|
|
@ -18,10 +18,10 @@ const (
|
|||
Less Operator = "<"
|
||||
)
|
||||
|
||||
const relativePrefix Operator = "./"
|
||||
//ReferenceSign defines the operator for anchor reference
|
||||
const ReferenceSign Operator = "$()"
|
||||
|
||||
// getOperatorFromStringPattern parses opeartor from pattern
|
||||
// GetOperatorFromStringPattern parses opeartor from pattern
|
||||
func GetOperatorFromStringPattern(pattern string) Operator {
|
||||
if len(pattern) < 2 {
|
||||
return Equal
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package operator
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"gotest.tools/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetOperatorFromStringPattern_OneChar(t *testing.T) {
|
||||
assert.Equal(t, GetOperatorFromStringPattern("f"), Equal)
|
||||
}
|
||||
|
|
|
@ -268,14 +268,14 @@ func validateValidation(v kyverno.Validation) (string, error) {
|
|||
}
|
||||
|
||||
if v.Pattern != nil {
|
||||
if path, err := validatePattern(v.Pattern, "/", []anchor.IsAnchor{anchor.IsConditionAnchor, anchor.IsExistanceAnchor, anchor.IsEqualityAnchor, anchor.IsNegationAnchor}); err != nil {
|
||||
if path, err := validatePattern(v.Pattern, "/", []anchor.IsAnchor{anchor.IsConditionAnchor, anchor.IsExistenceAnchor, anchor.IsEqualityAnchor, anchor.IsNegationAnchor}); err != nil {
|
||||
return fmt.Sprintf("pattern.%s", path), err
|
||||
}
|
||||
}
|
||||
|
||||
if len(v.AnyPattern) != 0 {
|
||||
for i, pattern := range v.AnyPattern {
|
||||
if path, err := validatePattern(pattern, "/", []anchor.IsAnchor{anchor.IsConditionAnchor, anchor.IsExistanceAnchor, anchor.IsEqualityAnchor, anchor.IsNegationAnchor}); err != nil {
|
||||
if path, err := validatePattern(pattern, "/", []anchor.IsAnchor{anchor.IsConditionAnchor, anchor.IsExistenceAnchor, anchor.IsEqualityAnchor, anchor.IsNegationAnchor}); err != nil {
|
||||
return fmt.Sprintf("anyPattern[%d].%s", i, path), err
|
||||
}
|
||||
}
|
||||
|
@ -322,7 +322,7 @@ func validateGeneration(gen kyverno.Generation) (string, error) {
|
|||
//TODO: is this required ?? as anchors can only be on pattern and not resource
|
||||
// we can add this check by not sure if its needed here
|
||||
if path, err := validatePattern(gen.Data, "/", []anchor.IsAnchor{}); err != nil {
|
||||
return fmt.Sprintf("data.%s", path), fmt.Errorf("anchors not supported on generate resoruces: %v", err)
|
||||
return fmt.Sprintf("data.%s", path), fmt.Errorf("anchors not supported on generate resources: %v", err)
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
|
@ -359,10 +359,12 @@ func validateMap(patternMap map[string]interface{}, path string, supportedAnchor
|
|||
// check regex () -> this is anchor
|
||||
// ()
|
||||
// single char ()
|
||||
matched, err := regexp.MatchString(`^.?\(.+\)$`, key)
|
||||
re, err := regexp.Compile(`^.?\(.+\)$`)
|
||||
if err != nil {
|
||||
return path + "/" + key, fmt.Errorf("Unable to parse the field %s: %v", key, err)
|
||||
}
|
||||
|
||||
matched := re.MatchString(key)
|
||||
// check the type of anchor
|
||||
if matched {
|
||||
// some type of anchor
|
||||
|
@ -371,16 +373,16 @@ func validateMap(patternMap map[string]interface{}, path string, supportedAnchor
|
|||
return path + "/" + key, fmt.Errorf("Unsupported anchor %s", key)
|
||||
}
|
||||
|
||||
// addition check for existance anchor
|
||||
// addition check for existence anchor
|
||||
// value must be of type list
|
||||
if anchor.IsExistanceAnchor(key) {
|
||||
if anchor.IsExistenceAnchor(key) {
|
||||
typedValue, ok := value.([]interface{})
|
||||
if !ok {
|
||||
return path + "/" + key, fmt.Errorf("Existance anchor should have value of type list")
|
||||
return path + "/" + key, fmt.Errorf("Existence anchor should have value of type list")
|
||||
}
|
||||
// validate there is only one entry in the list
|
||||
if len(typedValue) == 0 || len(typedValue) > 1 {
|
||||
return path + "/" + key, fmt.Errorf("Existance anchor: single value expected, multiple specified")
|
||||
return path + "/" + key, fmt.Errorf("Existence anchor: single value expected, multiple specified")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -500,7 +500,6 @@ func Test_Validate_ExistingAnchor_Valid(t *testing.T) {
|
|||
if _, err := validateValidation(validation); err != nil {
|
||||
assert.Assert(t, err != nil)
|
||||
}
|
||||
rawValidation = nil
|
||||
rawValidation = []byte(`
|
||||
{
|
||||
"message": "validate container security contexts",
|
||||
|
@ -567,7 +566,6 @@ func Test_Validate_Validate_ValidAnchor(t *testing.T) {
|
|||
}
|
||||
|
||||
// case 2
|
||||
rawValidate = nil
|
||||
validate = kyverno.Validation{}
|
||||
rawValidate = []byte(`
|
||||
{
|
||||
|
|
|
@ -10,10 +10,11 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
//SaPrefix defines the prefix for service accounts
|
||||
SaPrefix = "system:serviceaccount:"
|
||||
)
|
||||
|
||||
// matchAdmissionInfo return true if the rule can be applied to the request
|
||||
// MatchAdmissionInfo return true if the rule can be applied to the request
|
||||
func MatchAdmissionInfo(rule kyverno.Rule, requestInfo kyverno.RequestInfo) bool {
|
||||
// when processing existing resource, it does not contain requestInfo
|
||||
// skip permission checking
|
||||
|
|
|
@ -47,7 +47,7 @@ func (rs ResourceSpec) GetKey() string {
|
|||
type PolicyStats struct {
|
||||
// time required to process the policy rules on a resource
|
||||
ProcessingTime time.Duration `json:"processingTime"`
|
||||
// Count of rules that were applied succesfully
|
||||
// Count of rules that were applied successfully
|
||||
RulesAppliedCount int `json:"rulesAppliedCount"`
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
"github.com/minio/minio/pkg/wildcard"
|
||||
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
||||
"github.com/nirmata/kyverno/pkg/engine/context"
|
||||
"github.com/nirmata/kyverno/pkg/engine/operator"
|
||||
"github.com/nirmata/kyverno/pkg/engine/response"
|
||||
"github.com/nirmata/kyverno/pkg/engine/variables"
|
||||
"github.com/nirmata/kyverno/pkg/utils"
|
||||
|
@ -23,7 +22,7 @@ import (
|
|||
type EngineStats struct {
|
||||
// average time required to process the policy rules on a resource
|
||||
ExecutionTime time.Duration
|
||||
// Count of rules that were applied succesfully
|
||||
// Count of rules that were applied successfully
|
||||
RulesAppliedCount int
|
||||
}
|
||||
|
||||
|
@ -146,12 +145,16 @@ func MatchesResourceDescription(resource unstructured.Unstructured, rule kyverno
|
|||
}()
|
||||
}
|
||||
|
||||
//Condition type for conditions
|
||||
type Condition int
|
||||
|
||||
const (
|
||||
// NotEvaluate to not-evaluate to condition
|
||||
NotEvaluate Condition = 0
|
||||
Process Condition = 1
|
||||
Skip Condition = 2
|
||||
// Process to process the condition
|
||||
Process Condition = 1
|
||||
// Skip to skip the condition
|
||||
Skip Condition = 2
|
||||
)
|
||||
|
||||
// ParseResourceInfoFromObject get kind/namepace/name from resource
|
||||
|
@ -219,19 +222,6 @@ func findKind(kinds []string, kindGVK string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func isStringIsReference(str string) bool {
|
||||
if len(str) < len(operator.ReferenceSign) {
|
||||
return false
|
||||
}
|
||||
|
||||
return str[0] == '$' && str[1] == '(' && str[len(str)-1] == ')'
|
||||
}
|
||||
|
||||
type resourceInfo struct {
|
||||
Resource unstructured.Unstructured
|
||||
Gvk *metav1.GroupVersionKind
|
||||
}
|
||||
|
||||
// validateGeneralRuleInfoVariables validate variable subtition defined in
|
||||
// - MatchResources
|
||||
// - ExcludeResources
|
||||
|
|
|
@ -6,12 +6,17 @@ import (
|
|||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
||||
//RuleType defines the type for rule
|
||||
type RuleType int
|
||||
|
||||
const (
|
||||
//Mutation type for mutation rule
|
||||
Mutation RuleType = iota
|
||||
//Validation type for validation rule
|
||||
Validation
|
||||
//Generation type for generation rule
|
||||
Generation
|
||||
//All type for other rule operations(future)
|
||||
All
|
||||
)
|
||||
|
||||
|
@ -73,6 +78,7 @@ func JoinPatches(patches [][]byte) []byte {
|
|||
return result
|
||||
}
|
||||
|
||||
//ConvertToUnstructured converts the resource to unstructured format
|
||||
func ConvertToUnstructured(data []byte) (*unstructured.Unstructured, error) {
|
||||
resource := &unstructured.Unstructured{}
|
||||
err := resource.UnmarshalJSON(data)
|
||||
|
@ -82,7 +88,7 @@ func ConvertToUnstructured(data []byte) (*unstructured.Unstructured, error) {
|
|||
return resource, nil
|
||||
}
|
||||
|
||||
// getAnchorsFromMap gets the conditional anchor map
|
||||
// GetAnchorsFromMap gets the conditional anchor map
|
||||
func GetAnchorsFromMap(anchorsMap map[string]interface{}) map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package utils
|
||||
|
||||
import(
|
||||
"testing"
|
||||
import (
|
||||
"encoding/json"
|
||||
"gotest.tools/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetAnchorsFromMap_ThereAreNoAnchors(t *testing.T) {
|
||||
|
@ -19,8 +19,10 @@ func TestGetAnchorsFromMap_ThereAreNoAnchors(t *testing.T) {
|
|||
}`)
|
||||
|
||||
var unmarshalled map[string]interface{}
|
||||
json.Unmarshal(rawMap, &unmarshalled)
|
||||
|
||||
err := json.Unmarshal(rawMap, &unmarshalled)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
actualMap := GetAnchorsFromMap(unmarshalled)
|
||||
assert.Assert(t, len(actualMap) == 0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -237,7 +237,7 @@ func TestResourceDescriptionMatch_Label_Expression_NotMatch(t *testing.T) {
|
|||
Selector: &metav1.LabelSelector{
|
||||
MatchLabels: nil,
|
||||
MatchExpressions: []metav1.LabelSelectorRequirement{
|
||||
metav1.LabelSelectorRequirement{
|
||||
{
|
||||
Key: "label2",
|
||||
Operator: "NotIn",
|
||||
Values: []string{
|
||||
|
@ -303,7 +303,7 @@ func TestResourceDescriptionMatch_Label_Expression_Match(t *testing.T) {
|
|||
Selector: &metav1.LabelSelector{
|
||||
MatchLabels: nil,
|
||||
MatchExpressions: []metav1.LabelSelectorRequirement{
|
||||
metav1.LabelSelectorRequirement{
|
||||
{
|
||||
Key: "app",
|
||||
Operator: "NotIn",
|
||||
Values: []string{
|
||||
|
@ -371,7 +371,7 @@ func TestResourceDescriptionExclude_Label_Expression_Match(t *testing.T) {
|
|||
Selector: &metav1.LabelSelector{
|
||||
MatchLabels: nil,
|
||||
MatchExpressions: []metav1.LabelSelectorRequirement{
|
||||
metav1.LabelSelectorRequirement{
|
||||
{
|
||||
Key: "app",
|
||||
Operator: "NotIn",
|
||||
Values: []string{
|
||||
|
@ -488,9 +488,19 @@ func Test_validateGeneralRuleInfoVariables(t *testing.T) {
|
|||
assert.NilError(t, json.Unmarshal(policyRaw, &policy))
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(rawResource)
|
||||
ctx.AddUserInfo(userReqInfo)
|
||||
ctx.AddSA("system:serviceaccount:test:testuser")
|
||||
var err error
|
||||
err = ctx.AddResource(rawResource)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
err = ctx.AddUserInfo(userReqInfo)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
err = ctx.AddSA("system:serviceaccount:test:testuser")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
expectPaths := []string{"request.userInfo.username1", "request.object.namespace", ""}
|
||||
|
||||
|
|
|
@ -3,47 +3,18 @@ package validate
|
|||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/nirmata/kyverno/pkg/engine/operator"
|
||||
)
|
||||
|
||||
//ValidationFailureReason defeins type for Validation Failure reason
|
||||
type ValidationFailureReason int
|
||||
|
||||
const (
|
||||
// PathNotPresent if path is not present
|
||||
PathNotPresent ValidationFailureReason = iota
|
||||
// Rulefailure if the rule failed
|
||||
Rulefailure
|
||||
)
|
||||
|
||||
func isStringIsReference(str string) bool {
|
||||
if len(str) < len(operator.ReferenceSign) {
|
||||
return false
|
||||
}
|
||||
|
||||
return str[0] == '$' && str[1] == '(' && str[len(str)-1] == ')'
|
||||
}
|
||||
|
||||
// convertToFloat converts string and any other value to float64
|
||||
func convertToFloat(value interface{}) (float64, error) {
|
||||
switch typed := value.(type) {
|
||||
case string:
|
||||
var err error
|
||||
floatValue, err := strconv.ParseFloat(typed, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return floatValue, nil
|
||||
case float64:
|
||||
return typed, nil
|
||||
case int64:
|
||||
return float64(typed), nil
|
||||
case int:
|
||||
return float64(typed), nil
|
||||
default:
|
||||
return 0, fmt.Errorf("Could not convert %T to float64", value)
|
||||
}
|
||||
}
|
||||
|
||||
// convertToString converts value to string
|
||||
func convertToString(value interface{}) (string, error) {
|
||||
switch typed := value.(type) {
|
||||
|
@ -74,6 +45,7 @@ func getRawKeyIfWrappedWithAttributes(str string) string {
|
|||
}
|
||||
}
|
||||
|
||||
//ValidationError stores error for validation error
|
||||
type ValidationError struct {
|
||||
StatusCode ValidationFailureReason
|
||||
ErrorMsg string
|
||||
|
|
|
@ -55,7 +55,7 @@ func ValidateValueWithPattern(value, pattern interface{}) bool {
|
|||
|
||||
func validateValueWithMapPattern(value interface{}, typedPattern map[string]interface{}) bool {
|
||||
// verify the type of the resource value is map[string]interface,
|
||||
// we only check for existance of object, not the equality of content and value
|
||||
// we only check for existence of object, not the equality of content and value
|
||||
//TODO: check if adding
|
||||
_, ok := value.(map[string]interface{})
|
||||
if !ok {
|
||||
|
@ -139,7 +139,7 @@ func validateValueWithNilPattern(value interface{}) bool {
|
|||
case string:
|
||||
return typed == ""
|
||||
case bool:
|
||||
return typed == false
|
||||
return !typed
|
||||
case nil:
|
||||
return true
|
||||
case map[string]interface{}, []interface{}:
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
"github.com/nirmata/kyverno/pkg/engine/variables"
|
||||
)
|
||||
|
||||
// validateResourceWithPattern is a start of element-by-element validation process
|
||||
// ValidateResourceWithPattern is a start of element-by-element validation process
|
||||
// It assumes that validation is started from root, so "/" is passed
|
||||
func ValidateResourceWithPattern(ctx context.EvalInterface, resource, pattern interface{}) (string, ValidationError) {
|
||||
// if referenced path is not present, we skip processing the rule and report violation
|
||||
|
@ -93,7 +93,7 @@ func validateMap(resourceMap, patternMap map[string]interface{}, origPattern int
|
|||
for key, patternElement := range anchors {
|
||||
// get handler for each pattern in the pattern
|
||||
// - Conditional
|
||||
// - Existance
|
||||
// - Existence
|
||||
// - Equality
|
||||
handler := anchor.CreateElementHandler(key, patternElement, path)
|
||||
handlerPath, err := handler.Handle(validateResourceElement, resourceMap, origPattern)
|
||||
|
@ -209,7 +209,7 @@ func formAbsolutePath(referencePath, absolutePath string) string {
|
|||
//Prepares original pattern, path to value, and call traverse function
|
||||
func getValueFromReference(origPattern interface{}, reference string) (interface{}, error) {
|
||||
originalPatternMap := origPattern.(map[string]interface{})
|
||||
reference = reference[1:len(reference)]
|
||||
reference = reference[1:]
|
||||
statements := strings.Split(reference, "/")
|
||||
|
||||
return getValueFromPattern(originalPatternMap, statements, 0)
|
||||
|
@ -274,3 +274,11 @@ func validateArrayOfMaps(resourceMapArray []interface{}, patternMap map[string]i
|
|||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func isStringIsReference(str string) bool {
|
||||
if len(str) < len(operator.ReferenceSign) {
|
||||
return false
|
||||
}
|
||||
|
||||
return str[0] == '$' && str[1] == '(' && str[len(str)-1] == ')'
|
||||
}
|
||||
|
|
|
@ -97,8 +97,8 @@ func TestValidateMap(t *testing.T) {
|
|||
}`)
|
||||
|
||||
var pattern, resource map[string]interface{}
|
||||
json.Unmarshal(rawPattern, &pattern)
|
||||
json.Unmarshal(rawMap, &resource)
|
||||
assert.Assert(t, json.Unmarshal(rawPattern, &pattern))
|
||||
assert.Assert(t, json.Unmarshal(rawMap, &resource))
|
||||
|
||||
path, err := validateMap(resource, pattern, pattern, "/")
|
||||
assert.Equal(t, path, "")
|
||||
|
@ -193,8 +193,8 @@ func TestValidateMap_AsteriskForInt(t *testing.T) {
|
|||
`)
|
||||
|
||||
var pattern, resource map[string]interface{}
|
||||
json.Unmarshal(rawPattern, &pattern)
|
||||
json.Unmarshal(rawMap, &resource)
|
||||
assert.Assert(t, json.Unmarshal(rawPattern, &pattern))
|
||||
assert.Assert(t, json.Unmarshal(rawMap, &resource))
|
||||
|
||||
path, err := validateMap(resource, pattern, pattern, "/")
|
||||
t.Log(path)
|
||||
|
@ -286,8 +286,8 @@ func TestValidateMap_AsteriskForMap(t *testing.T) {
|
|||
}`)
|
||||
|
||||
var pattern, resource map[string]interface{}
|
||||
json.Unmarshal(rawPattern, &pattern)
|
||||
json.Unmarshal(rawMap, &resource)
|
||||
assert.Assert(t, json.Unmarshal(rawPattern, &pattern))
|
||||
assert.Assert(t, json.Unmarshal(rawMap, &resource))
|
||||
|
||||
path, err := validateMap(resource, pattern, pattern, "/")
|
||||
assert.Equal(t, path, "")
|
||||
|
@ -374,8 +374,8 @@ func TestValidateMap_AsteriskForArray(t *testing.T) {
|
|||
}`)
|
||||
|
||||
var pattern, resource map[string]interface{}
|
||||
json.Unmarshal(rawPattern, &pattern)
|
||||
json.Unmarshal(rawMap, &resource)
|
||||
assert.Assert(t, json.Unmarshal(rawPattern, &pattern))
|
||||
assert.Assert(t, json.Unmarshal(rawMap, &resource))
|
||||
|
||||
path, err := validateMap(resource, pattern, pattern, "/")
|
||||
assert.Equal(t, path, "")
|
||||
|
@ -465,8 +465,8 @@ func TestValidateMap_AsteriskFieldIsMissing(t *testing.T) {
|
|||
}`)
|
||||
|
||||
var pattern, resource map[string]interface{}
|
||||
json.Unmarshal(rawPattern, &pattern)
|
||||
json.Unmarshal(rawMap, &resource)
|
||||
assert.Assert(t, json.Unmarshal(rawPattern, &pattern))
|
||||
assert.Assert(t, json.Unmarshal(rawMap, &resource))
|
||||
|
||||
path, err := validateMap(resource, pattern, pattern, "/")
|
||||
assert.Equal(t, path, "/spec/template/spec/containers/0/")
|
||||
|
@ -556,7 +556,7 @@ func TestValidateMap_livenessProbeIsNull(t *testing.T) {
|
|||
}`)
|
||||
|
||||
var pattern, resource map[string]interface{}
|
||||
json.Unmarshal(rawPattern, &pattern)
|
||||
assert.Assert(t, json.Unmarshal(rawPattern, &pattern))
|
||||
json.Unmarshal(rawMap, &resource)
|
||||
|
||||
path, err := validateMap(resource, pattern, pattern, "/")
|
||||
|
@ -646,8 +646,8 @@ func TestValidateMap_livenessProbeIsMissing(t *testing.T) {
|
|||
}`)
|
||||
|
||||
var pattern, resource map[string]interface{}
|
||||
json.Unmarshal(rawPattern, &pattern)
|
||||
json.Unmarshal(rawMap, &resource)
|
||||
assert.Assert(t, json.Unmarshal(rawPattern, &pattern))
|
||||
assert.Assert(t, json.Unmarshal(rawMap, &resource))
|
||||
|
||||
path, err := validateMap(resource, pattern, pattern, "/")
|
||||
assert.Equal(t, path, "")
|
||||
|
@ -692,8 +692,8 @@ func TestValidateMapElement_TwoElementsInArrayOnePass(t *testing.T) {
|
|||
}`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(rawPattern, &pattern)
|
||||
json.Unmarshal(rawMap, &resource)
|
||||
assert.Assert(t, json.Unmarshal(rawPattern, &pattern))
|
||||
assert.Assert(t, json.Unmarshal(rawMap, &resource))
|
||||
|
||||
path, err := validateResourceElement(resource, pattern, pattern, "/")
|
||||
assert.Equal(t, path, "")
|
||||
|
@ -727,8 +727,8 @@ func TestValidateMapElement_OneElementInArrayPass(t *testing.T) {
|
|||
]`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(rawPattern, &pattern)
|
||||
json.Unmarshal(rawMap, &resource)
|
||||
assert.Assert(t, json.Unmarshal(rawPattern, &pattern))
|
||||
assert.Assert(t, json.Unmarshal(rawMap, &resource))
|
||||
|
||||
path, err := validateResourceElement(resource, pattern, pattern, "/")
|
||||
assert.Equal(t, path, "")
|
||||
|
@ -781,8 +781,8 @@ func TestValidateMap_CorrectRelativePathInConfig(t *testing.T) {
|
|||
}`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(rawPattern, &pattern)
|
||||
json.Unmarshal(rawMap, &resource)
|
||||
assert.Assert(t, json.Unmarshal(rawPattern, &pattern))
|
||||
assert.Assert(t, json.Unmarshal(rawMap, &resource))
|
||||
|
||||
path, err := validateResourceElement(resource, pattern, pattern, "/")
|
||||
assert.Equal(t, path, "")
|
||||
|
@ -835,8 +835,8 @@ func TestValidateMap_RelativePathDoesNotExists(t *testing.T) {
|
|||
}`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(rawPattern, &pattern)
|
||||
json.Unmarshal(rawMap, &resource)
|
||||
assert.Assert(t, json.Unmarshal(rawPattern, &pattern))
|
||||
assert.Assert(t, json.Unmarshal(rawMap, &resource))
|
||||
|
||||
path, err := validateResourceElement(resource, pattern, pattern, "/")
|
||||
assert.Equal(t, path, "/spec/containers/0/resources/requests/memory/")
|
||||
|
@ -889,8 +889,8 @@ func TestValidateMap_OnlyAnchorsInPath(t *testing.T) {
|
|||
}`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(rawPattern, &pattern)
|
||||
json.Unmarshal(rawMap, &resource)
|
||||
assert.Assert(t, json.Unmarshal(rawPattern, &pattern))
|
||||
assert.Assert(t, json.Unmarshal(rawMap, &resource))
|
||||
|
||||
path, err := validateResourceElement(resource, pattern, pattern, "/")
|
||||
assert.Equal(t, path, "/spec/containers/0/resources/requests/memory/")
|
||||
|
@ -943,8 +943,8 @@ func TestValidateMap_MalformedReferenceOnlyDolarMark(t *testing.T) {
|
|||
}`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(rawPattern, &pattern)
|
||||
json.Unmarshal(rawMap, &resource)
|
||||
assert.Assert(t, json.Unmarshal(rawPattern, &pattern))
|
||||
assert.Assert(t, json.Unmarshal(rawMap, &resource))
|
||||
|
||||
path, err := validateResourceElement(resource, pattern, pattern, "/")
|
||||
assert.Equal(t, path, "/spec/containers/0/resources/requests/memory/")
|
||||
|
@ -997,8 +997,8 @@ func TestValidateMap_RelativePathWithParentheses(t *testing.T) {
|
|||
}`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(rawPattern, &pattern)
|
||||
json.Unmarshal(rawMap, &resource)
|
||||
assert.Assert(t, json.Unmarshal(rawPattern, &pattern))
|
||||
assert.Assert(t, json.Unmarshal(rawMap, &resource))
|
||||
|
||||
path, err := validateResourceElement(resource, pattern, pattern, "/")
|
||||
assert.Equal(t, path, "")
|
||||
|
@ -1051,8 +1051,8 @@ func TestValidateMap_MalformedPath(t *testing.T) {
|
|||
}`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(rawPattern, &pattern)
|
||||
json.Unmarshal(rawMap, &resource)
|
||||
assert.Assert(t, json.Unmarshal(rawPattern, &pattern))
|
||||
assert.Assert(t, json.Unmarshal(rawMap, &resource))
|
||||
|
||||
path, err := validateResourceElement(resource, pattern, pattern, "/")
|
||||
assert.Equal(t, path, "/spec/containers/0/resources/requests/memory/")
|
||||
|
@ -1105,8 +1105,8 @@ func TestValidateMap_AbosolutePathExists(t *testing.T) {
|
|||
}`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(rawPattern, &pattern)
|
||||
json.Unmarshal(rawMap, &resource)
|
||||
assert.Assert(t, json.Unmarshal(rawPattern, &pattern))
|
||||
assert.Assert(t, json.Unmarshal(rawMap, &resource))
|
||||
|
||||
path, err := validateResourceElement(resource, pattern, pattern, "/")
|
||||
assert.Equal(t, path, "")
|
||||
|
@ -1146,8 +1146,8 @@ func TestValidateMap_AbsolutePathToMetadata(t *testing.T) {
|
|||
}`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(rawPattern, &pattern)
|
||||
json.Unmarshal(rawMap, &resource)
|
||||
assert.Assert(t, json.Unmarshal(rawPattern, &pattern))
|
||||
assert.Assert(t, json.Unmarshal(rawMap, &resource))
|
||||
|
||||
path, err := validateResourceElement(resource, pattern, pattern, "/")
|
||||
assert.Equal(t, path, "")
|
||||
|
@ -1188,8 +1188,8 @@ func TestValidateMap_AbsolutePathToMetadata_fail(t *testing.T) {
|
|||
}`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(rawPattern, &pattern)
|
||||
json.Unmarshal(rawMap, &resource)
|
||||
assert.Assert(t, json.Unmarshal(rawPattern, &pattern))
|
||||
assert.Assert(t, json.Unmarshal(rawMap, &resource))
|
||||
|
||||
path, err := validateResourceElement(resource, pattern, pattern, "/")
|
||||
assert.Equal(t, path, "/spec/containers/0/image/")
|
||||
|
@ -1242,8 +1242,8 @@ func TestValidateMap_AbosolutePathDoesNotExists(t *testing.T) {
|
|||
}`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(rawPattern, &pattern)
|
||||
json.Unmarshal(rawMap, &resource)
|
||||
assert.Assert(t, json.Unmarshal(rawPattern, &pattern))
|
||||
assert.Assert(t, json.Unmarshal(rawMap, &resource))
|
||||
|
||||
path, err := validateResourceElement(resource, pattern, pattern, "/")
|
||||
assert.Equal(t, path, "/spec/containers/0/resources/requests/memory/")
|
||||
|
@ -1274,7 +1274,7 @@ func TestActualizePattern_GivenRelativePathThatExists(t *testing.T) {
|
|||
|
||||
var pattern interface{}
|
||||
|
||||
json.Unmarshal(rawPattern, &pattern)
|
||||
assert.Assert(t, json.Unmarshal(rawPattern, &pattern))
|
||||
|
||||
pattern, err := actualizePattern(pattern, referencePath, absolutePath)
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ func Validate(policyContext PolicyContext) (resp response.EngineResponse) {
|
|||
resp := validateResource(ctx, policy, newR, admissionInfo)
|
||||
startResultResponse(resp, policy, newR)
|
||||
defer endResultResponse(resp, startTime)
|
||||
// set PatchedResource with orgin resource if empty
|
||||
// set PatchedResource with origin resource if empty
|
||||
// in order to create policy violation
|
||||
if reflect.DeepEqual(resp.PatchedResource, unstructured.Unstructured{}) {
|
||||
resp.PatchedResource = newR
|
||||
|
@ -79,11 +79,11 @@ func startResultResponse(resp *response.EngineResponse, policy kyverno.ClusterPo
|
|||
func endResultResponse(resp *response.EngineResponse, startTime time.Time) {
|
||||
resp.PolicyResponse.ProcessingTime = time.Since(startTime)
|
||||
glog.V(4).Infof("Finished applying validation rules policy %v (%v)", resp.PolicyResponse.Policy, resp.PolicyResponse.ProcessingTime)
|
||||
glog.V(4).Infof("Validation Rules appplied succesfully count %v for policy %q", resp.PolicyResponse.RulesAppliedCount, resp.PolicyResponse.Policy)
|
||||
glog.V(4).Infof("Validation Rules appplied successfully count %v for policy %q", resp.PolicyResponse.RulesAppliedCount, resp.PolicyResponse.Policy)
|
||||
}
|
||||
|
||||
func incrementAppliedCount(resp *response.EngineResponse) {
|
||||
// rules applied succesfully count
|
||||
// rules applied successfully count
|
||||
resp.PolicyResponse.RulesAppliedCount++
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,7 @@ func validateResource(ctx context.EvalInterface, policy kyverno.ClusterPolicy, r
|
|||
}
|
||||
|
||||
func isSameResponse(oldResponse, newResponse *response.EngineResponse) bool {
|
||||
// if the respones are same then return true
|
||||
// if the response are same then return true
|
||||
return isSamePolicyResponse(oldResponse.PolicyResponse, newResponse.PolicyResponse)
|
||||
|
||||
}
|
||||
|
@ -203,14 +203,14 @@ func validatePatterns(ctx context.EvalInterface, resource unstructured.Unstructu
|
|||
return resp
|
||||
}
|
||||
|
||||
// rule application succesful
|
||||
glog.V(4).Infof("rule %s pattern validated succesfully on resource %s/%s/%s", rule.Name, resource.GetKind(), resource.GetNamespace(), resource.GetName())
|
||||
// rule application successful
|
||||
glog.V(4).Infof("rule %s pattern validated successfully on resource %s/%s/%s", rule.Name, resource.GetKind(), resource.GetNamespace(), resource.GetName())
|
||||
resp.Success = true
|
||||
resp.Message = fmt.Sprintf("Validation rule '%s' succeeded.", rule.Name)
|
||||
return resp
|
||||
}
|
||||
|
||||
// using anyPattern we can define multiple patterns and only one of them has to be succesfully validated
|
||||
// using anyPattern we can define multiple patterns and only one of them has to be successfully validated
|
||||
// return directly if one pattern succeed
|
||||
// if none succeed, report violation / policyerror(TODO)
|
||||
if rule.Validation.AnyPattern != nil {
|
||||
|
@ -218,9 +218,9 @@ func validatePatterns(ctx context.EvalInterface, resource unstructured.Unstructu
|
|||
var failedPaths, invalidPaths []string
|
||||
for index, pattern := range rule.Validation.AnyPattern {
|
||||
path, err := validate.ValidateResourceWithPattern(ctx, resource.Object, pattern)
|
||||
// this pattern was succesfully validated
|
||||
// this pattern was successfully validated
|
||||
if reflect.DeepEqual(err, validate.ValidationError{}) {
|
||||
glog.V(4).Infof("anyPattern %v succesfully validated on resource %s/%s/%s", pattern, resource.GetKind(), resource.GetNamespace(), resource.GetName())
|
||||
glog.V(4).Infof("anyPattern %v successfully validated on resource %s/%s/%s", pattern, resource.GetKind(), resource.GetNamespace(), resource.GetName())
|
||||
resp.Success = true
|
||||
resp.Message = fmt.Sprintf("Validation rule '%s' anyPattern[%d] succeeded.", rule.Name, index)
|
||||
return resp
|
||||
|
|
|
@ -1457,7 +1457,7 @@ func Test_VariableSubstitutionPathNotExistInPattern(t *testing.T) {
|
|||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "substitue-variable"
|
||||
"name": "substitute-variable"
|
||||
},
|
||||
"spec": {
|
||||
"rules": [
|
||||
|
@ -1528,7 +1528,7 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_OnePatternStatisfies(t *t
|
|||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "substitue-variable"
|
||||
"name": "substitute-variable"
|
||||
},
|
||||
"spec": {
|
||||
"rules": [
|
||||
|
@ -1620,7 +1620,7 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_AllPathNotPresent(t *test
|
|||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "substitue-variable"
|
||||
"name": "substitute-variable"
|
||||
},
|
||||
"spec": {
|
||||
"rules": [
|
||||
|
@ -1710,7 +1710,7 @@ func Test_VariableSubstitutionPathNotExistInAnyPattern_AllPathPresent_NonePatter
|
|||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "ClusterPolicy",
|
||||
"metadata": {
|
||||
"name": "substitue-variable"
|
||||
"name": "substitute-variable"
|
||||
},
|
||||
"spec": {
|
||||
"rules": [
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/nirmata/kyverno/pkg/engine/variables/operator"
|
||||
)
|
||||
|
||||
//Evaluate evaluates the condition
|
||||
func Evaluate(ctx context.EvalInterface, condition kyverno.Condition) bool {
|
||||
// get handler for the operator
|
||||
handle := operator.CreateOperatorHandler(ctx, condition.Operator, SubstituteVariables)
|
||||
|
@ -16,6 +17,7 @@ func Evaluate(ctx context.EvalInterface, condition kyverno.Condition) bool {
|
|||
return handle.Evaluate(condition.Key, condition.Value)
|
||||
}
|
||||
|
||||
//EvaluateConditions evaluates multiple conditions
|
||||
func EvaluateConditions(ctx context.EvalInterface, conditions []kyverno.Condition) bool {
|
||||
// AND the conditions
|
||||
for _, condition := range conditions {
|
||||
|
|
|
@ -299,12 +299,20 @@ func Test_Eval_NoEqual_Const_float64_Fail(t *testing.T) {
|
|||
|
||||
func Test_Eval_Equal_Const_object_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
var err error
|
||||
|
||||
obj1Raw := []byte(`{ "dir": { "file1": "a" } }`)
|
||||
obj2Raw := []byte(`{ "dir": { "file1": "a" } }`)
|
||||
var obj1, obj2 interface{}
|
||||
json.Unmarshal(obj1Raw, &obj1)
|
||||
json.Unmarshal(obj2Raw, &obj2)
|
||||
err = json.Unmarshal(obj1Raw, &obj1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
err = json.Unmarshal(obj2Raw, &obj2)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// no variables
|
||||
condition := kyverno.Condition{
|
||||
Key: obj1,
|
||||
|
@ -319,12 +327,20 @@ func Test_Eval_Equal_Const_object_Pass(t *testing.T) {
|
|||
|
||||
func Test_Eval_Equal_Const_object_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
|
||||
var err error
|
||||
obj1Raw := []byte(`{ "dir": { "file1": "a" } }`)
|
||||
obj2Raw := []byte(`{ "dir": { "file1": "b" } }`)
|
||||
var obj1, obj2 interface{}
|
||||
json.Unmarshal(obj1Raw, &obj1)
|
||||
json.Unmarshal(obj2Raw, &obj2)
|
||||
err = json.Unmarshal(obj1Raw, &obj1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(obj2Raw, &obj2)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// no variables
|
||||
condition := kyverno.Condition{
|
||||
Key: obj1,
|
||||
|
@ -339,12 +355,20 @@ func Test_Eval_Equal_Const_object_Fail(t *testing.T) {
|
|||
|
||||
func Test_Eval_NotEqual_Const_object_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
|
||||
var err error
|
||||
obj1Raw := []byte(`{ "dir": { "file1": "a" } }`)
|
||||
obj2Raw := []byte(`{ "dir": { "file1": "b" } }`)
|
||||
var obj1, obj2 interface{}
|
||||
json.Unmarshal(obj1Raw, &obj1)
|
||||
json.Unmarshal(obj2Raw, &obj2)
|
||||
err = json.Unmarshal(obj1Raw, &obj1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(obj2Raw, &obj2)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// no variables
|
||||
condition := kyverno.Condition{
|
||||
Key: obj1,
|
||||
|
@ -359,12 +383,20 @@ func Test_Eval_NotEqual_Const_object_Pass(t *testing.T) {
|
|||
|
||||
func Test_Eval_NotEqual_Const_object_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
|
||||
var err error
|
||||
obj1Raw := []byte(`{ "dir": { "file1": "a" } }`)
|
||||
obj2Raw := []byte(`{ "dir": { "file1": "a" } }`)
|
||||
var obj1, obj2 interface{}
|
||||
json.Unmarshal(obj1Raw, &obj1)
|
||||
json.Unmarshal(obj2Raw, &obj2)
|
||||
err = json.Unmarshal(obj1Raw, &obj1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(obj2Raw, &obj2)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// no variables
|
||||
condition := kyverno.Condition{
|
||||
Key: obj1,
|
||||
|
@ -381,12 +413,20 @@ func Test_Eval_NotEqual_Const_object_Fail(t *testing.T) {
|
|||
|
||||
func Test_Eval_Equal_Const_list_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
|
||||
var err error
|
||||
obj1Raw := []byte(`[ { "name": "a", "file": "a" }, { "name": "b", "file": "b" } ]`)
|
||||
obj2Raw := []byte(`[ { "name": "a", "file": "a" }, { "name": "b", "file": "b" } ]`)
|
||||
var obj1, obj2 interface{}
|
||||
json.Unmarshal(obj1Raw, &obj1)
|
||||
json.Unmarshal(obj2Raw, &obj2)
|
||||
err = json.Unmarshal(obj1Raw, &obj1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(obj2Raw, &obj2)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// no variables
|
||||
condition := kyverno.Condition{
|
||||
Key: obj1,
|
||||
|
@ -401,12 +441,18 @@ func Test_Eval_Equal_Const_list_Pass(t *testing.T) {
|
|||
|
||||
func Test_Eval_Equal_Const_list_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
|
||||
var err error
|
||||
obj1Raw := []byte(`[ { "name": "a", "file": "a" }, { "name": "b", "file": "b" } ]`)
|
||||
obj2Raw := []byte(`[ { "name": "b", "file": "a" }, { "name": "b", "file": "b" } ]`)
|
||||
var obj1, obj2 interface{}
|
||||
json.Unmarshal(obj1Raw, &obj1)
|
||||
json.Unmarshal(obj2Raw, &obj2)
|
||||
err = json.Unmarshal(obj1Raw, &obj1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
err = json.Unmarshal(obj2Raw, &obj2)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
// no variables
|
||||
condition := kyverno.Condition{
|
||||
Key: obj1,
|
||||
|
@ -421,12 +467,18 @@ func Test_Eval_Equal_Const_list_Fail(t *testing.T) {
|
|||
|
||||
func Test_Eval_NotEqual_Const_list_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
|
||||
var err error
|
||||
obj1Raw := []byte(`[ { "name": "a", "file": "a" }, { "name": "b", "file": "b" } ]`)
|
||||
obj2Raw := []byte(`[ { "name": "b", "file": "a" }, { "name": "b", "file": "b" } ]`)
|
||||
var obj1, obj2 interface{}
|
||||
json.Unmarshal(obj1Raw, &obj1)
|
||||
json.Unmarshal(obj2Raw, &obj2)
|
||||
err = json.Unmarshal(obj1Raw, &obj1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
err = json.Unmarshal(obj2Raw, &obj2)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
// no variables
|
||||
condition := kyverno.Condition{
|
||||
Key: obj1,
|
||||
|
@ -441,12 +493,18 @@ func Test_Eval_NotEqual_Const_list_Pass(t *testing.T) {
|
|||
|
||||
func Test_Eval_NotEqual_Const_list_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
|
||||
var err error
|
||||
obj1Raw := []byte(`[ { "name": "a", "file": "a" }, { "name": "b", "file": "b" } ]`)
|
||||
obj2Raw := []byte(`[ { "name": "a", "file": "a" }, { "name": "b", "file": "b" } ]`)
|
||||
var obj1, obj2 interface{}
|
||||
json.Unmarshal(obj1Raw, &obj1)
|
||||
json.Unmarshal(obj2Raw, &obj2)
|
||||
err = json.Unmarshal(obj1Raw, &obj1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
err = json.Unmarshal(obj2Raw, &obj2)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
// no variables
|
||||
condition := kyverno.Condition{
|
||||
Key: obj1,
|
||||
|
@ -477,7 +535,10 @@ func Test_Eval_Equal_Var_Pass(t *testing.T) {
|
|||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(resourceRaw)
|
||||
err := ctx.AddResource(resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
condition := kyverno.Condition{
|
||||
Key: "{{request.object.metadata.name}}",
|
||||
Operator: kyverno.Equal,
|
||||
|
@ -505,7 +566,10 @@ func Test_Eval_Equal_Var_Fail(t *testing.T) {
|
|||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(resourceRaw)
|
||||
err := ctx.AddResource(resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
condition := kyverno.Condition{
|
||||
Key: "{{request.object.metadata.name}}",
|
||||
Operator: kyverno.Equal,
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/nirmata/kyverno/pkg/engine/context"
|
||||
)
|
||||
|
||||
//NewEqualHandler returns handler to manage Equal operations
|
||||
func NewEqualHandler(ctx context.EvalInterface, subHandler VariableSubstitutionHandler) OperatorHandler {
|
||||
return EqualHandler{
|
||||
ctx: ctx,
|
||||
|
@ -16,11 +17,13 @@ func NewEqualHandler(ctx context.EvalInterface, subHandler VariableSubstitutionH
|
|||
}
|
||||
}
|
||||
|
||||
//EqualHandler provides implementation to handle NotEqual Operator
|
||||
type EqualHandler struct {
|
||||
ctx context.EvalInterface
|
||||
subHandler VariableSubstitutionHandler
|
||||
}
|
||||
|
||||
//Evaluate evaluates expression with Equal Operator
|
||||
func (eh EqualHandler) Evaluate(key, value interface{}) bool {
|
||||
// substitute the variables
|
||||
nKey := eh.subHandler(eh.ctx, key)
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/nirmata/kyverno/pkg/engine/context"
|
||||
)
|
||||
|
||||
//NewNotEqualHandler returns handler to manage NotEqual operations
|
||||
func NewNotEqualHandler(ctx context.EvalInterface, subHandler VariableSubstitutionHandler) OperatorHandler {
|
||||
return NotEqualHandler{
|
||||
ctx: ctx,
|
||||
|
@ -16,11 +17,13 @@ func NewNotEqualHandler(ctx context.EvalInterface, subHandler VariableSubstituti
|
|||
}
|
||||
}
|
||||
|
||||
//NotEqualHandler provides implementation to handle NotEqual Operator
|
||||
type NotEqualHandler struct {
|
||||
ctx context.EvalInterface
|
||||
subHandler VariableSubstitutionHandler
|
||||
}
|
||||
|
||||
//Evaluate evaluates expression with NotEqual Operator
|
||||
func (neh NotEqualHandler) Evaluate(key, value interface{}) bool {
|
||||
// substitute the variables
|
||||
nKey := neh.subHandler(neh.ctx, key)
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"github.com/nirmata/kyverno/pkg/engine/context"
|
||||
)
|
||||
|
||||
//OperatorHandler provides interface to manage types
|
||||
type OperatorHandler interface {
|
||||
Evaluate(key, value interface{}) bool
|
||||
validateValuewithBoolPattern(key bool, value interface{}) bool
|
||||
|
@ -15,8 +16,10 @@ type OperatorHandler interface {
|
|||
validateValueWithSlicePattern(key []interface{}, value interface{}) bool
|
||||
}
|
||||
|
||||
//VariableSubstitutionHandler defines the handler function for variable substitution
|
||||
type VariableSubstitutionHandler = func(ctx context.EvalInterface, pattern interface{}) interface{}
|
||||
|
||||
//CreateOperatorHandler returns the operator handler based on the operator used in condition
|
||||
func CreateOperatorHandler(ctx context.EvalInterface, op kyverno.ConditionOperator, subHandler VariableSubstitutionHandler) OperatorHandler {
|
||||
switch op {
|
||||
case kyverno.Equal:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package variables
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
|
@ -42,6 +43,7 @@ func extractVariables(pattern interface{}) [][]string {
|
|||
case string:
|
||||
return extractValue(typedPattern)
|
||||
default:
|
||||
fmt.Printf("variable type %T", typedPattern)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,12 +37,14 @@ func Test_ExtractVariables(t *testing.T) {
|
|||
`)
|
||||
|
||||
var pattern interface{}
|
||||
json.Unmarshal(patternRaw, &pattern)
|
||||
if err := json.Unmarshal(patternRaw, &pattern); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
vars := extractVariables(pattern)
|
||||
|
||||
result := [][]string{[]string{"{{request.userInfo.username}}", "request.userInfo.username"},
|
||||
[]string{"{{request.object.metadata.name}}", "request.object.metadata.name"}}
|
||||
result := [][]string{{"{{request.userInfo.username}}", "request.userInfo.username"},
|
||||
{"{{request.object.metadata.name}}", "request.object.metadata.name"}}
|
||||
|
||||
assert.Assert(t, len(vars) == len(result), fmt.Sprintf("result does not match, var: %s", vars))
|
||||
}
|
||||
|
@ -95,10 +97,16 @@ func Test_ValidateVariables_NoVariable(t *testing.T) {
|
|||
assert.NilError(t, json.Unmarshal(patternRaw, &pattern))
|
||||
assert.NilError(t, json.Unmarshal(resourceRaw, &resource))
|
||||
|
||||
var err error
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(resourceRaw)
|
||||
ctx.AddUserInfo(userReqInfo)
|
||||
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
err = ctx.AddUserInfo(userReqInfo)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
invalidPaths := ValidateVariables(ctx, pattern)
|
||||
assert.Assert(t, len(invalidPaths) == 0)
|
||||
}
|
||||
|
@ -152,8 +160,15 @@ func Test_ValidateVariables(t *testing.T) {
|
|||
assert.NilError(t, json.Unmarshal(resourceRaw, &resource))
|
||||
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(resourceRaw)
|
||||
ctx.AddUserInfo(userReqInfo)
|
||||
var err error
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
err = ctx.AddUserInfo(userReqInfo)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
invalidPaths := ValidateVariables(ctx, pattern)
|
||||
assert.Assert(t, len(invalidPaths) > 0)
|
||||
|
|
|
@ -96,7 +96,7 @@ func getValueQuery(ctx context.EvalInterface, valuePattern string) interface{} {
|
|||
return newVal
|
||||
}
|
||||
|
||||
// we do not support mutliple substitution per statement for non-string types
|
||||
// we do not support multiple substitution per statement for non-string types
|
||||
for _, value := range varMap {
|
||||
return value
|
||||
}
|
||||
|
|
|
@ -59,12 +59,27 @@ func Test_variablesub1(t *testing.T) {
|
|||
resultMap := []byte(`{"data":{"rules":[{"apiGroups":[""],"resourceNames":["temp"],"resources":["namespaces"],"verbs":["*"]}]},"kind":"ClusterRole","name":"ns-owner-user1"}`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(patternMap, &pattern)
|
||||
json.Unmarshal(resourceRaw, &resource)
|
||||
var err error
|
||||
err = json.Unmarshal(patternMap, &pattern)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
err = json.Unmarshal(resourceRaw, &resource)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(resourceRaw)
|
||||
ctx.AddUserInfo(userReqInfo)
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = ctx.AddUserInfo(userReqInfo)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
value := SubstituteVariables(ctx, pattern)
|
||||
resultRaw, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
|
@ -125,12 +140,29 @@ func Test_variablesub_multiple(t *testing.T) {
|
|||
resultMap := []byte(`{"data":{"rules":[{"apiGroups":[""],"resourceNames":["temp"],"resources":["namespaces"],"verbs":["*"]}]},"kind":"ClusterRole","name":"ns-owner-n1-user1-bindings"}`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(patternMap, &pattern)
|
||||
json.Unmarshal(resourceRaw, &resource)
|
||||
var err error
|
||||
err = json.Unmarshal(patternMap, &pattern)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(resourceRaw, &resource)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(resourceRaw)
|
||||
ctx.AddUserInfo(userReqInfo)
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = ctx.AddUserInfo(userReqInfo)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
value := SubstituteVariables(ctx, pattern)
|
||||
resultRaw, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
|
@ -188,12 +220,29 @@ func Test_variablesubstitution(t *testing.T) {
|
|||
},
|
||||
}
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(patternMap, &pattern)
|
||||
json.Unmarshal(resourceRaw, &resource)
|
||||
var err error
|
||||
err = json.Unmarshal(patternMap, &pattern)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(resourceRaw, &resource)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(resourceRaw)
|
||||
ctx.AddUserInfo(userReqInfo)
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = ctx.AddUserInfo(userReqInfo)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
value := SubstituteVariables(ctx, pattern)
|
||||
resultRaw, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
|
@ -231,12 +280,24 @@ func Test_variableSubstitutionValue(t *testing.T) {
|
|||
resultMap := []byte(`{"spec":{"name":"temp"}}`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(patternMap, &pattern)
|
||||
json.Unmarshal(resourceRaw, &resource)
|
||||
var err error
|
||||
err = json.Unmarshal(patternMap, &pattern)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(resourceRaw, &resource)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(resourceRaw)
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
value := SubstituteVariables(ctx, pattern)
|
||||
resultRaw, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
|
@ -271,12 +332,24 @@ func Test_variableSubstitutionValueOperatorNotEqual(t *testing.T) {
|
|||
resultMap := []byte(`{"spec":{"name":"!temp"}}`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(patternMap, &pattern)
|
||||
json.Unmarshal(resourceRaw, &resource)
|
||||
var err error
|
||||
err = json.Unmarshal(patternMap, &pattern)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(resourceRaw, &resource)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(resourceRaw)
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
value := SubstituteVariables(ctx, pattern)
|
||||
resultRaw, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
|
@ -313,12 +386,24 @@ func Test_variableSubstitutionValueFail(t *testing.T) {
|
|||
resultMap := []byte(`{"spec":{"name":null}}`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(patternMap, &pattern)
|
||||
json.Unmarshal(resourceRaw, &resource)
|
||||
var err error
|
||||
err = json.Unmarshal(patternMap, &pattern)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(resourceRaw, &resource)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(resourceRaw)
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
value := SubstituteVariables(ctx, pattern)
|
||||
resultRaw, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
|
@ -360,12 +445,24 @@ func Test_variableSubstitutionObject(t *testing.T) {
|
|||
resultMap := []byte(`{"spec":{"variable":{"var1":"temp1","var2":"temp2","varNested":{"var1":"temp1"}}}}`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(patternMap, &pattern)
|
||||
json.Unmarshal(resourceRaw, &resource)
|
||||
var err error
|
||||
err = json.Unmarshal(patternMap, &pattern)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(resourceRaw, &resource)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(resourceRaw)
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
value := SubstituteVariables(ctx, pattern)
|
||||
resultRaw, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
|
@ -408,12 +505,24 @@ func Test_variableSubstitutionObjectOperatorNotEqualFail(t *testing.T) {
|
|||
resultMap := []byte(`{"spec":{"variable":null}}`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(patternMap, &pattern)
|
||||
json.Unmarshal(resourceRaw, &resource)
|
||||
var err error
|
||||
err = json.Unmarshal(patternMap, &pattern)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(resourceRaw, &resource)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(resourceRaw)
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
value := SubstituteVariables(ctx, pattern)
|
||||
resultRaw, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
|
@ -457,12 +566,24 @@ func Test_variableSubstitutionMultipleObject(t *testing.T) {
|
|||
resultMap := []byte(`{"spec":{"var":"temp1","variable":{"var1":"temp1","var2":"temp2","varNested":{"var1":"temp1"}}}}`)
|
||||
|
||||
var pattern, resource interface{}
|
||||
json.Unmarshal(patternMap, &pattern)
|
||||
json.Unmarshal(resourceRaw, &resource)
|
||||
var err error
|
||||
err = json.Unmarshal(patternMap, &pattern)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(resourceRaw, &resource)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// context
|
||||
ctx := context.NewContext()
|
||||
ctx.AddResource(resourceRaw)
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
value := SubstituteVariables(ctx, pattern)
|
||||
resultRaw, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
|
|
|
@ -85,7 +85,7 @@ func (gen *Generator) Add(infos ...Info) {
|
|||
if info.Name == "" {
|
||||
// dont create event for resources with generateName
|
||||
// as the name is not generated yet
|
||||
glog.V(4).Infof("recieved info %v, not creating an event as the resource has not been assigned a name yet", info)
|
||||
glog.V(4).Infof("received info %v, not creating an event as the resource has not been assigned a name yet", info)
|
||||
continue
|
||||
}
|
||||
gen.queue.Add(info)
|
||||
|
|
|
@ -2,8 +2,6 @@ package event
|
|||
|
||||
const eventWorkQueueName = "kyverno-events"
|
||||
|
||||
const eventWorkerThreadCount = 1
|
||||
|
||||
const workQueueRetryLimit = 5
|
||||
|
||||
//Info defines the event details
|
||||
|
|
|
@ -35,7 +35,7 @@ func (c *Controller) processGR(gr kyverno.GenerateRequest) error {
|
|||
createTime := gr.GetCreationTimestamp()
|
||||
if time.Since(createTime.UTC()) > timeout {
|
||||
// the GR was in state ["",Failed] for more than timeout
|
||||
glog.V(4).Infof("GR %s was not processed succesfully in %d minutes", gr.Name, timoutMins)
|
||||
glog.V(4).Infof("GR %s was not processed successfully in %d minutes", gr.Name, timoutMins)
|
||||
glog.V(4).Infof("delete GR %s", gr.Name)
|
||||
return c.control.Delete(gr.Name)
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ func deleteGeneratedResources(client *dclient.Client, gr kyverno.GenerateRequest
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ const (
|
|||
maxRetries = 5
|
||||
)
|
||||
|
||||
//Controller manages life-cycle of generate-requests
|
||||
type Controller struct {
|
||||
// dyanmic client implementation
|
||||
client *dclient.Client
|
||||
|
@ -54,6 +55,7 @@ type Controller struct {
|
|||
nsInformer informers.GenericInformer
|
||||
}
|
||||
|
||||
//NewController returns a new controller instance to manage generate-requests
|
||||
func NewController(
|
||||
kyvernoclient *kyvernoclient.Clientset,
|
||||
client *dclient.Client,
|
||||
|
@ -106,10 +108,10 @@ func (c *Controller) deleteGenericResource(obj interface{}) {
|
|||
glog.Errorf("failed to Generate Requests for resource %s/%s/%s: %v", r.GetKind(), r.GetNamespace(), r.GetName(), err)
|
||||
return
|
||||
}
|
||||
// re-evaluate the GR as the resource was deleted
|
||||
for _, gr := range grs {
|
||||
c.enqueueGR(gr)
|
||||
}
|
||||
// re-evaluate the GR as the resource was deleted
|
||||
for _, gr := range grs {
|
||||
c.enqueueGR(gr)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Controller) deletePolicy(obj interface{}) {
|
||||
|
@ -179,6 +181,7 @@ func (c *Controller) enqueue(gr *kyverno.GenerateRequest) {
|
|||
c.queue.Add(key)
|
||||
}
|
||||
|
||||
//Run starts the generate-request re-conciliation loop
|
||||
func (c *Controller) Run(workers int, stopCh <-chan struct{}) {
|
||||
defer utilruntime.HandleCrash()
|
||||
defer c.queue.ShutDown()
|
||||
|
|
|
@ -5,14 +5,17 @@ import (
|
|||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// ControlInterface manages resource deletes
|
||||
type ControlInterface interface {
|
||||
Delete(gr string) error
|
||||
}
|
||||
|
||||
//Control provides implementation to manage resource
|
||||
type Control struct {
|
||||
client kyvernoclient.Interface
|
||||
}
|
||||
|
||||
//Delete deletes the specified resource
|
||||
func (c Control) Delete(gr string) error {
|
||||
return c.client.KyvernoV1().GenerateRequests("kyverno").Delete(gr,&metav1.DeleteOptions{})
|
||||
return c.client.KyvernoV1().GenerateRequests("kyverno").Delete(gr, &metav1.DeleteOptions{})
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ const (
|
|||
maxRetries = 5
|
||||
)
|
||||
|
||||
// Controller manages the life-cycle for Generate-Requests and applies generate rule
|
||||
type Controller struct {
|
||||
// dyanmic client implementation
|
||||
client *dclient.Client
|
||||
|
@ -58,6 +59,7 @@ type Controller struct {
|
|||
nsInformer informers.GenericInformer
|
||||
}
|
||||
|
||||
//NewController returns an instance of the Generate-Request Controller
|
||||
func NewController(
|
||||
kyvernoclient *kyvernoclient.Clientset,
|
||||
client *dclient.Client,
|
||||
|
|
|
@ -2,7 +2,7 @@ package generate
|
|||
|
||||
import "fmt"
|
||||
|
||||
// DATA
|
||||
// ParseFailed stores the resource that failed to parse
|
||||
type ParseFailed struct {
|
||||
spec interface{}
|
||||
parseError error
|
||||
|
@ -12,10 +12,12 @@ func (e *ParseFailed) Error() string {
|
|||
return fmt.Sprintf("failed to parse the resource spec %v: %v", e.spec, e.parseError.Error())
|
||||
}
|
||||
|
||||
//NewParseFailed returns a new ParseFailed error
|
||||
func NewParseFailed(spec interface{}, err error) *ParseFailed {
|
||||
return &ParseFailed{spec: spec, parseError: err}
|
||||
}
|
||||
|
||||
//Violation stores the rule that violated
|
||||
type Violation struct {
|
||||
rule string
|
||||
err error
|
||||
|
@ -25,10 +27,12 @@ func (e *Violation) Error() string {
|
|||
return fmt.Sprintf("creating Violation; error %s", e.err)
|
||||
}
|
||||
|
||||
//NewViolation returns a new Violation error
|
||||
func NewViolation(rule string, err error) *Violation {
|
||||
return &Violation{rule: rule, err: err}
|
||||
}
|
||||
|
||||
// NotFound stores the resource that was not found
|
||||
type NotFound struct {
|
||||
kind string
|
||||
namespace string
|
||||
|
@ -39,10 +43,12 @@ func (e *NotFound) Error() string {
|
|||
return fmt.Sprintf("resource %s/%s/%s not present", e.kind, e.namespace, e.name)
|
||||
}
|
||||
|
||||
//NewNotFound returns a new NotFound error
|
||||
func NewNotFound(kind, namespace, name string) *NotFound {
|
||||
return &NotFound{kind: kind, namespace: namespace, name: name}
|
||||
}
|
||||
|
||||
//ConfigNotFound stores the config information
|
||||
type ConfigNotFound struct {
|
||||
config interface{}
|
||||
kind string
|
||||
|
@ -54,6 +60,7 @@ func (e *ConfigNotFound) Error() string {
|
|||
return fmt.Sprintf("configuration %v, not present in resource %s/%s/%s", e.config, e.kind, e.namespace, e.name)
|
||||
}
|
||||
|
||||
//NewConfigNotFound returns a new NewConfigNotFound error
|
||||
func NewConfigNotFound(config interface{}, kind, namespace, name string) *ConfigNotFound {
|
||||
return &ConfigNotFound{config: config, kind: kind, namespace: namespace, name: name}
|
||||
}
|
||||
|
|
|
@ -66,10 +66,21 @@ func (c *Controller) applyGenerate(resource unstructured.Unstructured, gr kyvern
|
|||
glog.V(4).Infof("failed to marshal resource: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.AddResource(resourceRaw)
|
||||
ctx.AddUserInfo(gr.Spec.Context.UserRequestInfo)
|
||||
ctx.AddSA(gr.Spec.Context.UserRequestInfo.AdmissionUserInfo.Username)
|
||||
err = ctx.AddResource(resourceRaw)
|
||||
if err != nil {
|
||||
glog.Infof("Failed to load resource in context: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
err = ctx.AddUserInfo(gr.Spec.Context.UserRequestInfo)
|
||||
if err != nil {
|
||||
glog.Infof("Failed to load userInfo in context: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
err = ctx.AddSA(gr.Spec.Context.UserRequestInfo.AdmissionUserInfo.Username)
|
||||
if err != nil {
|
||||
glog.Infof("Failed to load serviceAccount in context: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
policyContext := engine.PolicyContext{
|
||||
NewResource: resource,
|
||||
|
@ -79,7 +90,7 @@ func (c *Controller) applyGenerate(resource unstructured.Unstructured, gr kyvern
|
|||
}
|
||||
|
||||
// check if the policy still applies to the resource
|
||||
engineResponse := engine.GenerateNew(policyContext)
|
||||
engineResponse := engine.Generate(policyContext)
|
||||
if len(engineResponse.PolicyResponse.Rules) == 0 {
|
||||
glog.V(4).Infof("policy %s, dont not apply to resource %v", gr.Spec.Policy, gr.Spec.Resource)
|
||||
return nil, fmt.Errorf("policy %s, dont not apply to resource %v", gr.Spec.Policy, gr.Spec.Resource)
|
||||
|
@ -255,7 +266,10 @@ func handleData(ruleName string, generateRule kyverno.Generation, client *dclien
|
|||
return nil, NewViolation(ruleName, fmt.Errorf("path not present in generate data: %s", invalidPaths))
|
||||
}
|
||||
|
||||
newData := variables.SubstituteVariables(ctx, generateRule.Data)
|
||||
//work on copy
|
||||
copyDataTemp := reflect.Indirect(reflect.ValueOf(generateRule.Data))
|
||||
copyData := copyDataTemp.Interface()
|
||||
newData := variables.SubstituteVariables(ctx, copyData)
|
||||
|
||||
// check if resource exists
|
||||
obj, err := client.GetResource(generateRule.Kind, generateRule.Namespace, generateRule.Name)
|
||||
|
@ -339,7 +353,7 @@ func generatePV(gr kyverno.GenerateRequest, resource unstructured.Unstructured,
|
|||
info := policyviolation.Info{
|
||||
PolicyName: gr.Spec.Policy,
|
||||
Resource: resource,
|
||||
Rules: []kyverno.ViolatedRule{kyverno.ViolatedRule{
|
||||
Rules: []kyverno.ViolatedRule{{
|
||||
Name: err.rule,
|
||||
Type: "Generation",
|
||||
Message: err.Error(),
|
||||
|
|
|
@ -14,8 +14,8 @@ import (
|
|||
func reportEvents(err error, eventGen event.Interface, gr kyverno.GenerateRequest, resource unstructured.Unstructured) {
|
||||
if err == nil {
|
||||
// Success Events
|
||||
// - resource -> policy rule applied succesfully
|
||||
// - policy -> rule succesfully applied on resource
|
||||
// - resource -> policy rule applied successfully
|
||||
// - policy -> rule successfully applied on resource
|
||||
events := successEvents(gr, resource)
|
||||
eventGen.Add(events...)
|
||||
return
|
||||
|
@ -95,7 +95,7 @@ func successEvents(gr kyverno.GenerateRequest, resource unstructured.Unstructure
|
|||
pe.Name = gr.Spec.Policy
|
||||
pe.Reason = event.PolicyApplied.String()
|
||||
pe.Source = event.GeneratePolicyController
|
||||
pe.Message = fmt.Sprintf("applied succesfully on resource %s/%s/%s", resource.GetKind(), resource.GetNamespace(), resource.GetName())
|
||||
pe.Message = fmt.Sprintf("applied successfully on resource %s/%s/%s", resource.GetKind(), resource.GetNamespace(), resource.GetName())
|
||||
events = append(events, pe)
|
||||
|
||||
// Resource
|
||||
|
@ -105,7 +105,7 @@ func successEvents(gr kyverno.GenerateRequest, resource unstructured.Unstructure
|
|||
re.Name = resource.GetName()
|
||||
re.Reason = event.PolicyApplied.String()
|
||||
re.Source = event.GeneratePolicyController
|
||||
re.Message = fmt.Sprintf("policy %s succesfully applied", gr.Spec.Policy)
|
||||
re.Message = fmt.Sprintf("policy %s successfully applied", gr.Spec.Policy)
|
||||
events = append(events, re)
|
||||
|
||||
return events
|
||||
|
|
|
@ -2,10 +2,10 @@ package generate
|
|||
|
||||
import (
|
||||
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
dclient "github.com/nirmata/kyverno/pkg/dclient"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
||||
func getResource(client *dclient.Client, resourceSpec kyverno.ResourceSpec) (*unstructured.Unstructured,error) {
|
||||
func getResource(client *dclient.Client, resourceSpec kyverno.ResourceSpec) (*unstructured.Unstructured, error) {
|
||||
return client.GetResource(resourceSpec.Kind, resourceSpec.Namespace, resourceSpec.Name)
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
kyvernoclient "github.com/nirmata/kyverno/pkg/client/clientset/versioned"
|
||||
)
|
||||
|
||||
//StatusControlInterface provides interface to update status subresource
|
||||
type StatusControlInterface interface {
|
||||
Failed(gr kyverno.GenerateRequest, message string, genResources []kyverno.ResourceSpec) error
|
||||
Success(gr kyverno.GenerateRequest, genResources []kyverno.ResourceSpec) error
|
||||
|
@ -16,7 +17,7 @@ type StatusControl struct {
|
|||
client kyvernoclient.Interface
|
||||
}
|
||||
|
||||
//FailedGR sets gr status.state to failed with message
|
||||
//Failed sets gr status.state to failed with message
|
||||
func (sc StatusControl) Failed(gr kyverno.GenerateRequest, message string, genResources []kyverno.ResourceSpec) error {
|
||||
gr.Status.State = kyverno.Failed
|
||||
gr.Status.Message = message
|
||||
|
@ -31,7 +32,7 @@ func (sc StatusControl) Failed(gr kyverno.GenerateRequest, message string, genRe
|
|||
return nil
|
||||
}
|
||||
|
||||
// SuccessGR sets the gr status.state to completed and clears message
|
||||
// Success sets the gr status.state to completed and clears message
|
||||
func (sc StatusControl) Success(gr kyverno.GenerateRequest, genResources []kyverno.ResourceSpec) error {
|
||||
gr.Status.State = kyverno.Completed
|
||||
gr.Status.Message = ""
|
||||
|
|
|
@ -112,7 +112,7 @@ func applyPolicyOnRaw(policy *kyverno.ClusterPolicy, rawResource []byte, gvk *me
|
|||
glog.Warning(r.Message)
|
||||
}
|
||||
} else if len(engineResponse.PolicyResponse.Rules) > 0 {
|
||||
glog.Infof("Mutation from policy %s has applied succesfully to %s %s/%s", policy.Name, gvk.Kind, rname, rns)
|
||||
glog.Infof("Mutation from policy %s has applied successfully to %s %s/%s", policy.Name, gvk.Kind, rname, rns)
|
||||
|
||||
// Process Validation
|
||||
engineResponse := engine.Validate(engine.PolicyContext{Policy: *policy, NewResource: *resource})
|
||||
|
@ -124,7 +124,7 @@ func applyPolicyOnRaw(policy *kyverno.ClusterPolicy, rawResource []byte, gvk *me
|
|||
}
|
||||
return patchedResource, fmt.Errorf("policy %s on resource %s/%s not satisfied", policy.Name, rname, rns)
|
||||
} else if len(engineResponse.PolicyResponse.Rules) > 0 {
|
||||
glog.Infof("Validation from policy %s has applied succesfully to %s %s/%s", policy.Name, gvk.Kind, rname, rns)
|
||||
glog.Infof("Validation from policy %s has applied successfully to %s %s/%s", policy.Name, gvk.Kind, rname, rns)
|
||||
}
|
||||
}
|
||||
return patchedResource, nil
|
||||
|
|
|
@ -94,6 +94,8 @@ func scanDir(dir string) ([]string, error) {
|
|||
|
||||
return res[1:], nil
|
||||
}
|
||||
|
||||
//ConvertToUnstructured converts the resource to unstructured format
|
||||
func ConvertToUnstructured(data []byte) (*unstructured.Unstructured, error) {
|
||||
resource := &unstructured.Unstructured{}
|
||||
err := resource.UnmarshalJSON(data)
|
||||
|
|
|
@ -173,7 +173,7 @@ func (nsc *NamespaceController) Run(workers int, stopCh <-chan struct{}) {
|
|||
return
|
||||
}
|
||||
|
||||
for i := 0; i < workerCount; i++ {
|
||||
for i := 0; i < workers; i++ {
|
||||
go wait.Until(nsc.worker, time.Second, stopCh)
|
||||
}
|
||||
<-stopCh
|
||||
|
|
|
@ -66,7 +66,7 @@ func (rm *ResourceManager) ProcessResource(policy, pv, kind, ns, name, rv string
|
|||
|
||||
key := buildKey(policy, pv, kind, ns, name, rv)
|
||||
_, ok := rm.data[key]
|
||||
return ok == false
|
||||
return !ok
|
||||
}
|
||||
|
||||
//Drop drop the cache after every rebuild interval mins
|
||||
|
@ -98,7 +98,7 @@ func (nsc *NamespaceController) processNamespace(namespace corev1.Namespace) []r
|
|||
|
||||
ns := unstructured.Unstructured{Object: unstr}
|
||||
|
||||
// get all the policies that have a generate rule and resource description satifies the namespace
|
||||
// get all the policies that have a generate rule and resource description satisfies the namespace
|
||||
// apply policy on resource
|
||||
policies := listpolicies(ns, nsc.pMetaStore)
|
||||
var engineResponses []response.EngineResponse
|
||||
|
@ -233,7 +233,7 @@ func applyPolicy(client *client.Client, resource unstructured.Unstructured, p ky
|
|||
Client: client,
|
||||
Context: ctx,
|
||||
}
|
||||
engineResponse := engine.GenerateNew(policyContext)
|
||||
engineResponse := engine.Generate(policyContext)
|
||||
// gather stats
|
||||
gatherStat(p.Name, engineResponse.PolicyResponse)
|
||||
//send stats
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
package namespace
|
||||
|
||||
const (
|
||||
wqNamespace string = "namespace"
|
||||
workerCount int = 1
|
||||
wqRetryLimit int = 5
|
||||
)
|
|
@ -129,7 +129,7 @@ func getFailedOverallRuleInfo(resource unstructured.Unstructured, engineResponse
|
|||
return response.EngineResponse{}, err
|
||||
}
|
||||
if !jsonpatch.Equal(patchedResource, rawResource) {
|
||||
glog.V(4).Infof("policy %s rule %s condition not satisifed by existing resource", engineResponse.PolicyResponse.Policy, rule.Name)
|
||||
glog.V(4).Infof("policy %s rule %s condition not satisfied by existing resource", engineResponse.PolicyResponse.Policy, rule.Name)
|
||||
engineResponse.PolicyResponse.Rules[index].Success = false
|
||||
engineResponse.PolicyResponse.Rules[index].Message = fmt.Sprintf("mutation json patches not found at resource path %s", extractPatchPath(rule.Patches))
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
||||
kyvernolister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1"
|
||||
"github.com/nirmata/kyverno/pkg/engine/response"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
|
@ -88,18 +87,3 @@ func getNamespacedPV(nspvLister kyvernolister.PolicyViolationLister, policyName,
|
|||
|
||||
return kyverno.PolicyViolation{}, nil
|
||||
}
|
||||
|
||||
func converLabelToSelector(labelMap map[string]string) (labels.Selector, error) {
|
||||
ls := &metav1.LabelSelector{}
|
||||
err := metav1.Convert_Map_string_To_string_To_v1_LabelSelector(&labelMap, ls, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
policyViolationSelector, err := metav1.LabelSelectorAsSelector(ls)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid label selector: %v", err)
|
||||
}
|
||||
|
||||
return policyViolationSelector, nil
|
||||
}
|
||||
|
|
|
@ -38,8 +38,6 @@ const (
|
|||
maxRetries = 15
|
||||
)
|
||||
|
||||
var controllerKind = kyverno.SchemeGroupVersion.WithKind("ClusterPolicy")
|
||||
|
||||
// PolicyController is responsible for synchronizing Policy objects stored
|
||||
// in the system with the corresponding policy violations
|
||||
type PolicyController struct {
|
||||
|
@ -70,7 +68,7 @@ type PolicyController struct {
|
|||
rm resourceManager
|
||||
// helpers to validate against current loaded configuration
|
||||
configHandler config.Interface
|
||||
// recieves stats and aggregates details
|
||||
// receives stats and aggregates details
|
||||
statusAggregator *PolicyStatusAggregator
|
||||
// store to hold policy meta data for faster lookup
|
||||
pMetaStore policystore.UpdateInterface
|
||||
|
@ -188,7 +186,10 @@ func (pc *PolicyController) updatePolicy(old, cur interface{}) {
|
|||
curP := cur.(*kyverno.ClusterPolicy)
|
||||
// TODO: optimize this : policy meta-store
|
||||
// Update policy-> (remove,add)
|
||||
pc.pMetaStore.UnRegister(*oldP)
|
||||
err := pc.pMetaStore.UnRegister(*oldP)
|
||||
if err != nil {
|
||||
glog.Infof("Failed to unregister policy %s", oldP.Name)
|
||||
}
|
||||
pc.pMetaStore.Register(*curP)
|
||||
|
||||
// Only process policies that are enabled for "background" execution
|
||||
|
@ -230,7 +231,9 @@ func (pc *PolicyController) deletePolicy(obj interface{}) {
|
|||
}
|
||||
glog.V(4).Infof("Deleting Policy %s", p.Name)
|
||||
// Unregister from policy meta-store
|
||||
pc.pMetaStore.UnRegister(*p)
|
||||
if err := pc.pMetaStore.UnRegister(*p); err != nil {
|
||||
glog.Infof("failed to unregister policy %s", p.Name)
|
||||
}
|
||||
// we process policies that are not set of background processing as we need to perform policy violation
|
||||
// cleanup when a policy is deleted.
|
||||
pc.enqueuePolicy(p)
|
||||
|
@ -447,7 +450,7 @@ type RealPVControl struct {
|
|||
Recorder record.EventRecorder
|
||||
}
|
||||
|
||||
//DeletePolicyViolation deletes the policy violation
|
||||
//DeleteClusterPolicyViolation deletes the policy violation
|
||||
func (r RealPVControl) DeleteClusterPolicyViolation(name string) error {
|
||||
return r.Client.KyvernoV1().ClusterPolicyViolations().Delete(name, &metav1.DeleteOptions{})
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ func (pc *PolicyController) processExistingResources(policy kyverno.ClusterPolic
|
|||
// apply the policy on each
|
||||
glog.V(4).Infof("apply policy %s with resource version %s on resource %s/%s/%s with resource version %s", policy.Name, policy.ResourceVersion, resource.GetKind(), resource.GetNamespace(), resource.GetName(), resource.GetResourceVersion())
|
||||
engineResponse := applyPolicy(policy, resource, pc.statusAggregator)
|
||||
// get engine response for mutation & validation indipendently
|
||||
// get engine response for mutation & validation independently
|
||||
engineResponses = append(engineResponses, engineResponse...)
|
||||
// post-processing, register the resource as processed
|
||||
pc.rm.RegisterResource(policy.GetName(), policy.GetResourceVersion(), resource.GetKind(), resource.GetNamespace(), resource.GetName(), resource.GetResourceVersion())
|
||||
|
@ -225,12 +225,16 @@ func excludeResources(included map[string]unstructured.Unstructured, exclude kyv
|
|||
}
|
||||
}
|
||||
|
||||
//Condition defines condition type
|
||||
type Condition int
|
||||
|
||||
const (
|
||||
//NotEvaluate to not evaluate condition
|
||||
NotEvaluate Condition = 0
|
||||
Process Condition = 1
|
||||
Skip Condition = 2
|
||||
// Process to evaluate condition
|
||||
Process Condition = 1
|
||||
// Skip to ignore/skip the condition
|
||||
Skip Condition = 2
|
||||
)
|
||||
|
||||
// merge b into a map
|
||||
|
@ -239,47 +243,6 @@ func mergeresources(a, b map[string]unstructured.Unstructured) {
|
|||
a[k] = v
|
||||
}
|
||||
}
|
||||
func mergeLabelSectors(include, exclude *metav1.LabelSelector) *metav1.LabelSelector {
|
||||
if exclude == nil {
|
||||
return include
|
||||
}
|
||||
// negate the exclude information
|
||||
// copy the label selector
|
||||
//TODO: support exclude expressions in exclude
|
||||
ls := include.DeepCopy()
|
||||
for k, v := range exclude.MatchLabels {
|
||||
lsreq := metav1.LabelSelectorRequirement{
|
||||
Key: k,
|
||||
Operator: metav1.LabelSelectorOpNotIn,
|
||||
Values: []string{v},
|
||||
}
|
||||
ls.MatchExpressions = append(ls.MatchExpressions, lsreq)
|
||||
}
|
||||
return ls
|
||||
}
|
||||
|
||||
func kindIsExcluded(kind string, list []string) bool {
|
||||
for _, b := range list {
|
||||
if b == kind {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func excludeNamespaces(namespaces, excludeNs []string) []string {
|
||||
if len(excludeNs) == 0 {
|
||||
return namespaces
|
||||
}
|
||||
filteredNamespaces := []string{}
|
||||
for _, n := range namespaces {
|
||||
if utils.ContainsNamepace(excludeNs, n) {
|
||||
continue
|
||||
}
|
||||
filteredNamespaces = append(filteredNamespaces, n)
|
||||
}
|
||||
return filteredNamespaces
|
||||
}
|
||||
|
||||
func getAllNamespaces(client *client.Client) []string {
|
||||
var namespaces []string
|
||||
|
@ -357,7 +320,7 @@ func (rm *ResourceManager) ProcessResource(policy, pv, kind, ns, name, rv string
|
|||
|
||||
key := buildKey(policy, pv, kind, ns, name, rv)
|
||||
_, ok := rm.data[key]
|
||||
return ok == false
|
||||
return !ok
|
||||
}
|
||||
|
||||
func buildKey(policy, pv, kind, ns, name, rv string) string {
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
type PolicyStatusAggregator struct {
|
||||
// time since we start aggregating the stats
|
||||
startTime time.Time
|
||||
// channel to recieve stats
|
||||
// channel to receive stats
|
||||
ch chan PolicyStat
|
||||
//TODO: lock based on key, possibly sync.Map ?
|
||||
//sync RW for policyData
|
||||
|
@ -47,13 +47,13 @@ func (psa *PolicyStatusAggregator) Run(workers int, stopCh <-chan struct{}) {
|
|||
}
|
||||
|
||||
func (psa *PolicyStatusAggregator) process() {
|
||||
// As mutation and validation are handled seperately
|
||||
// ideally we need to combine the exection time from both for a policy
|
||||
// As mutation and validation are handled separately
|
||||
// ideally we need to combine the execution time from both for a policy
|
||||
// but its tricky to detect here the type of rules policy contains
|
||||
// so we dont combine the results, but instead compute the execution time for
|
||||
// mutation & validation rules seperately
|
||||
// mutation & validation rules separately
|
||||
for r := range psa.ch {
|
||||
glog.V(4).Infof("recieved policy stats %v", r)
|
||||
glog.V(4).Infof("received policy stats %v", r)
|
||||
psa.aggregate(r)
|
||||
}
|
||||
}
|
||||
|
@ -178,6 +178,7 @@ type PolicyStat struct {
|
|||
Stats PolicyStatInfo
|
||||
}
|
||||
|
||||
//PolicyStatInfo provides statistics for policy
|
||||
type PolicyStatInfo struct {
|
||||
MutationExecutionTime time.Duration
|
||||
ValidationExecutionTime time.Duration
|
||||
|
@ -187,6 +188,7 @@ type PolicyStatInfo struct {
|
|||
Rules []RuleStatinfo
|
||||
}
|
||||
|
||||
//RuleStatinfo provides statistics for rule
|
||||
type RuleStatinfo struct {
|
||||
RuleName string
|
||||
ExecutionTime time.Duration
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
package policy
|
||||
|
||||
import kyverno "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
||||
|
||||
// reEvaulatePolicy checks if the policy needs to be re-evaulated
|
||||
// during re-evaulation we remove all the old policy violations and re-create new ones
|
||||
// - Rule count changes
|
||||
// - Rule resource description changes
|
||||
// - Rule operation changes
|
||||
// - Rule name changed
|
||||
func reEvaulatePolicy(curP, oldP *kyverno.ClusterPolicy) bool {
|
||||
// count of rules changed
|
||||
if len(curP.Spec.Rules) != len(curP.Spec.Rules) {
|
||||
|
||||
}
|
||||
return true
|
||||
}
|
|
@ -20,9 +20,8 @@ func (pc *PolicyController) removeResourceWebhookConfiguration() error {
|
|||
}
|
||||
|
||||
glog.V(4).Info("no policies with mutating or validating webhook configurations, remove resource webhook configuration if one exists")
|
||||
return pc.resourceWebhookWatcher.RemoveResourceWebhookConfiguration()
|
||||
|
||||
return nil
|
||||
return pc.resourceWebhookWatcher.RemoveResourceWebhookConfiguration()
|
||||
}
|
||||
|
||||
func (pc *PolicyController) registerResourceWebhookConfiguration() {
|
||||
|
|
|
@ -230,7 +230,10 @@ func Test_Operations(t *testing.T) {
|
|||
}
|
||||
|
||||
// Remove
|
||||
store.UnRegister(policy1)
|
||||
err = store.UnRegister(policy1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
retPolicies, err = store.LookUp("Pod", "")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
|
|
@ -8,9 +8,10 @@ import (
|
|||
"github.com/nirmata/kyverno/pkg/engine/response"
|
||||
)
|
||||
|
||||
//GeneratePVsFromEngineResponse generate Violations from engine responses
|
||||
func GeneratePVsFromEngineResponse(ers []response.EngineResponse) (pvInfos []Info) {
|
||||
for _, er := range ers {
|
||||
// ignore creation of PV for resoruces that are yet to be assigned a name
|
||||
// ignore creation of PV for resources that are yet to be assigned a name
|
||||
if er.PolicyResponse.Resource.Name == "" {
|
||||
glog.V(4).Infof("resource %v, has not been assigned a name, not creating a policy violation for it", er.PolicyResponse.Resource)
|
||||
continue
|
||||
|
|
|
@ -9,23 +9,23 @@ import (
|
|||
|
||||
func Test_GeneratePVsFromEngineResponse_PathNotExist(t *testing.T) {
|
||||
ers := []response.EngineResponse{
|
||||
response.EngineResponse{
|
||||
{
|
||||
PolicyResponse: response.PolicyResponse{
|
||||
Policy: "test-substitue-variable",
|
||||
Policy: "test-substitute-variable",
|
||||
Resource: response.ResourceSpec{
|
||||
Kind: "Pod",
|
||||
Name: "test",
|
||||
Namespace: "test",
|
||||
},
|
||||
Rules: []response.RuleResponse{
|
||||
response.RuleResponse{
|
||||
{
|
||||
Name: "test-path-not-exist",
|
||||
Type: "Mutation",
|
||||
Message: "referenced paths are not present: request.object.metadata.name1",
|
||||
Success: true,
|
||||
PathNotPresent: true,
|
||||
},
|
||||
response.RuleResponse{
|
||||
{
|
||||
Name: "test-path-exist",
|
||||
Type: "Mutation",
|
||||
Success: true,
|
||||
|
@ -34,17 +34,17 @@ func Test_GeneratePVsFromEngineResponse_PathNotExist(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
response.EngineResponse{
|
||||
{
|
||||
PolicyResponse: response.PolicyResponse{
|
||||
Policy: "test-substitue-variable2",
|
||||
Policy: "test-substitute-variable2",
|
||||
Resource: response.ResourceSpec{
|
||||
Kind: "Pod",
|
||||
Name: "test",
|
||||
Namespace: "test",
|
||||
},
|
||||
Rules: []response.RuleResponse{
|
||||
response.RuleResponse{
|
||||
Name: "test-path-not-exist-accross-policy",
|
||||
{
|
||||
Name: "test-path-not-exist-across-policy",
|
||||
Type: "Mutation",
|
||||
Message: "referenced paths are not present: request.object.metadata.name1",
|
||||
Success: true,
|
||||
|
|
|
@ -214,10 +214,9 @@ func (gen *Generator) processNextWorkitem() bool {
|
|||
}
|
||||
|
||||
func (gen *Generator) syncHandler(info Info) error {
|
||||
glog.V(4).Infof("recieved info:%v", info)
|
||||
glog.V(4).Infof("received info:%v", info)
|
||||
var handler pvGenerator
|
||||
var builder Builder
|
||||
builder = newPvBuilder()
|
||||
builder := newPvBuilder()
|
||||
if info.Resource.GetNamespace() == "" {
|
||||
// cluster scope resource generate a clusterpolicy violation
|
||||
handler = newClusterPV(gen.dclient, gen.cpvLister, gen.kyvernoInterface)
|
||||
|
|
|
@ -111,6 +111,6 @@ func (nspv *namespacedPV) updatePV(newPv, oldPv *kyverno.PolicyViolation) error
|
|||
if err != nil {
|
||||
return fmt.Errorf("failed to update namespaced polciy violation: %v", err)
|
||||
}
|
||||
glog.Infof("namespced policy violation updated for resource %v", newPv.Spec.ResourceSpec)
|
||||
glog.Infof("namespaced policy violation updated for resource %v", newPv.Spec.ResourceSpec)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
ospath "path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
|
@ -51,19 +50,19 @@ type sExpected struct {
|
|||
type sMutation struct {
|
||||
// path to the patched resource to be compared with
|
||||
PatchedResource string `yaml:"patchedresource,omitempty"`
|
||||
// expected respone from the policy engine
|
||||
// expected response from the policy engine
|
||||
PolicyResponse response.PolicyResponse `yaml:"policyresponse"`
|
||||
}
|
||||
|
||||
type sValidation struct {
|
||||
// expected respone from the policy engine
|
||||
// expected response from the policy engine
|
||||
PolicyResponse response.PolicyResponse `yaml:"policyresponse"`
|
||||
}
|
||||
|
||||
type sGeneration struct {
|
||||
// generated resources
|
||||
GeneratedResources []kyverno.ResourceSpec `yaml:"generatedResources"`
|
||||
// expected respone from the policy engine
|
||||
// expected response from the policy engine
|
||||
PolicyResponse response.PolicyResponse `yaml:"policyresponse"`
|
||||
}
|
||||
|
||||
|
@ -81,7 +80,7 @@ func loadScenario(t *testing.T, path string) (*scenarioT, error) {
|
|||
}
|
||||
|
||||
var testCases []scaseT
|
||||
// load test cases seperated by '---'
|
||||
// load test cases separated by '---'
|
||||
// each test case defines an input & expected result
|
||||
scenariosBytes := bytes.Split(fileBytes, []byte("---"))
|
||||
for _, scenarioBytes := range scenariosBytes {
|
||||
|
@ -109,24 +108,6 @@ func loadFile(t *testing.T, path string) ([]byte, error) {
|
|||
return ioutil.ReadFile(path)
|
||||
}
|
||||
|
||||
//getFiles loads all scneario files in specified folder path
|
||||
func getFiles(t *testing.T, folder string) ([]string, error) {
|
||||
t.Logf("loading scneario files for folder %s", folder)
|
||||
files, err := ioutil.ReadDir(folder)
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var yamls []string
|
||||
for _, file := range files {
|
||||
if filepath.Ext(file.Name()) == ".yml" || filepath.Ext(file.Name()) == ".yaml" {
|
||||
yamls = append(yamls, ospath.Join(folder, file.Name()))
|
||||
}
|
||||
}
|
||||
return yamls, nil
|
||||
}
|
||||
|
||||
func runScenario(t *testing.T, s *scenarioT) bool {
|
||||
for _, tc := range s.testCases {
|
||||
runTestCase(t, tc)
|
||||
|
@ -179,7 +160,7 @@ func runTestCase(t *testing.T, tc scaseT) bool {
|
|||
Client: client,
|
||||
}
|
||||
|
||||
er = engine.GenerateNew(policyContext)
|
||||
er = engine.Generate(policyContext)
|
||||
t.Log(("---Generation---"))
|
||||
validateResponse(t, er.PolicyResponse, tc.Expected.Generation.PolicyResponse)
|
||||
// Expected generate resource will be in same namesapces as resource
|
||||
|
@ -238,10 +219,10 @@ func validateResponse(t *testing.T, er response.PolicyResponse, expected respons
|
|||
}
|
||||
// cant do deepEquals and the stats will be different, or we nil those fields and then do a comparison
|
||||
// forcing only the fields that are specified to be comprared
|
||||
// doing a field by fields comparsion will allow us to provied more details logs and granular error reporting
|
||||
// doing a field by fields comparison will allow us to provied more details logs and granular error reporting
|
||||
// check policy name is same :P
|
||||
if er.Policy != expected.Policy {
|
||||
t.Errorf("Policy name: expected %s, recieved %s", expected.Policy, er.Policy)
|
||||
t.Errorf("Policy name: expected %s, received %s", expected.Policy, er.Policy)
|
||||
}
|
||||
// compare resource spec
|
||||
compareResourceSpec(t, er.Resource, expected.Resource)
|
||||
|
@ -257,7 +238,7 @@ func validateResponse(t *testing.T, er response.PolicyResponse, expected respons
|
|||
}
|
||||
if len(er.Rules) == len(expected.Rules) {
|
||||
// if there are rules being applied then we compare the rule response
|
||||
// as the rules are applied in the order defined, the comparions of rules will be in order
|
||||
// as the rules are applied in the order defined, the comparison of rules will be in order
|
||||
for index, r := range expected.Rules {
|
||||
compareRules(t, er.Rules[index], r)
|
||||
}
|
||||
|
@ -267,7 +248,7 @@ func validateResponse(t *testing.T, er response.PolicyResponse, expected respons
|
|||
func compareResourceSpec(t *testing.T, resource response.ResourceSpec, expectedResource response.ResourceSpec) {
|
||||
// kind
|
||||
if resource.Kind != expectedResource.Kind {
|
||||
t.Errorf("kind: expected %s, recieved %s", expectedResource.Kind, resource.Kind)
|
||||
t.Errorf("kind: expected %s, received %s", expectedResource.Kind, resource.Kind)
|
||||
}
|
||||
// //TODO apiVersion
|
||||
// if resource.APIVersion != expectedResource.APIVersion {
|
||||
|
@ -276,28 +257,28 @@ func compareResourceSpec(t *testing.T, resource response.ResourceSpec, expectedR
|
|||
|
||||
// namespace
|
||||
if resource.Namespace != expectedResource.Namespace {
|
||||
t.Errorf("namespace: expected %s, recieved %s", expectedResource.Namespace, resource.Namespace)
|
||||
t.Errorf("namespace: expected %s, received %s", expectedResource.Namespace, resource.Namespace)
|
||||
}
|
||||
// name
|
||||
if resource.Name != expectedResource.Name {
|
||||
t.Errorf("name: expected %s, recieved %s", expectedResource.Name, resource.Name)
|
||||
t.Errorf("name: expected %s, received %s", expectedResource.Name, resource.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func compareRules(t *testing.T, rule response.RuleResponse, expectedRule response.RuleResponse) {
|
||||
// name
|
||||
if rule.Name != expectedRule.Name {
|
||||
t.Errorf("rule name: expected %s, recieved %+v", expectedRule.Name, rule.Name)
|
||||
t.Errorf("rule name: expected %s, received %+v", expectedRule.Name, rule.Name)
|
||||
// as the rule names dont match no need to compare the rest of the information
|
||||
}
|
||||
// type
|
||||
if rule.Type != expectedRule.Type {
|
||||
t.Errorf("rule type: expected %s, recieved %s", expectedRule.Type, rule.Type)
|
||||
t.Errorf("rule type: expected %s, received %s", expectedRule.Type, rule.Type)
|
||||
}
|
||||
// message
|
||||
// compare messages if expected rule message is not empty
|
||||
if expectedRule.Message != "" && rule.Message != expectedRule.Message {
|
||||
t.Errorf("rule message: expected %s, recieved %s", expectedRule.Message, rule.Message)
|
||||
t.Errorf("rule message: expected %s, received %s", expectedRule.Message, rule.Message)
|
||||
}
|
||||
// //TODO patches
|
||||
// if reflect.DeepEqual(rule.Patches, expectedRule.Patches) {
|
||||
|
@ -306,7 +287,7 @@ func compareRules(t *testing.T, rule response.RuleResponse, expectedRule respons
|
|||
|
||||
// success
|
||||
if rule.Success != expectedRule.Success {
|
||||
t.Errorf("rule success: expected %t, recieved %t", expectedRule.Success, rule.Success)
|
||||
t.Errorf("rule success: expected %t, received %t", expectedRule.Success, rule.Success)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
defaultYamlSeparator = "---"
|
||||
projectPath = "src/github.com/nirmata/kyverno"
|
||||
projectPath = "src/github.com/nirmata/kyverno"
|
||||
)
|
||||
|
||||
// LoadFile loads file in byte buffer
|
||||
|
@ -38,6 +37,7 @@ func getResourceFromKind(kind string) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
//ConvertToUnstructured converts a resource to unstructured format
|
||||
func ConvertToUnstructured(data []byte) (*unstructured.Unstructured, error) {
|
||||
resource := &unstructured.Unstructured{}
|
||||
err := resource.UnmarshalJSON(data)
|
||||
|
|
|
@ -18,6 +18,7 @@ const (
|
|||
rolekind = "Role"
|
||||
)
|
||||
|
||||
//GetRoleRef gets the list of roles and cluster roles for the incoming api-request
|
||||
func GetRoleRef(rbLister rbaclister.RoleBindingLister, crbLister rbaclister.ClusterRoleBindingLister, request *v1beta1.AdmissionRequest) (roles []string, clusterRoles []string, err error) {
|
||||
// rolebindings
|
||||
roleBindings, err := rbLister.List(labels.NewSelector())
|
||||
|
|
|
@ -161,49 +161,50 @@ func Test_matchSubjectsMap(t *testing.T) {
|
|||
assert.Assert(t, !res)
|
||||
}
|
||||
|
||||
func newRoleBinding(name, ns string, subjects []rbacv1.Subject, roles rbacv1.RoleRef) *rbacv1.RoleBinding {
|
||||
rb := &rbacv1.RoleBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: ns},
|
||||
Subjects: subjects,
|
||||
RoleRef: roles,
|
||||
}
|
||||
|
||||
rb.Kind = "RoleBinding"
|
||||
rb.APIVersion = "rbac.authorization.k8s.io/v1"
|
||||
return rb
|
||||
}
|
||||
|
||||
func Test_getRoleRefByRoleBindings(t *testing.T) {
|
||||
flag.Parse()
|
||||
flag.Set("logtostderr", "true")
|
||||
flag.Set("v", "3")
|
||||
|
||||
list := []*rbacv1.RoleBinding{
|
||||
&rbacv1.RoleBinding{
|
||||
metav1.TypeMeta{
|
||||
Kind: "RoleBinding",
|
||||
APIVersion: "rbac.authorization.k8s.io/v1",
|
||||
},
|
||||
metav1.ObjectMeta{Name: "test1", Namespace: "mynamespace"},
|
||||
[]rbacv1.Subject{
|
||||
rbacv1.Subject{
|
||||
Kind: "ServiceAccount",
|
||||
Name: "saconfig",
|
||||
Namespace: "default",
|
||||
},
|
||||
},
|
||||
rbacv1.RoleRef{
|
||||
Kind: rolekind,
|
||||
Name: "myrole",
|
||||
list := make([]*rbacv1.RoleBinding, 2)
|
||||
|
||||
list[0] = newRoleBinding("test1", "mynamespace",
|
||||
[]rbacv1.Subject{
|
||||
{
|
||||
Kind: "ServiceAccount",
|
||||
Name: "saconfig",
|
||||
Namespace: "default",
|
||||
},
|
||||
}, rbacv1.RoleRef{
|
||||
Kind: rolekind,
|
||||
Name: "myrole",
|
||||
},
|
||||
&rbacv1.RoleBinding{
|
||||
metav1.TypeMeta{
|
||||
Kind: "RoleBinding",
|
||||
APIVersion: "rbac.authorization.k8s.io/v1",
|
||||
},
|
||||
metav1.ObjectMeta{Name: "test2", Namespace: "mynamespace"},
|
||||
[]rbacv1.Subject{
|
||||
rbacv1.Subject{
|
||||
Kind: "ServiceAccount",
|
||||
Name: "saconfig",
|
||||
Namespace: "default",
|
||||
},
|
||||
},
|
||||
rbacv1.RoleRef{
|
||||
Kind: clusterrolekind,
|
||||
Name: "myclusterrole",
|
||||
)
|
||||
|
||||
list[1] = newRoleBinding("test2", "mynamespace",
|
||||
[]rbacv1.Subject{
|
||||
{
|
||||
Kind: "ServiceAccount",
|
||||
Name: "saconfig",
|
||||
Namespace: "default",
|
||||
},
|
||||
}, rbacv1.RoleRef{
|
||||
Kind: clusterrolekind,
|
||||
Name: "myclusterrole",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
sa := authenticationv1.UserInfo{
|
||||
Username: "system:serviceaccount:default:saconfig",
|
||||
|
@ -217,44 +218,46 @@ func Test_getRoleRefByRoleBindings(t *testing.T) {
|
|||
assert.Assert(t, reflect.DeepEqual(clusterroles, expectedClusterRole))
|
||||
}
|
||||
|
||||
func Test_getRoleRefByClusterRoleBindings(t *testing.T) {
|
||||
list := []*rbacv1.ClusterRoleBinding{
|
||||
&rbacv1.ClusterRoleBinding{
|
||||
metav1.TypeMeta{
|
||||
Kind: "ClusterRoleBinding",
|
||||
APIVersion: "rbac.authorization.k8s.io/v1",
|
||||
},
|
||||
metav1.ObjectMeta{Name: "test1", Namespace: "mynamespace"},
|
||||
[]rbacv1.Subject{
|
||||
rbacv1.Subject{
|
||||
Kind: "User",
|
||||
Name: "kube-scheduler",
|
||||
},
|
||||
},
|
||||
rbacv1.RoleRef{
|
||||
Kind: clusterrolekind,
|
||||
Name: "fakeclusterrole",
|
||||
},
|
||||
},
|
||||
&rbacv1.ClusterRoleBinding{
|
||||
metav1.TypeMeta{
|
||||
Kind: "ClusterRoleBinding",
|
||||
APIVersion: "rbac.authorization.k8s.io/v1",
|
||||
},
|
||||
metav1.ObjectMeta{Name: "test2", Namespace: "mynamespace"},
|
||||
[]rbacv1.Subject{
|
||||
rbacv1.Subject{
|
||||
Kind: "Group",
|
||||
Name: "system:masters",
|
||||
},
|
||||
},
|
||||
rbacv1.RoleRef{
|
||||
Kind: clusterrolekind,
|
||||
Name: "myclusterrole",
|
||||
},
|
||||
},
|
||||
func newClusterRoleBinding(name, ns string, subjects []rbacv1.Subject, roles rbacv1.RoleRef) *rbacv1.ClusterRoleBinding {
|
||||
rb := &rbacv1.ClusterRoleBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: ns},
|
||||
Subjects: subjects,
|
||||
RoleRef: roles,
|
||||
}
|
||||
|
||||
rb.Kind = "ClusterRoleBinding"
|
||||
rb.APIVersion = "rbac.authorization.k8s.io/v1"
|
||||
return rb
|
||||
}
|
||||
|
||||
func Test_getRoleRefByClusterRoleBindings(t *testing.T) {
|
||||
|
||||
list := make([]*rbacv1.ClusterRoleBinding, 2)
|
||||
|
||||
list[0] = newClusterRoleBinding("test1", "mynamespace",
|
||||
[]rbacv1.Subject{
|
||||
{
|
||||
Kind: "User",
|
||||
Name: "kube-scheduler",
|
||||
},
|
||||
}, rbacv1.RoleRef{
|
||||
Kind: clusterrolekind,
|
||||
Name: "fakeclusterrole",
|
||||
},
|
||||
)
|
||||
|
||||
list[1] = newClusterRoleBinding("test2", "mynamespace",
|
||||
[]rbacv1.Subject{
|
||||
{
|
||||
Kind: "Group",
|
||||
Name: "system:masters",
|
||||
},
|
||||
}, rbacv1.RoleRef{
|
||||
Kind: clusterrolekind,
|
||||
Name: "myclusterrole",
|
||||
},
|
||||
)
|
||||
|
||||
group := authenticationv1.UserInfo{
|
||||
Username: "kubernetes-admin",
|
||||
Groups: []string{"system:masters", "system:authenticated"},
|
||||
|
|
|
@ -7,10 +7,10 @@ import (
|
|||
|
||||
"github.com/minio/minio/pkg/wildcard"
|
||||
client "github.com/nirmata/kyverno/pkg/dclient"
|
||||
dclient "github.com/nirmata/kyverno/pkg/dclient"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
dclient "github.com/nirmata/kyverno/pkg/dclient"
|
||||
)
|
||||
|
||||
//Contains Check if strint is contained in a list of string
|
||||
|
@ -75,6 +75,8 @@ func CRDInstalled(discovery client.IDiscovery) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
//CleanupOldCrd deletes any existing NamespacedPolicyViolation resources in cluster
|
||||
// If resource violates policy, new Violations will be generated
|
||||
func CleanupOldCrd(client *dclient.Client) {
|
||||
gvr := client.DiscoveryClient.GetGVRFromKind("NamespacedPolicyViolation")
|
||||
if !reflect.DeepEqual(gvr, (schema.GroupVersionResource{})) {
|
||||
|
|
|
@ -75,6 +75,6 @@ func (wrc *WebhookRegistrationClient) removeVerifyWebhookMutatingWebhookConfig(w
|
|||
} else if err != nil {
|
||||
glog.Errorf("failed to delete verify webhook configuration %s: %v", mutatingConfig, err)
|
||||
} else {
|
||||
glog.V(4).Infof("succesfully deleted verify webhook configuration %s", mutatingConfig)
|
||||
glog.V(4).Infof("successfully deleted verify webhook configuration %s", mutatingConfig)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"github.com/golang/glog"
|
||||
"github.com/nirmata/kyverno/pkg/config"
|
||||
admregapi "k8s.io/api/admissionregistration/v1beta1"
|
||||
errorsapi "k8s.io/apimachinery/pkg/api/errors"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
|
@ -105,43 +104,3 @@ func (wrc *WebhookRegistrationClient) contructDebugPolicyMutatingWebhookConfig(c
|
|||
},
|
||||
}
|
||||
}
|
||||
|
||||
// removePolicyWebhookConfigurations removes mutating and validating webhook configurations, if already presnt
|
||||
// webhookConfigurations are re-created later
|
||||
func (wrc *WebhookRegistrationClient) removePolicyWebhookConfigurations() {
|
||||
// Validating webhook configuration
|
||||
var err error
|
||||
var validatingConfig string
|
||||
if wrc.serverIP != "" {
|
||||
validatingConfig = config.PolicyValidatingWebhookConfigurationDebugName
|
||||
} else {
|
||||
validatingConfig = config.PolicyValidatingWebhookConfigurationName
|
||||
}
|
||||
glog.V(4).Infof("removing webhook configuration %s", validatingConfig)
|
||||
err = wrc.client.DeleteResource(ValidatingWebhookConfigurationKind, "", validatingConfig, false)
|
||||
if errorsapi.IsNotFound(err) {
|
||||
glog.V(4).Infof("policy webhook configuration %s, does not exits. not deleting", validatingConfig)
|
||||
} else if err != nil {
|
||||
glog.Errorf("failed to delete policy webhook configuration %s: %v", validatingConfig, err)
|
||||
} else {
|
||||
glog.V(4).Infof("succesfully deleted policy webhook configuration %s", validatingConfig)
|
||||
}
|
||||
|
||||
// Mutating webhook configuration
|
||||
var mutatingConfig string
|
||||
if wrc.serverIP != "" {
|
||||
mutatingConfig = config.PolicyMutatingWebhookConfigurationDebugName
|
||||
} else {
|
||||
mutatingConfig = config.PolicyMutatingWebhookConfigurationName
|
||||
}
|
||||
|
||||
glog.V(4).Infof("removing webhook configuration %s", mutatingConfig)
|
||||
err = wrc.client.DeleteResource(MutatingWebhookConfigurationKind, "", mutatingConfig, false)
|
||||
if errorsapi.IsNotFound(err) {
|
||||
glog.V(4).Infof("policy webhook configuration %s, does not exits. not deleting", mutatingConfig)
|
||||
} else if err != nil {
|
||||
glog.Errorf("failed to delete policy webhook configuration %s: %v", mutatingConfig, err)
|
||||
} else {
|
||||
glog.V(4).Infof("succesfully deleted policy webhook configuration %s", mutatingConfig)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,9 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
MutatingWebhookConfigurationKind string = "MutatingWebhookConfiguration"
|
||||
//MutatingWebhookConfigurationKind defines the kind for MutatingWebhookConfiguration
|
||||
MutatingWebhookConfigurationKind string = "MutatingWebhookConfiguration"
|
||||
//ValidatingWebhookConfigurationKind defines the kind for ValidatingWebhookConfiguration
|
||||
ValidatingWebhookConfigurationKind string = "ValidatingWebhookConfiguration"
|
||||
)
|
||||
|
||||
|
@ -236,7 +238,9 @@ func (wrc *WebhookRegistrationClient) removeWebhookConfigurations() {
|
|||
// TODO: re-work with RemoveResourceMutatingWebhookConfiguration, as the only difference is wg handling
|
||||
func (wrc *WebhookRegistrationClient) removeResourceMutatingWebhookConfiguration(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
wrc.RemoveResourceMutatingWebhookConfiguration()
|
||||
if err := wrc.RemoveResourceMutatingWebhookConfiguration(); err != nil {
|
||||
glog.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
// delete policy mutating webhookconfigurations
|
||||
|
@ -258,7 +262,7 @@ func (wrc *WebhookRegistrationClient) removePolicyMutatingWebhookConfiguration(w
|
|||
} else if err != nil {
|
||||
glog.Errorf("failed to delete policy webhook configuration %s: %v", mutatingConfig, err)
|
||||
} else {
|
||||
glog.V(4).Infof("succesfully deleted policy webhook configuration %s", mutatingConfig)
|
||||
glog.V(4).Infof("successfully deleted policy webhook configuration %s", mutatingConfig)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -280,6 +284,6 @@ func (wrc *WebhookRegistrationClient) removePolicyValidatingWebhookConfiguration
|
|||
} else if err != nil {
|
||||
glog.Errorf("failed to delete policy webhook configuration %s: %v", validatingConfig, err)
|
||||
} else {
|
||||
glog.V(4).Infof("succesfully deleted policy webhook configuration %s", validatingConfig)
|
||||
glog.V(4).Infof("successfully deleted policy webhook configuration %s", validatingConfig)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
cache "k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
//ResourceWebhookRegister manages the resource webhook registration
|
||||
type ResourceWebhookRegister struct {
|
||||
// pendingCreation indicates the status of resource webhook creation
|
||||
pendingCreation *abool.AtomicBool
|
||||
|
@ -21,6 +22,7 @@ type ResourceWebhookRegister struct {
|
|||
webhookRegistrationClient *WebhookRegistrationClient
|
||||
}
|
||||
|
||||
// NewResourceWebhookRegister returns a new instance of ResourceWebhookRegister manager
|
||||
func NewResourceWebhookRegister(
|
||||
lastReqTime *checker.LastReqTime,
|
||||
mconfigwebhookinformer mconfiginformer.MutatingWebhookConfigurationInformer,
|
||||
|
@ -35,6 +37,7 @@ func NewResourceWebhookRegister(
|
|||
}
|
||||
}
|
||||
|
||||
//RegisterResourceWebhook registers a resource webhook
|
||||
func (rww *ResourceWebhookRegister) RegisterResourceWebhook() {
|
||||
// drop the request if creation is in processing
|
||||
if rww.pendingCreation.IsSet() {
|
||||
|
@ -72,6 +75,7 @@ func (rww *ResourceWebhookRegister) RegisterResourceWebhook() {
|
|||
}
|
||||
}
|
||||
|
||||
//Run starts the ResourceWebhookRegister manager
|
||||
func (rww *ResourceWebhookRegister) Run(stopCh <-chan struct{}) {
|
||||
// wait for cache to populate first time
|
||||
if !cache.WaitForCacheSync(stopCh, rww.mwebhookconfigSynced) {
|
||||
|
@ -79,6 +83,7 @@ func (rww *ResourceWebhookRegister) Run(stopCh <-chan struct{}) {
|
|||
}
|
||||
}
|
||||
|
||||
// RemoveResourceWebhookConfiguration removes the resource webhook configurations
|
||||
func (rww *ResourceWebhookRegister) RemoveResourceWebhookConfiguration() error {
|
||||
var err error
|
||||
// check informer cache
|
||||
|
|
|
@ -17,7 +17,7 @@ func newPolicyResponse(policy, rule string, patchesStr []string, success bool) r
|
|||
return response.PolicyResponse{
|
||||
Policy: policy,
|
||||
Rules: []response.RuleResponse{
|
||||
response.RuleResponse{
|
||||
{
|
||||
Name: rule,
|
||||
Patches: patches,
|
||||
Success: success},
|
||||
|
|
|
@ -92,19 +92,6 @@ func (i *ArrayFlags) Set(value string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// extract the kinds that the policy rules apply to
|
||||
func getApplicableKindsForPolicy(p *kyverno.ClusterPolicy) []string {
|
||||
kinds := []string{}
|
||||
// iterate over the rules an identify all kinds
|
||||
// Matching
|
||||
for _, rule := range p.Spec.Rules {
|
||||
for _, k := range rule.MatchResources.Kinds {
|
||||
kinds = append(kinds, k)
|
||||
}
|
||||
}
|
||||
return kinds
|
||||
}
|
||||
|
||||
// Policy Reporting Modes
|
||||
const (
|
||||
Enforce = "enforce" // blocks the request on failure
|
||||
|
|
|
@ -12,17 +12,20 @@ import (
|
|||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
)
|
||||
|
||||
//GenerateRequests provides interface to manage generate requests
|
||||
type GenerateRequests interface {
|
||||
Create(gr kyverno.GenerateRequestSpec) error
|
||||
}
|
||||
|
||||
// Generator defines the implmentation to mange generate request resource
|
||||
type Generator struct {
|
||||
// channel to recieve request
|
||||
// channel to receive request
|
||||
ch chan kyverno.GenerateRequestSpec
|
||||
client *kyvernoclient.Clientset
|
||||
stopCh <-chan struct{}
|
||||
}
|
||||
|
||||
//NewGenerator returns a new instance of Generate-Request resource generator
|
||||
func NewGenerator(client *kyvernoclient.Clientset, stopCh <-chan struct{}) *Generator {
|
||||
gen := &Generator{
|
||||
ch: make(chan kyverno.GenerateRequestSpec, 1000),
|
||||
|
@ -32,7 +35,7 @@ func NewGenerator(client *kyvernoclient.Clientset, stopCh <-chan struct{}) *Gene
|
|||
return gen
|
||||
}
|
||||
|
||||
// blocking if channel is full
|
||||
//Create to create generate request resoruce (blocking call if channel is full)
|
||||
func (g *Generator) Create(gr kyverno.GenerateRequestSpec) error {
|
||||
glog.V(4).Infof("create GR %v", gr)
|
||||
// Send to channel
|
||||
|
@ -60,7 +63,7 @@ func (g *Generator) Run(workers int) {
|
|||
|
||||
func (g *Generator) process() {
|
||||
for r := range g.ch {
|
||||
glog.V(4).Infof("recived generate request %v", r)
|
||||
glog.V(4).Infof("received generate request %v", r)
|
||||
if err := g.generate(r); err != nil {
|
||||
glog.Errorf("Failed to create Generate Request CR: %v", err)
|
||||
}
|
||||
|
@ -75,7 +78,7 @@ func (g *Generator) generate(grSpec kyverno.GenerateRequestSpec) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// -> recieving channel to take requests to create request
|
||||
// -> receiving channel to take requests to create request
|
||||
// use worker pattern to read and create the CR resource
|
||||
|
||||
func retryCreateResource(client *kyvernoclient.Clientset, grSpec kyverno.GenerateRequestSpec) error {
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
v1beta1 "k8s.io/api/admission/v1beta1"
|
||||
)
|
||||
|
||||
//HandleGenerate handles admission-requests for policies with generate rules
|
||||
func (ws *WebhookServer) HandleGenerate(request *v1beta1.AdmissionRequest, policies []kyverno.ClusterPolicy, patchedResource []byte, roles, clusterRoles []string) (bool, string) {
|
||||
var engineResponses []response.EngineResponse
|
||||
|
||||
|
@ -33,10 +34,19 @@ func (ws *WebhookServer) HandleGenerate(request *v1beta1.AdmissionRequest, polic
|
|||
// build context
|
||||
ctx := context.NewContext()
|
||||
// load incoming resource into the context
|
||||
ctx.AddResource(request.Object.Raw)
|
||||
ctx.AddUserInfo(userRequestInfo)
|
||||
err = ctx.AddResource(request.Object.Raw)
|
||||
if err != nil {
|
||||
glog.Infof("Failed to load resource in context:%v", err)
|
||||
}
|
||||
err = ctx.AddUserInfo(userRequestInfo)
|
||||
if err != nil {
|
||||
glog.Infof("Failed to load userInfo in context:%v", err)
|
||||
}
|
||||
// load service account in context
|
||||
ctx.AddSA(userRequestInfo.AdmissionUserInfo.Username)
|
||||
err = ctx.AddSA(userRequestInfo.AdmissionUserInfo.Username)
|
||||
if err != nil {
|
||||
glog.Infof("Failed to load service account in context:%v", err)
|
||||
}
|
||||
|
||||
policyContext := engine.PolicyContext{
|
||||
NewResource: *resource,
|
||||
|
@ -47,7 +57,7 @@ func (ws *WebhookServer) HandleGenerate(request *v1beta1.AdmissionRequest, polic
|
|||
// engine.Generate returns a list of rules that are applicable on this resource
|
||||
for _, policy := range policies {
|
||||
policyContext.Policy = policy
|
||||
engineResponse := engine.GenerateNew(policyContext)
|
||||
engineResponse := engine.Generate(policyContext)
|
||||
if len(engineResponse.PolicyResponse.Rules) > 0 {
|
||||
// some generate rules do apply to the resource
|
||||
engineResponses = append(engineResponses, engineResponse)
|
||||
|
|
|
@ -66,10 +66,21 @@ func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest, resou
|
|||
|
||||
// build context
|
||||
ctx := context.NewContext()
|
||||
var err error
|
||||
// load incoming resource into the context
|
||||
ctx.AddResource(request.Object.Raw)
|
||||
ctx.AddUserInfo(userRequestInfo)
|
||||
ctx.AddSA(userRequestInfo.AdmissionUserInfo.Username)
|
||||
err = ctx.AddResource(request.Object.Raw)
|
||||
if err != nil {
|
||||
glog.Infof("Failed to load resource in context:%v", err)
|
||||
}
|
||||
|
||||
err = ctx.AddUserInfo(userRequestInfo)
|
||||
if err != nil {
|
||||
glog.Infof("Failed to load userInfo in context:%v", err)
|
||||
}
|
||||
err = ctx.AddSA(userRequestInfo.AdmissionUserInfo.Username)
|
||||
if err != nil {
|
||||
glog.Infof("Failed to load service account in context:%v", err)
|
||||
}
|
||||
|
||||
policyContext := engine.PolicyContext{
|
||||
NewResource: resource,
|
||||
|
@ -92,7 +103,7 @@ func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest, resou
|
|||
}
|
||||
// gather patches
|
||||
patches = append(patches, engineResponse.GetPatches()...)
|
||||
glog.V(4).Infof("Mutation from policy %s has applied succesfully to %s %s/%s", policy.Name, request.Kind.Kind, resource.GetNamespace(), resource.GetName())
|
||||
glog.V(4).Infof("Mutation from policy %s has applied successfully to %s %s/%s", policy.Name, request.Kind.Kind, resource.GetNamespace(), resource.GetName())
|
||||
|
||||
policyContext.NewResource = engineResponse.PatchedResource
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@ func defaultvalidationFailureAction(policy *kyverno.ClusterPolicy) ([]byte, stri
|
|||
// scenario A: not exist, set default to "all", which generates on all pod controllers
|
||||
// - if name / selector exist in resource description -> skip
|
||||
// as these fields may not be applicable to pod controllers
|
||||
// scenario B: "none", user explicitely disable this feature -> skip
|
||||
// scenario B: "none", user explicitly disable this feature -> skip
|
||||
// scenario C: some certain controllers that user set -> generate on defined controllers
|
||||
// copy entrie match / exclude block, it's users' responsibility to
|
||||
// make sure all fields are applicable to pod cotrollers
|
||||
|
|
|
@ -43,12 +43,3 @@ func (ws *WebhookServer) handlePolicyValidation(request *v1beta1.AdmissionReques
|
|||
}
|
||||
return admissionResp
|
||||
}
|
||||
|
||||
func failResponseWithMsg(msg string) *v1beta1.AdmissionResponse {
|
||||
return &v1beta1.AdmissionResponse{
|
||||
Allowed: false,
|
||||
Result: &metav1.Status{
|
||||
Message: msg,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ func generateEvents(engineResponses []response.EngineResponse, onUpdate bool) []
|
|||
return events
|
||||
}
|
||||
if !onUpdate {
|
||||
// All policies were applied succesfully
|
||||
// All policies were applied successfully
|
||||
// CREATE
|
||||
for _, er := range engineResponses {
|
||||
successRules := er.GetSuccessRules()
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue