From 54aaf10df8182d50aed4761e78682f23ced363dd Mon Sep 17 00:00:00 2001 From: Alan Date: Mon, 20 Mar 2023 09:53:29 +0100 Subject: [PATCH] feat(pr-workflow): refactor webhook to enable multiple type of Events and Providers --- go.mod | 26 ++-- go.sum | 44 ++++--- internal/burrito/config/config.go | 7 +- internal/webhook/event/common.go | 62 +++++++++ internal/webhook/event/pull.go | 64 +++++++++ internal/webhook/event/push.go | 57 ++++++++ internal/webhook/github/provider.go | 108 +++++++++++++++ internal/webhook/gitlab/provider.go | 96 ++++++++++++++ internal/webhook/webhook.go | 195 +++++++--------------------- 9 files changed, 480 insertions(+), 179 deletions(-) create mode 100644 internal/webhook/event/common.go create mode 100644 internal/webhook/event/pull.go create mode 100644 internal/webhook/event/push.go create mode 100644 internal/webhook/github/provider.go create mode 100644 internal/webhook/gitlab/provider.go diff --git a/go.mod b/go.mod index 07d49841a..650a8c824 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/padok-team/burrito go 1.19 require ( - github.com/go-playground/webhooks/v6 v6.0.1 + github.com/hashicorp/terraform-json v0.14.0 github.com/onsi/ginkgo/v2 v2.6.0 github.com/onsi/gomega v1.24.1 github.com/sirupsen/logrus v1.8.1 @@ -14,14 +14,15 @@ require ( require ( github.com/Microsoft/go-winio v0.5.2 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect github.com/acomagu/bufpipe v1.0.3 // indirect github.com/cloudflare/circl v1.1.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/go-git/gcfg v1.5.0 // indirect github.com/go-git/go-billy/v5 v5.3.1 // indirect + github.com/google/go-querystring v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/terraform-json v0.14.0 // indirect + github.com/hashicorp/go-retryablehttp v0.7.2 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/pjbgf/sha1cd v0.2.3 // indirect @@ -46,12 +47,14 @@ require ( github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.20.0 // indirect github.com/go-openapi/swag v0.19.14 // indirect + github.com/go-playground/webhooks v5.17.0+incompatible github.com/go-redis/redis/v8 v8.11.5 github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/go-cmp v0.5.9 // indirect + github.com/google/go-github/v50 v50.2.0 github.com/google/gofuzz v1.1.0 // indirect github.com/google/uuid v1.3.0 // indirect github.com/hashicorp/go-version v1.6.0 @@ -83,19 +86,20 @@ require ( github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.14.0 github.com/subosito/gotenv v1.4.1 // indirect + github.com/xanzy/go-gitlab v0.81.0 go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.3.0 // indirect - golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10 // indirect - golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect - golang.org/x/sys v0.3.0 // indirect - golang.org/x/term v0.3.0 // indirect - golang.org/x/text v0.5.0 // indirect + golang.org/x/crypto v0.7.0 // indirect + golang.org/x/net v0.8.0 // indirect + golang.org/x/oauth2 v0.6.0 + golang.org/x/sys v0.6.0 // indirect + golang.org/x/term v0.6.0 // indirect + golang.org/x/text v0.8.0 // indirect golang.org/x/time v0.3.0 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.28.1 // indirect + google.golang.org/protobuf v1.29.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 0f60e61c9..dceaa52fe 100644 --- a/go.sum +++ b/go.sum @@ -43,8 +43,9 @@ github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugX github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= -github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 h1:ra2OtmuW0AE5csawV4YXMNGNQQXvLRps3z2Z59OPO+I= github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= +github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA= +github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -145,12 +146,11 @@ github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXym github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-playground/webhooks/v6 v6.0.1 h1:ssqgU7vZ+xK+/Uwx4zkf5tfmzOHnLBpzSp5bJ4cX3rg= -github.com/go-playground/webhooks/v6 v6.0.1/go.mod h1:GCocmfMtpJdkEOM1uG9p2nXzg1kY5X/LtvQgtPHUaaA= +github.com/go-playground/webhooks v5.17.0+incompatible h1:Ea3zLJXlnlIFweIujDxdneq512xO4k9cYwAuZ3VuPJo= +github.com/go-playground/webhooks v5.17.0+incompatible/go.mod h1:rMsxoY7bQzIPF9Ni55rTCyLG2af55f9IWgJ1ao3JiZA= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gogits/go-gogs-client v0.0.0-20200905025246-8bb8a50cb355/go.mod h1:cY2AIrMgHm6oOHmR7jY+9TtjzSjQ3iG7tURJG3Y6XH0= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -185,6 +185,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 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/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= @@ -202,6 +204,10 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-github/v50 v50.2.0 h1:j2FyongEHlO9nxXLc+LP3wuBSVU9mVxfpdYUexMpIfk= +github.com/google/go-github/v50 v50.2.0/go.mod h1:VBY8FB6yPIjrtKhozXv4FQupxKLS6H4m6xFZlT43q8Q= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -230,7 +236,10 @@ github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuD github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0= +github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= @@ -406,6 +415,8 @@ github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNG github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= +github.com/xanzy/go-gitlab v0.81.0 h1:ofbhZ5ZY9AjHATWQie4qd2JfncdUmvcSA/zfQB767Dk= +github.com/xanzy/go-gitlab v0.81.0/go.mod h1:VMbY3JIWdZ/ckvHbQqkyd3iYk2aViKrNIQ23IbFMQDo= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= @@ -451,8 +462,9 @@ golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -529,8 +541,8 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10 h1:Frnccbp+ok2GkUS2tC84yAq/U9Vg+0sIO7aRL3T4Xnc= -golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -542,8 +554,8 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 h1:nt+Q6cXKz4MosCSpnbMtqiQ8Oz0pxTef2B4Vca2lvfk= -golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -613,14 +625,14 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -631,8 +643,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -789,6 +801,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.29.0 h1:44S3JjaKmLEE4YIkjzexaP+NzZsudE3Zin5Njn/pYX0= +google.golang.org/protobuf v1.29.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/burrito/config/config.go b/internal/burrito/config/config.go index d715b1bca..77611763c 100644 --- a/internal/burrito/config/config.go +++ b/internal/burrito/config/config.go @@ -25,11 +25,14 @@ type WebhookConfig struct { } type WebhookGithubConfig struct { - Secret string `yaml:"secret"` + Secret string `yaml:"secret"` + APIToken string `yaml:"token"` } type WebhookGitlabConfig struct { - Secret string `yaml:"secret"` + URL string `yaml:"url"` + Secret string `yaml:"secret"` + APIToken string `yaml:"token"` } type ControllerConfig struct { diff --git a/internal/webhook/event/common.go b/internal/webhook/event/common.go new file mode 100644 index 000000000..f807e03ab --- /dev/null +++ b/internal/webhook/event/common.go @@ -0,0 +1,62 @@ +package event + +import ( + "path/filepath" + "strings" + + configv1alpha1 "github.com/padok-team/burrito/api/v1alpha1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +const PullRequestOpened = "opened" +const PullRequestClosed = "closed" + +type ChangeInfo struct { + ShaBefore string + ShaAfter string +} + +type Event interface { + Handle(client.Client, []configv1alpha1.TerraformRepository, []configv1alpha1.TerraformLayer) error +} + +func GetNormalizedURL(urls []string) string { + return "" +} + +func ParseRevision(ref string) string { + refParts := strings.SplitN(ref, "/", 3) + return refParts[len(refParts)-1] +} + +func isLayerLinkedToAnyRepositories(repositories []configv1alpha1.TerraformRepository, layer configv1alpha1.TerraformLayer) bool { + for _, r := range repositories { + if r.Name == layer.Spec.Repository.Name && r.Namespace == layer.Spec.Repository.Namespace { + return true + } + } + return false +} + +func layerFilesHaveChanged(layer configv1alpha1.TerraformLayer, changedFiles []string) bool { + if len(changedFiles) == 0 { + return true + } + + // At last one changed file must be under refresh path + for _, f := range changedFiles { + f = ensureAbsPath(f) + if strings.Contains(f, layer.Spec.Path) { + return true + } + } + + return false +} + +func ensureAbsPath(input string) string { + if !filepath.IsAbs(input) { + return string(filepath.Separator) + input + } + return input +} diff --git a/internal/webhook/event/pull.go b/internal/webhook/event/pull.go new file mode 100644 index 000000000..b5c3a4e60 --- /dev/null +++ b/internal/webhook/event/pull.go @@ -0,0 +1,64 @@ +package event + +import ( + "fmt" + + configv1alpha1 "github.com/padok-team/burrito/api/v1alpha1" + log "github.com/sirupsen/logrus" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type PullRequestEvent struct { + URL string + ProviderLabel string + Revision string + Action string + Base string + ID string + Changes []string +} + +func (e *PullRequestEvent) getAffectedLayers(allLayers []configv1alpha1.TerraformLayer, allRepos []configv1alpha1.TerraformRepository) []configv1alpha1.TerraformLayer { + affectedRepositories := []configv1alpha1.TerraformRepository{} + for _, repo := range allRepos { + log.Infof("evaluating terraform repository %s for url %s", repo.Name, repo.Spec.Repository.Url) + if e.URL == GetNormalizedURL([]string{repo.Spec.Repository.Url}) { + affectedRepositories = append(affectedRepositories, repo) + continue + } + } + layers := []configv1alpha1.TerraformLayer{} + for _, layer := range allLayers { + eventIsRelevant := layerFilesHaveChanged(layer, e.Changes) && isLayerLinkedToAnyRepositories(affectedRepositories, layer) && layer.Spec.Branch == e.Base + if eventIsRelevant { + layers = append(layers, layer) + } + } + return layers +} +func (e *PullRequestEvent) Handle(c client.Client, allRepositories []configv1alpha1.TerraformRepository, allLayers []configv1alpha1.TerraformLayer) error { + layers := e.getAffectedLayers(allLayers, allRepositories) + for _, layer := range layers { + switch e.Action { + case PullRequestOpened: + + case PullRequestClosed: + default: + log.Infof("pull request event %s is not supported", e.Action) + return nil + } + } + return nil +} + +func (e *PullRequestEvent) getNewPullRequestLayer(layer configv1alpha1.TerraformLayer) *configv1alpha1.TerraformLayer { + newLayer := layer.DeepCopy() + newLayer.Spec.Branch = e.Revision + newLayer.GenerateName = fmt.Sprintf("%s-pr-", layer.Name) + newLayer.Name = "" + newLayer.Labels["pull-request-event"] = "true" + newLayer.Labels[e.ProviderLabel] = e.ID + newLayer.Spec.RemediationStrategy = "dry" + newLayer.Spec.PlanOnPullRequest = false + return newLayer +} diff --git a/internal/webhook/event/push.go b/internal/webhook/event/push.go new file mode 100644 index 000000000..42b38526e --- /dev/null +++ b/internal/webhook/event/push.go @@ -0,0 +1,57 @@ +package event + +import ( + "context" + + configv1alpha1 "github.com/padok-team/burrito/api/v1alpha1" + "github.com/padok-team/burrito/internal/annotations" + log "github.com/sirupsen/logrus" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type PushEvent struct { + URL string + Revision string + ChangeInfo + Changes []string +} + +func (e *PushEvent) Handle(c client.Client, allRepositories []configv1alpha1.TerraformRepository, allLayers []configv1alpha1.TerraformLayer) error { + layers := e.getAffectedLayers(allLayers, allRepositories) + for _, layer := range layers { + ann := map[string]string{} + log.Printf("evaluating terraform layer %s for revision %s", layer.Name, e.Revision) + if layer.Spec.Branch != e.Revision { + log.Infof("branch %s for terraform layer %s not matching revision %s", layer.Spec.Branch, layer.Name, e.Revision) + continue + } + ann[annotations.LastBranchCommit] = e.ChangeInfo.ShaAfter + if layerFilesHaveChanged(layer, e.Changes) { + ann[annotations.LastRelevantCommit] = e.ChangeInfo.ShaAfter + } + err := annotations.Add(context.TODO(), c, layer, ann) + if err != nil { + log.Errorf("could not add annotation to terraform layer %s", err) + return err + } + } + return nil +} + +func (e *PushEvent) getAffectedLayers(allLayers []configv1alpha1.TerraformLayer, allRepos []configv1alpha1.TerraformRepository) []configv1alpha1.TerraformLayer { + affectedRepositories := []configv1alpha1.TerraformRepository{} + for _, repo := range allRepos { + log.Infof("evaluating terraform repository %s for url %s", repo.Name, repo.Spec.Repository.Url) + if e.URL == GetNormalizedURL([]string{repo.Spec.Repository.Url}) { + affectedRepositories = append(affectedRepositories, repo) + continue + } + } + layers := []configv1alpha1.TerraformLayer{} + for _, layer := range allLayers { + if layerFilesHaveChanged(layer, e.Changes) && isLayerLinkedToAnyRepositories(affectedRepositories, layer) { + layers = append(layers, layer) + } + } + return layers +} diff --git a/internal/webhook/github/provider.go b/internal/webhook/github/provider.go new file mode 100644 index 000000000..a01cb1ca3 --- /dev/null +++ b/internal/webhook/github/provider.go @@ -0,0 +1,108 @@ +package github + +import ( + "context" + "errors" + "net/http" + + "github.com/go-playground/webhooks/github" + api "github.com/google/go-github/v50/github" + "github.com/padok-team/burrito/internal/burrito/config" + "github.com/padok-team/burrito/internal/webhook/event" + "golang.org/x/oauth2" + + log "github.com/sirupsen/logrus" +) + +type Github struct { + github *github.Webhook + client *api.Client +} + +func (g *Github) Init(c *config.Config) error { + githubWebhook, err := github.New(github.Options.Secret(c.Server.Webhook.Github.Secret)) + if err != nil { + return err + } + g.github = githubWebhook + ctx := context.Background() + ts := oauth2.StaticTokenSource( + &oauth2.Token{AccessToken: c.Server.Webhook.Github.APIToken}, + ) + tc := oauth2.NewClient(ctx, ts) + g.client = api.NewClient(tc) + return nil +} + +func (g *Github) IsFromProvider(r *http.Request) bool { + return r.Header.Get("X-GitHub-Event") != "" +} + +func (g *Github) GetEvent(r *http.Request) (event.Event, error) { + p, err := g.github.Parse(r, github.PushEvent, github.PingEvent) + if errors.Is(err, github.ErrHMACVerificationFailed) { + log.Errorf("GitHub webhook HMAC verification failed: %s", err) + return nil, err + } + var e event.Event + switch payload := p.(type) { + case github.PushPayload: + log.Infof("parsing Github push event payload") + changedFiles := []string{} + for _, commit := range payload.Commits { + changedFiles = append(changedFiles, commit.Added...) + changedFiles = append(changedFiles, commit.Modified...) + changedFiles = append(changedFiles, commit.Removed...) + } + e = &event.PushEvent{ + URL: event.GetNormalizedURL([]string{payload.Repository.HTMLURL, payload.Repository.SSHURL}), + Revision: event.ParseRevision(payload.Ref), + ChangeInfo: event.ChangeInfo{ + ShaBefore: payload.Before, + ShaAfter: payload.After, + }, + Changes: changedFiles, + } + case github.PullRequestPayload: + log.Infof("parsing Github pull request event payload") + if err != nil { + log.Warnf("Could not retrieve pull request from Github API", err) + return nil, err + } + opts := &api.ListOptions{ + PerPage: 100, + } + // get all pages of results + var allFiles []*api.CommitFile + for { + repos, resp, err := g.client.PullRequests.ListFiles(context.Background(), + payload.Repository.Owner.Login, + payload.Repository.Name, + int(payload.PullRequest.ID), + opts) + if err != nil { + log.Warnf("could not list files associated with pull request") + return nil, err + } + allFiles = append(allFiles, repos...) + if resp.NextPage == 0 { + break + } + opts.Page = resp.NextPage + } + changedFiles := []string{} + for _, file := range allFiles { + changedFiles = append(changedFiles, file.GetFilename()) + } + e = &event.PullRequestEvent{ + URL: event.GetNormalizedURL([]string{payload.Repository.HTMLURL, payload.Repository.SSHURL}), + Revision: event.ParseRevision(payload.PullRequest.Base.Ref), + Action: payload.Action, + Changes: changedFiles, + Base: payload.PullRequest.Base.Ref, + } + default: + return nil, errors.New("unsupported Event") + } + return e, nil +} diff --git a/internal/webhook/gitlab/provider.go b/internal/webhook/gitlab/provider.go new file mode 100644 index 000000000..e018b7cb3 --- /dev/null +++ b/internal/webhook/gitlab/provider.go @@ -0,0 +1,96 @@ +package gitlab + +import ( + "errors" + "net/http" + + "github.com/go-playground/webhooks/gitlab" + "github.com/padok-team/burrito/internal/burrito/config" + "github.com/padok-team/burrito/internal/webhook/event" + log "github.com/sirupsen/logrus" + api "github.com/xanzy/go-gitlab" +) + +type Gitlab struct { + gitlab *gitlab.Webhook + client *api.Client +} + +func (g *Gitlab) Init(c *config.Config) error { + gitlabWebhook, err := gitlab.New(gitlab.Options.Secret(c.Server.Webhook.Gitlab.Secret)) + if err != nil { + return err + } + g.gitlab = gitlabWebhook + client, err := api.NewClient(c.Server.Webhook.Gitlab.APIToken, api.WithBaseURL(c.Server.Webhook.Gitlab.URL)) + log.Warnf("error initializing new Gitlab Client: %s", err) + g.client = client + return nil +} + +func (g *Gitlab) IsFromProvider(r *http.Request) bool { + return r.Header.Get("X-Gitlab-Event") != "" +} + +func (g *Gitlab) GetEvent(r *http.Request) (event.Event, error) { + var e event.Event + p, err := g.gitlab.Parse(r, gitlab.PushEvents, gitlab.TagEvents) + if errors.Is(err, gitlab.ErrGitLabTokenVerificationFailed) { + log.Errorf("GitLab webhook token verification failed: %s", err) + } + switch payload := p.(type) { + case gitlab.PushEventPayload: + log.Infof("parsing Gitlab push event payload") + changedFiles := []string{} + for _, commit := range payload.Commits { + changedFiles = append(changedFiles, commit.Added...) + changedFiles = append(changedFiles, commit.Modified...) + changedFiles = append(changedFiles, commit.Removed...) + } + e = &event.PushEvent{ + URL: event.GetNormalizedURL([]string{payload.Project.WebURL}), + Revision: event.ParseRevision(payload.Ref), + ChangeInfo: event.ChangeInfo{ + ShaBefore: payload.Before, + ShaAfter: payload.After, + }, + Changes: changedFiles, + } + case gitlab.MergeRequestEventPayload: + log.Infof("parsing Gitlab merge request event payload") + if g.client == nil { + return nil, errors.New("uninitialized Gitlab client, verify your config") + } + + mr, _, err := g.client.MergeRequests.GetMergeRequestChanges(payload.Project.PathWithNamespace, int(payload.ObjectAttributes.ID), nil) + if err != nil { + log.Warnf("could not list files associated with merge request") + return nil, err + } + changedFiles := []string{} + for _, change := range mr.Changes { + changedFiles = append(changedFiles, change.NewPath) + } + e = &event.PullRequestEvent{ + URL: event.GetNormalizedURL([]string{payload.Project.WebURL}), + Revision: event.ParseRevision(payload.ObjectAttributes.Ref), + Action: getNormalizedAction(payload.ObjectAttributes.Action), + Changes: changedFiles, + Base: payload.ObjectAttributes.TargetBranch, + } + default: + return nil, errors.New("unsupported event") + } + return e, nil +} + +func getNormalizedAction(action string) string { + switch action { + case "open": + return event.PullRequestOpened + case "close": + return event.PullRequestClosed + default: + return action + } +} diff --git a/internal/webhook/webhook.go b/internal/webhook/webhook.go index 22d5d25b6..68f88a94d 100644 --- a/internal/webhook/webhook.go +++ b/internal/webhook/webhook.go @@ -2,27 +2,24 @@ package webhook import ( "context" - "errors" "fmt" "html" "net/http" - "path/filepath" - "strings" log "github.com/sirupsen/logrus" - "github.com/go-playground/webhooks/v6/github" - "github.com/go-playground/webhooks/v6/gitlab" - "github.com/padok-team/burrito/internal/annotations" "github.com/padok-team/burrito/internal/burrito/config" - "k8s.io/apimachinery/pkg/runtime" + "github.com/padok-team/burrito/internal/webhook/event" + "github.com/padok-team/burrito/internal/webhook/github" + "github.com/padok-team/burrito/internal/webhook/gitlab" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" + "k8s.io/apimachinery/pkg/runtime" configv1alpha1 "github.com/padok-team/burrito/api/v1alpha1" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" ) type Handler interface { @@ -31,9 +28,8 @@ type Handler interface { type Webhook struct { client.Client - config *config.Config - github *github.Webhook - gitlab *gitlab.Webhook + config *config.Config + providers []Provider } func New(c *config.Config) *Webhook { @@ -42,6 +38,12 @@ func New(c *config.Config) *Webhook { } } +type Provider interface { + Init(*config.Config) error + IsFromProvider(*http.Request) bool + GetEvent(*http.Request) (event.Event, error) +} + func (w *Webhook) Init() error { scheme := runtime.NewScheme() utilruntime.Must(clientgoscheme.AddToScheme(scheme)) @@ -53,171 +55,62 @@ func (w *Webhook) Init() error { return err } w.Client = cl - githubWebhook, err := github.New(github.Options.Secret(w.config.Server.Webhook.Github.Secret)) - if err != nil { - return err - } - w.github = githubWebhook - gitlabWebhook, err := gitlab.New(gitlab.Options.Secret(w.config.Server.Webhook.Gitlab.Secret)) - if err != nil { - return err + w.providers = []Provider{&github.Github{}, &gitlab.Gitlab{}} + for _, p := range w.providers { + err = p.Init(w.config) + if err != nil { + return err + } } - w.gitlab = gitlabWebhook return nil } func (w *Webhook) GetHttpHandler() func(http.ResponseWriter, *http.Request) { log.Infof("webhook event received...") return func(writer http.ResponseWriter, r *http.Request) { - var payload interface{} var err error - - switch { - case r.Header.Get("X-GitHub-Event") != "": - log.Infof("webhook has detected a GitHub event") - payload, err = w.github.Parse(r, github.PushEvent, github.PingEvent) - if errors.Is(err, github.ErrHMACVerificationFailed) { - log.Errorf("GitHub webhook HMAC verification failed: %s", err) - } - case r.Header.Get("X-Gitlab-Event") != "": - log.Infof("webhook has detected a GitLab event") - payload, err = w.gitlab.Parse(r, gitlab.PushEvents, gitlab.TagEvents) - if errors.Is(err, gitlab.ErrGitLabTokenVerificationFailed) { - log.Errorf("GitLab webhook token verification failed: %s", err) + var event event.Event + for _, p := range w.providers { + if p.IsFromProvider(r) { + event, err = p.GetEvent(r) + break } - default: - log.Infof("ignoring unknown webhook event") - http.Error(writer, "Unknown webhook event", http.StatusBadRequest) - return } - if err != nil { log.Errorf("webhook processing failed: %s", err) status := http.StatusBadRequest if r.Method != "POST" { status = http.StatusMethodNotAllowed } - http.Error(writer, fmt.Sprintf("Webhook processing failed: %s", html.EscapeString(err.Error())), status) + http.Error(writer, fmt.Sprintf("webhook processing failed: %s", html.EscapeString(err.Error())), status) return } + if event == nil { + log.Infof("ignoring unknown webhook event") + http.Error(writer, "Unknown webhook event", http.StatusBadRequest) + } - w.Handle(payload) + err = w.Handle(event) + if err != nil { + log.Errorf("webhook processing worked but errored during event handling") + } } } -func (w *Webhook) Handle(payload interface{}) { - webUrls, sshUrls, revision, change, touchedHead, changedFiles := affectedRevisionInfo(payload) - allUrls := append(webUrls, sshUrls...) - - if len(allUrls) == 0 { - log.Infof("ignoring webhook event") - return - } - for _, url := range allUrls { - log.Infof("received event repo: %s, revision: %s, touchedHead: %v", url, revision, touchedHead) - } - +func (w *Webhook) Handle(e event.Event) error { repositories := &configv1alpha1.TerraformRepositoryList{} err := w.Client.List(context.TODO(), repositories) if err != nil { - log.Errorf("could not get terraform repositories: %s", err) - } - - for _, url := range allUrls { - for _, repo := range repositories.Items { - log.Infof("evaluating terraform repository %s for url %s", repo.Name, url) - if repo.Spec.Repository.Url != url { - log.Infof("evaluating terraform repository %s url %s not matching %s", repo.Name, repo.Spec.Repository.Url, url) - continue - } - layers := &configv1alpha1.TerraformLayerList{} - err := w.Client.List(context.TODO(), layers, &client.ListOptions{}) - if err != nil { - log.Errorf("could not get terraform layers: %s", err) - } - for _, layer := range layers.Items { - ann := map[string]string{} - log.Printf("evaluating terraform layer %s for revision %s", layer.Name, revision) - if layer.Spec.Branch != revision { - log.Infof("branch %s for terraform layer %s not matching revision %s", layer.Spec.Branch, layer.Name, revision) - continue - } - ann[annotations.LastBranchCommit] = change.shaAfter - if layerFilesHaveChanged(&layer, changedFiles) { - ann[annotations.LastRelevantCommit] = change.shaAfter - } - err = annotations.Add(context.TODO(), w.Client, layer, ann) - if err != nil { - log.Errorf("could not add annotation to terraform layer %s", err) - } - } - } - } - return -} - -type changeInfo struct { - shaBefore string - shaAfter string -} - -func parseRevision(ref string) string { - refParts := strings.SplitN(ref, "/", 3) - return refParts[len(refParts)-1] -} - -func affectedRevisionInfo(payloadIf interface{}) (webUrls []string, sshUrls []string, revision string, change changeInfo, touchedHead bool, changedFiles []string) { - switch payload := payloadIf.(type) { - case github.PushPayload: - log.Infof("parsing GitHub push event payload") - webUrls = append(webUrls, payload.Repository.HTMLURL) - sshUrls = append(sshUrls, payload.Repository.SSHURL) - revision = parseRevision(payload.Ref) - change.shaAfter = parseRevision(payload.After) - change.shaBefore = parseRevision(payload.Before) - touchedHead = bool(payload.Repository.DefaultBranch == revision) - for _, commit := range payload.Commits { - changedFiles = append(changedFiles, commit.Added...) - changedFiles = append(changedFiles, commit.Modified...) - changedFiles = append(changedFiles, commit.Removed...) - } - case gitlab.PushEventPayload: - log.Infof("parsing GitLab push event payload") - webUrls = append(webUrls, payload.Project.WebURL) - revision = parseRevision(payload.Ref) - change.shaAfter = parseRevision(payload.After) - change.shaBefore = parseRevision(payload.Before) - touchedHead = bool(payload.Project.DefaultBranch == revision) - for _, commit := range payload.Commits { - changedFiles = append(changedFiles, commit.Added...) - changedFiles = append(changedFiles, commit.Modified...) - changedFiles = append(changedFiles, commit.Removed...) - } - default: - log.Infof("event not handled") - } - return webUrls, sshUrls, revision, change, touchedHead, changedFiles -} - -func layerFilesHaveChanged(layer *configv1alpha1.TerraformLayer, changedFiles []string) bool { - if len(changedFiles) == 0 { - return true + return err } - - // At last one changed file must be under refresh path - for _, f := range changedFiles { - f = ensureAbsPath(f) - if strings.Contains(f, layer.Spec.Path) { - return true - } + layers := &configv1alpha1.TerraformLayerList{} + err = w.Client.List(context.TODO(), layers, &client.ListOptions{}) + if err != nil { + return err } - - return false -} - -func ensureAbsPath(input string) string { - if !filepath.IsAbs(input) { - return string(filepath.Separator) + input + err = e.Handle(w.Client, repositories.Items, layers.Items) + if err != nil { + return err } - return input + return nil }