{"action":"created","comment":{"url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/pulls/comments/288683186","pull_request_review_id":243409228,"id":288683186,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDI4ODY4MzE4Ng==","diff_hunk":"@@ -0,0 +1,155 @@\n+# Copyright 2019 Microsoft Corporation\n+#\n+# Licensed under the Apache License, Version 2.0 (the \"License\");\n+# you may not use this file except in compliance with the License.\n+# You may obtain a copy of the License at\n+#\n+# http://www.apache.org/licenses/LICENSE-2.0\n+#\n+# Unless required by applicable law or agreed to in writing, software\n+# distributed under the License is distributed on an \"AS IS\" BASIS,\n+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+# See the License for the specific language governing permissions and\n+# limitations under the License.\n+\n+import json\n+\n+import jmespath\n+import requests\n+from six.moves.urllib import parse\n+\n+from c7n import utils\n+from .core import EventAction\n+\n+\n+class Webhook(EventAction):\n+    \"\"\"Calls a webhook with optional parameters and body\n+       populated from JMESPath queries.\n+\n+        .. code-block:: yaml\n+\n+          policies:\n+            - name: call-webhook\n+              resource: ec2\n+              description: |\n+                Call webhook with list of resource groups\n+              actions:\n+               - type: webhook\n+                 url: http://foo.com\n+                 parameters:\n+                    - resource_name: resource.name\n+                    - policy_name: policy.name\n+    \"\"\"\n+\n+    schema = utils.type_schema(\n+        'webhook',\n+        required=['url'],\n+        **{\n+            'url': {'type': 'string'},\n+            'body': {'type': 'string'},\n+            'batch': {'type': 'boolean'},\n+            'batch-size': {'type': 'number'},\n+            'method': {'type': 'string', 'enum': ['PUT', 'POST', 'GET', 'PATCH', 'DELETE']},","path":"c7n/actions/webhook.py","position":52,"original_position":52,"commit_id":"fc1dbc9e594753bb53ba2bed8536a6acedc8c7a9","original_commit_id":"fc1dbc9e594753bb53ba2bed8536a6acedc8c7a9","user":{"login":"aluong","id":1683309,"node_id":"MDQ6VXNlcjE2ODMzMDk=","avatar_url":"https://avatars3.githubusercontent.com/u/1683309?v=4","gravatar_id":"","url":"https://api.github.com/users/aluong","html_url":"https://github.com/aluong","followers_url":"https://api.github.com/users/aluong/followers","following_url":"https://api.github.com/users/aluong/following{/other_user}","gists_url":"https://api.github.com/users/aluong/gists{/gist_id}","starred_url":"https://api.github.com/users/aluong/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aluong/subscriptions","organizations_url":"https://api.github.com/users/aluong/orgs","repos_url":"https://api.github.com/users/aluong/repos","events_url":"https://api.github.com/users/aluong/events{/privacy}","received_events_url":"https://api.github.com/users/aluong/received_events","type":"User","site_admin":false},"body":"I would the policy will fail validation if you put a `method` that is not a part of this enum, but a test may be helpful.","created_at":"2019-05-29T17:28:34Z","updated_at":"2019-05-29T17:28:35Z","html_url":"https://github.com/cloud-custodian/cloud-custodian/pull/4074#discussion_r288683186","pull_request_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/pulls/4074","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/cloud-custodian/cloud-custodian/pulls/comments/288683186"},"html":{"href":"https://github.com/cloud-custodian/cloud-custodian/pull/4074#discussion_r288683186"},"pull_request":{"href":"https://api.github.com/repos/cloud-custodian/cloud-custodian/pulls/4074"}}},"pull_request":{"url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/pulls/4074","id":282951476,"node_id":"MDExOlB1bGxSZXF1ZXN0MjgyOTUxNDc2","html_url":"https://github.com/cloud-custodian/cloud-custodian/pull/4074","diff_url":"https://github.com/cloud-custodian/cloud-custodian/pull/4074.diff","patch_url":"https://github.com/cloud-custodian/cloud-custodian/pull/4074.patch","issue_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/issues/4074","number":4074,"state":"open","locked":false,"title":"C7N - Webhook Action","user":{"login":"stefangordon","id":4087345,"node_id":"MDQ6VXNlcjQwODczNDU=","avatar_url":"https://avatars3.githubusercontent.com/u/4087345?v=4","gravatar_id":"","url":"https://api.github.com/users/stefangordon","html_url":"https://github.com/stefangordon","followers_url":"https://api.github.com/users/stefangordon/followers","following_url":"https://api.github.com/users/stefangordon/following{/other_user}","gists_url":"https://api.github.com/users/stefangordon/gists{/gist_id}","starred_url":"https://api.github.com/users/stefangordon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stefangordon/subscriptions","organizations_url":"https://api.github.com/users/stefangordon/orgs","repos_url":"https://api.github.com/users/stefangordon/repos","events_url":"https://api.github.com/users/stefangordon/events{/privacy}","received_events_url":"https://api.github.com/users/stefangordon/received_events","type":"User","site_admin":false},"body":"Took a first pass at a webhook Action this morning.  My intent is to inherit from this for some Azure specific flavors next (LogicApp, FunctionApp).\r\n\r\nI've tested it a bunch against different types of webhooks (post, put, get) and with different error scenarios, I find it simple to use and extremely useful.\r\n\r\nNot sure I ever added an action or filter in C7N so I might have missed some patterns - let me know (trying to sort out the resource permissions test now...)\r\n\r\n```\r\n    actions:\r\n     - type: webhook\r\n       url: http://foo.com?hook-id=123  ─▶ Most simple usage\r\n\r\n\r\n    actions:\r\n     - type: webhook\r\n       url: http://foo.com?hook-id=123  ─▶ Call will default to GET as there is no body\r\n       parameters:                      ─▶ Additional query string parameters\r\n          resource_name: name           ─▶ Value is a JMESPath query into resource dictionary\r\n          region: location\r\n\r\n\r\n    actions:\r\n      - type: webhook\r\n        url: http://foo.com             ─▶ Call will default to POST as there is a body\r\n        batch: true                     ─▶ Single call for full resource array\r\n        body: '[].name'                 ─▶ JMESPath will reference array since batch=true\r\n        parameters:\r\n          count: '[] | length(@)'       ─▶ E.G. Include resource count in query string\r\n```","created_at":"2019-05-28T18:45:01Z","updated_at":"2019-05-29T17:28:35Z","closed_at":null,"merged_at":null,"merge_commit_sha":"33cf3cd4bf4bf917ad38490ae51e4945a1c20728","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":390680437,"node_id":"MDU6TGFiZWwzOTA2ODA0Mzc=","url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/labels/area/actions","name":"area/actions","color":"d93f0b","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/pulls/4074/commits","review_comments_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/pulls/4074/comments","review_comment_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/pulls/comments{/number}","comments_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/issues/4074/comments","statuses_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/statuses/fc1dbc9e594753bb53ba2bed8536a6acedc8c7a9","head":{"label":"stefangordon:webhook","ref":"webhook","sha":"fc1dbc9e594753bb53ba2bed8536a6acedc8c7a9","user":{"login":"stefangordon","id":4087345,"node_id":"MDQ6VXNlcjQwODczNDU=","avatar_url":"https://avatars3.githubusercontent.com/u/4087345?v=4","gravatar_id":"","url":"https://api.github.com/users/stefangordon","html_url":"https://github.com/stefangordon","followers_url":"https://api.github.com/users/stefangordon/followers","following_url":"https://api.github.com/users/stefangordon/following{/other_user}","gists_url":"https://api.github.com/users/stefangordon/gists{/gist_id}","starred_url":"https://api.github.com/users/stefangordon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stefangordon/subscriptions","organizations_url":"https://api.github.com/users/stefangordon/orgs","repos_url":"https://api.github.com/users/stefangordon/repos","events_url":"https://api.github.com/users/stefangordon/events{/privacy}","received_events_url":"https://api.github.com/users/stefangordon/received_events","type":"User","site_admin":false},"repo":{"id":125872127,"node_id":"MDEwOlJlcG9zaXRvcnkxMjU4NzIxMjc=","name":"cloud-custodian","full_name":"stefangordon/cloud-custodian","private":false,"owner":{"login":"stefangordon","id":4087345,"node_id":"MDQ6VXNlcjQwODczNDU=","avatar_url":"https://avatars3.githubusercontent.com/u/4087345?v=4","gravatar_id":"","url":"https://api.github.com/users/stefangordon","html_url":"https://github.com/stefangordon","followers_url":"https://api.github.com/users/stefangordon/followers","following_url":"https://api.github.com/users/stefangordon/following{/other_user}","gists_url":"https://api.github.com/users/stefangordon/gists{/gist_id}","starred_url":"https://api.github.com/users/stefangordon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stefangordon/subscriptions","organizations_url":"https://api.github.com/users/stefangordon/orgs","repos_url":"https://api.github.com/users/stefangordon/repos","events_url":"https://api.github.com/users/stefangordon/events{/privacy}","received_events_url":"https://api.github.com/users/stefangordon/received_events","type":"User","site_admin":false},"html_url":"https://github.com/stefangordon/cloud-custodian","description":"Rules engine for AWS management, DSL in yaml for query, filter, and actions on resources","fork":true,"url":"https://api.github.com/repos/stefangordon/cloud-custodian","forks_url":"https://api.github.com/repos/stefangordon/cloud-custodian/forks","keys_url":"https://api.github.com/repos/stefangordon/cloud-custodian/keys{/key_id}","collaborators_url":"https://api.github.com/repos/stefangordon/cloud-custodian/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/stefangordon/cloud-custodian/teams","hooks_url":"https://api.github.com/repos/stefangordon/cloud-custodian/hooks","issue_events_url":"https://api.github.com/repos/stefangordon/cloud-custodian/issues/events{/number}","events_url":"https://api.github.com/repos/stefangordon/cloud-custodian/events","assignees_url":"https://api.github.com/repos/stefangordon/cloud-custodian/assignees{/user}","branches_url":"https://api.github.com/repos/stefangordon/cloud-custodian/branches{/branch}","tags_url":"https://api.github.com/repos/stefangordon/cloud-custodian/tags","blobs_url":"https://api.github.com/repos/stefangordon/cloud-custodian/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/stefangordon/cloud-custodian/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/stefangordon/cloud-custodian/git/refs{/sha}","trees_url":"https://api.github.com/repos/stefangordon/cloud-custodian/git/trees{/sha}","statuses_url":"https://api.github.com/repos/stefangordon/cloud-custodian/statuses/{sha}","languages_url":"https://api.github.com/repos/stefangordon/cloud-custodian/languages","stargazers_url":"https://api.github.com/repos/stefangordon/cloud-custodian/stargazers","contributors_url":"https://api.github.com/repos/stefangordon/cloud-custodian/contributors","subscribers_url":"https://api.github.com/repos/stefangordon/cloud-custodian/subscribers","subscription_url":"https://api.github.com/repos/stefangordon/cloud-custodian/subscription","commits_url":"https://api.github.com/repos/stefangordon/cloud-custodian/commits{/sha}","git_commits_url":"https://api.github.com/repos/stefangordon/cloud-custodian/git/commits{/sha}","comments_url":"https://api.github.com/repos/stefangordon/cloud-custodian/comments{/number}","issue_comment_url":"https://api.github.com/repos/stefangordon/cloud-custodian/issues/comments{/number}","contents_url":"https://api.github.com/repos/stefangordon/cloud-custodian/contents/{+path}","compare_url":"https://api.github.com/repos/stefangordon/cloud-custodian/compare/{base}...{head}","merges_url":"https://api.github.com/repos/stefangordon/cloud-custodian/merges","archive_url":"https://api.github.com/repos/stefangordon/cloud-custodian/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/stefangordon/cloud-custodian/downloads","issues_url":"https://api.github.com/repos/stefangordon/cloud-custodian/issues{/number}","pulls_url":"https://api.github.com/repos/stefangordon/cloud-custodian/pulls{/number}","milestones_url":"https://api.github.com/repos/stefangordon/cloud-custodian/milestones{/number}","notifications_url":"https://api.github.com/repos/stefangordon/cloud-custodian/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/stefangordon/cloud-custodian/labels{/name}","releases_url":"https://api.github.com/repos/stefangordon/cloud-custodian/releases{/id}","deployments_url":"https://api.github.com/repos/stefangordon/cloud-custodian/deployments","created_at":"2018-03-19T14:37:36Z","updated_at":"2018-12-03T22:50:31Z","pushed_at":"2019-05-29T16:42:49Z","git_url":"git://github.com/stefangordon/cloud-custodian.git","ssh_url":"git@github.com:stefangordon/cloud-custodian.git","clone_url":"https://github.com/stefangordon/cloud-custodian.git","svn_url":"https://github.com/stefangordon/cloud-custodian","homepage":"https://developer.capitalone.com/opensource-projects/cloud-custodian","size":110036,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":2,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":2,"watchers":0,"default_branch":"master"}},"base":{"label":"cloud-custodian:master","ref":"master","sha":"873d19c775789c7a88cef4ed7e91183e6e727692","user":{"login":"cloud-custodian","id":38811484,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM4ODExNDg0","avatar_url":"https://avatars2.githubusercontent.com/u/38811484?v=4","gravatar_id":"","url":"https://api.github.com/users/cloud-custodian","html_url":"https://github.com/cloud-custodian","followers_url":"https://api.github.com/users/cloud-custodian/followers","following_url":"https://api.github.com/users/cloud-custodian/following{/other_user}","gists_url":"https://api.github.com/users/cloud-custodian/gists{/gist_id}","starred_url":"https://api.github.com/users/cloud-custodian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cloud-custodian/subscriptions","organizations_url":"https://api.github.com/users/cloud-custodian/orgs","repos_url":"https://api.github.com/users/cloud-custodian/repos","events_url":"https://api.github.com/users/cloud-custodian/events{/privacy}","received_events_url":"https://api.github.com/users/cloud-custodian/received_events","type":"Organization","site_admin":false},"repo":{"id":52837350,"node_id":"MDEwOlJlcG9zaXRvcnk1MjgzNzM1MA==","name":"cloud-custodian","full_name":"cloud-custodian/cloud-custodian","private":false,"owner":{"login":"cloud-custodian","id":38811484,"node_id":"MDEyOk9yZ2FuaXphdGlvbjM4ODExNDg0","avatar_url":"https://avatars2.githubusercontent.com/u/38811484?v=4","gravatar_id":"","url":"https://api.github.com/users/cloud-custodian","html_url":"https://github.com/cloud-custodian","followers_url":"https://api.github.com/users/cloud-custodian/followers","following_url":"https://api.github.com/users/cloud-custodian/following{/other_user}","gists_url":"https://api.github.com/users/cloud-custodian/gists{/gist_id}","starred_url":"https://api.github.com/users/cloud-custodian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cloud-custodian/subscriptions","organizations_url":"https://api.github.com/users/cloud-custodian/orgs","repos_url":"https://api.github.com/users/cloud-custodian/repos","events_url":"https://api.github.com/users/cloud-custodian/events{/privacy}","received_events_url":"https://api.github.com/users/cloud-custodian/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/cloud-custodian/cloud-custodian","description":"Rules engine for cloud security, cost optimization, and governance, DSL in yaml for policies to query, filter, and take actions on resources","fork":false,"url":"https://api.github.com/repos/cloud-custodian/cloud-custodian","forks_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/forks","keys_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/teams","hooks_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/hooks","issue_events_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/issues/events{/number}","events_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/events","assignees_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/assignees{/user}","branches_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/branches{/branch}","tags_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/tags","blobs_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/git/refs{/sha}","trees_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/statuses/{sha}","languages_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/languages","stargazers_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/stargazers","contributors_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/contributors","subscribers_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/subscribers","subscription_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/subscription","commits_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/commits{/sha}","git_commits_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/git/commits{/sha}","comments_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/comments{/number}","issue_comment_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/issues/comments{/number}","contents_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/contents/{+path}","compare_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/merges","archive_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/downloads","issues_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/issues{/number}","pulls_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/pulls{/number}","milestones_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/milestones{/number}","notifications_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/labels{/name}","releases_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/releases{/id}","deployments_url":"https://api.github.com/repos/cloud-custodian/cloud-custodian/deployments","created_at":"2016-03-01T01:11:20Z","updated_at":"2019-05-29T17:06:22Z","pushed_at":"2019-05-29T17:06:12Z","git_url":"git://github.com/cloud-custodian/cloud-custodian.git","ssh_url":"git@github.com:cloud-custodian/cloud-custodian.git","clone_url":"https://github.com/cloud-custodian/cloud-custodian.git","svn_url":"https://github.com/cloud-custodian/cloud-custodian","homepage":"https://cloudcustodian.io","size":118800,"stargazers_count":2171,"watchers_count":2171,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":622,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":519,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":622,"open_issues":519,"watchers":2171,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/cloud-custodian/cloud-custodian/pulls/4074"},"html":{"href":"https://github.com/cloud-custodian/cloud-custodian/pull/4074"},"issue":{"href":"https://api.github.com/repos/cloud-custodian/cloud-custodian/issues/4074"},"comments":{"href":"https://api.github.com/repos/cloud-custodian/cloud-custodian/issues/4074/comments"},"review_comments":{"href":"https://api.github.com/repos/cloud-custodian/cloud-custodian/pulls/4074/comments"},"review_comment":{"href":"https://api.github.com/repos/cloud-custodian/cloud-custodian/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/cloud-custodian/cloud-custodian/pulls/4074/commits"},"statuses":{"href":"https://api.github.com/repos/cloud-custodian/cloud-custodian/statuses/fc1dbc9e594753bb53ba2bed8536a6acedc8c7a9"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"aluong"}}