{"action":"created","comment":{"url":"https://api.github.com/repos/kubeless/kubeless/pulls/comments/175334565","pull_request_review_id":104844451,"id":175334565,"diff_hunk":"@@ -24,7 +24,7 @@ local controller_roles = [\n   {\n     apiGroups: [\"kubeless.io\"],\n     resources: [\"functions\", \"kafkatriggers\", \"httptriggers\", \"cronjobtriggers\"],\n-    verbs: [\"get\", \"list\", \"watch\", \"update\"],\n+    verbs: [\"create\", \"get\", \"list\", \"watch\", \"update\", \"patch\"],","path":"kubeless-rbac.jsonnet","position":null,"original_position":5,"commit_id":"358f8cbd65d7ca1d5e5b0b7024f6e8a67cfb7315","original_commit_id":"358f8cbd65d7ca1d5e5b0b7024f6e8a67cfb7315","user":{"login":"anguslees","id":224224,"avatar_url":"https://avatars0.githubusercontent.com/u/224224?v=4","gravatar_id":"","url":"https://api.github.com/users/anguslees","html_url":"https://github.com/anguslees","followers_url":"https://api.github.com/users/anguslees/followers","following_url":"https://api.github.com/users/anguslees/following{/other_user}","gists_url":"https://api.github.com/users/anguslees/gists{/gist_id}","starred_url":"https://api.github.com/users/anguslees/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/anguslees/subscriptions","organizations_url":"https://api.github.com/users/anguslees/orgs","repos_url":"https://api.github.com/users/anguslees/repos","events_url":"https://api.github.com/users/anguslees/events{/privacy}","received_events_url":"https://api.github.com/users/anguslees/received_events","type":"User","site_admin":false},"body":"the resources in this rbac rule (functions and triggers)","created_at":"2018-03-19T05:32:05Z","updated_at":"2018-03-19T05:32:05Z","html_url":"https://github.com/kubeless/kubeless/pull/620#discussion_r175334565","pull_request_url":"https://api.github.com/repos/kubeless/kubeless/pulls/620","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/kubeless/kubeless/pulls/comments/175334565"},"html":{"href":"https://github.com/kubeless/kubeless/pull/620#discussion_r175334565"},"pull_request":{"href":"https://api.github.com/repos/kubeless/kubeless/pulls/620"}},"in_reply_to_id":175320743},"pull_request":{"url":"https://api.github.com/repos/kubeless/kubeless/pulls/620","id":173395324,"html_url":"https://github.com/kubeless/kubeless/pull/620","diff_url":"https://github.com/kubeless/kubeless/pull/620.diff","patch_url":"https://github.com/kubeless/kubeless/pull/620.patch","issue_url":"https://api.github.com/repos/kubeless/kubeless/issues/620","number":620,"state":"open","locked":false,"title":"decoupling Function, Trigger and Runtimes","user":{"login":"murali-reddy","id":2202956,"avatar_url":"https://avatars2.githubusercontent.com/u/2202956?v=4","gravatar_id":"","url":"https://api.github.com/users/murali-reddy","html_url":"https://github.com/murali-reddy","followers_url":"https://api.github.com/users/murali-reddy/followers","following_url":"https://api.github.com/users/murali-reddy/following{/other_user}","gists_url":"https://api.github.com/users/murali-reddy/gists{/gist_id}","starred_url":"https://api.github.com/users/murali-reddy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/murali-reddy/subscriptions","organizations_url":"https://api.github.com/users/murali-reddy/orgs","repos_url":"https://api.github.com/users/murali-reddy/repos","events_url":"https://api.github.com/users/murali-reddy/events{/privacy}","received_events_url":"https://api.github.com/users/murali-reddy/received_events","type":"User","site_admin":false},"body":"**Issue Ref**: [Issue number related to this PR or None]\r\n\r\n Basic issues this PR addresses are detailed/or dicussed in this [proposal](https://github.com/kubeless/kubeless/blob/master/docs/proposals/decoupling-triggers-and-runtimes.md)\r\n\r\n**Description**: \r\n\r\nThis PR is result of collabrative development effort from @andresmgot, @ngtuna and @murali-reddy \r\n\r\nWhat problems does this PR address?\r\n\r\n***decoupling function and event sources***\r\n\r\nIn the current design of Kubeless, there is just `Function` abstraction, respresented as CRD. This object is used to specify both function details (like function handler, code, runtime etc) and event source details (like Kafkat topic to which this function to be called, cron job etc).\r\n\r\nThis PR brings in notion of `Triggers` as concept in to Kubeless. A Trigger is basically represents the details on the event source and the associated function that needs to be called when event occurs. Existing supported event sources (Kafka, cron job, http) are modelled in to seperate triggers. Corresponding to each trigger there will be seperate CRD controller. This seperation at API layer, provides clean seperation of concerns of functions and event sources.\r\n\r\nAlso this seperation enables Kubeless to support n:m association between the function and event sources. For e.g, Kafka trigger object uses label selector to express the set of functions that need to be associated with trigger. \r\n\r\n***decoupling event source listener and runtimes***\r\n\r\nIn the current Kubeless architecture, pod that is deployed to run the function, also has the event source listener code (like Kafka client subsribing to a particualr topic. Problem with this approach is we need to maintain a separate image for each language, language version, event source combination. \r\n\r\nWith this PR each pod that is deployed to run function exposes a http endpoint, irrespective of event source and language type. Also fuction singature has been altered to carry event data and conext information.\r\n\r\n***design changes***\r\n\r\nSome notes on the design to help the reviewer.\r\n\r\n- Each trigger object has a corresponding CRD controller. Controller watches for add/delete/update events from the k8s api server and process the update to reflect to desired state expressed by the user. \r\n- Tigger object CRD controllers, also watches for `Function` object updates. Controller will take an action only if required. For e.g, when a function is deleted, Kafka trigger controller checks if there is any Kafka trigger object is associated. If there is Kafka trigger object associated then it will stop sending topic message to the function service.\r\n- By default CRD objects (like core objects) are deleted by API server when they are deleted by API. It's not possible for controllers to sync/clean-up when the object is gone. Kubernetes provides a declarative patterns of `Finalizers` which provides a mechansim through which interested controller can request for soft delete of the API object. This PR leverages `Finalizers` to process the deleted objects. Please see [PVC protection controller](https://github.com/kubernetes/kubernetes/blob/master/pkg/controller/volume/pvcprotection/pvc_protection_controller.go) for a reference.\r\n- kubeless-controller has been renamed to `kubeless-controller-manager`, and includes controllers for http triggers and cronjob triggers.\r\n- a new deployment manifest is added for Kafka. When deployed, it creates seperate deployment `afka-trigger-controller`, which has Kafka trigger controller CRD. \r\n\r\n**Known Issue**\r\n\r\n- CI is failing for GKE and Kafka build. I will fix it. But the reviews for the PR can get started.\r\n- Some inconsistent behaviour in edge cases was seen with API machinery for CRD controllers (for instance https://github.com/kubernetes/kubernetes/issues/60538). If any issue found we need to workaround or get it fixed upstream.\r\n- No explict CLI support for trigger creation in this PR. `Kubeless function deploy` implicitly creats the trigger objects as well. You can use API to create trigger object directly. CLI support will be added in seperatle PR.\r\n\r\n**TODOs**:\r\n - [x] Ready to review\r\n - [x] Automated Tests\r\n - [ ] Docs","created_at":"2018-03-07T09:29:49Z","updated_at":"2018-03-19T05:32:05Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8581f6eabb1a85fdefa68caf231219bf6526d62c","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/kubeless/kubeless/pulls/620/commits","review_comments_url":"https://api.github.com/repos/kubeless/kubeless/pulls/620/comments","review_comment_url":"https://api.github.com/repos/kubeless/kubeless/pulls/comments{/number}","comments_url":"https://api.github.com/repos/kubeless/kubeless/issues/620/comments","statuses_url":"https://api.github.com/repos/kubeless/kubeless/statuses/358f8cbd65d7ca1d5e5b0b7024f6e8a67cfb7315","head":{"label":"kubeless:function-trigger-runtimes","ref":"function-trigger-runtimes","sha":"358f8cbd65d7ca1d5e5b0b7024f6e8a67cfb7315","user":{"login":"kubeless","id":25339039,"avatar_url":"https://avatars3.githubusercontent.com/u/25339039?v=4","gravatar_id":"","url":"https://api.github.com/users/kubeless","html_url":"https://github.com/kubeless","followers_url":"https://api.github.com/users/kubeless/followers","following_url":"https://api.github.com/users/kubeless/following{/other_user}","gists_url":"https://api.github.com/users/kubeless/gists{/gist_id}","starred_url":"https://api.github.com/users/kubeless/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubeless/subscriptions","organizations_url":"https://api.github.com/users/kubeless/orgs","repos_url":"https://api.github.com/users/kubeless/repos","events_url":"https://api.github.com/users/kubeless/events{/privacy}","received_events_url":"https://api.github.com/users/kubeless/received_events","type":"Organization","site_admin":false},"repo":{"id":73902337,"name":"kubeless","full_name":"kubeless/kubeless","owner":{"login":"kubeless","id":25339039,"avatar_url":"https://avatars3.githubusercontent.com/u/25339039?v=4","gravatar_id":"","url":"https://api.github.com/users/kubeless","html_url":"https://github.com/kubeless","followers_url":"https://api.github.com/users/kubeless/followers","following_url":"https://api.github.com/users/kubeless/following{/other_user}","gists_url":"https://api.github.com/users/kubeless/gists{/gist_id}","starred_url":"https://api.github.com/users/kubeless/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubeless/subscriptions","organizations_url":"https://api.github.com/users/kubeless/orgs","repos_url":"https://api.github.com/users/kubeless/repos","events_url":"https://api.github.com/users/kubeless/events{/privacy}","received_events_url":"https://api.github.com/users/kubeless/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/kubeless/kubeless","description":"Kubernetes Native Serverless Framework","fork":false,"url":"https://api.github.com/repos/kubeless/kubeless","forks_url":"https://api.github.com/repos/kubeless/kubeless/forks","keys_url":"https://api.github.com/repos/kubeless/kubeless/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kubeless/kubeless/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kubeless/kubeless/teams","hooks_url":"https://api.github.com/repos/kubeless/kubeless/hooks","issue_events_url":"https://api.github.com/repos/kubeless/kubeless/issues/events{/number}","events_url":"https://api.github.com/repos/kubeless/kubeless/events","assignees_url":"https://api.github.com/repos/kubeless/kubeless/assignees{/user}","branches_url":"https://api.github.com/repos/kubeless/kubeless/branches{/branch}","tags_url":"https://api.github.com/repos/kubeless/kubeless/tags","blobs_url":"https://api.github.com/repos/kubeless/kubeless/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kubeless/kubeless/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kubeless/kubeless/git/refs{/sha}","trees_url":"https://api.github.com/repos/kubeless/kubeless/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kubeless/kubeless/statuses/{sha}","languages_url":"https://api.github.com/repos/kubeless/kubeless/languages","stargazers_url":"https://api.github.com/repos/kubeless/kubeless/stargazers","contributors_url":"https://api.github.com/repos/kubeless/kubeless/contributors","subscribers_url":"https://api.github.com/repos/kubeless/kubeless/subscribers","subscription_url":"https://api.github.com/repos/kubeless/kubeless/subscription","commits_url":"https://api.github.com/repos/kubeless/kubeless/commits{/sha}","git_commits_url":"https://api.github.com/repos/kubeless/kubeless/git/commits{/sha}","comments_url":"https://api.github.com/repos/kubeless/kubeless/comments{/number}","issue_comment_url":"https://api.github.com/repos/kubeless/kubeless/issues/comments{/number}","contents_url":"https://api.github.com/repos/kubeless/kubeless/contents/{+path}","compare_url":"https://api.github.com/repos/kubeless/kubeless/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kubeless/kubeless/merges","archive_url":"https://api.github.com/repos/kubeless/kubeless/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kubeless/kubeless/downloads","issues_url":"https://api.github.com/repos/kubeless/kubeless/issues{/number}","pulls_url":"https://api.github.com/repos/kubeless/kubeless/pulls{/number}","milestones_url":"https://api.github.com/repos/kubeless/kubeless/milestones{/number}","notifications_url":"https://api.github.com/repos/kubeless/kubeless/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kubeless/kubeless/labels{/name}","releases_url":"https://api.github.com/repos/kubeless/kubeless/releases{/id}","deployments_url":"https://api.github.com/repos/kubeless/kubeless/deployments","created_at":"2016-11-16T09:03:03Z","updated_at":"2018-03-19T03:44:04Z","pushed_at":"2018-03-19T03:48:27Z","git_url":"git://github.com/kubeless/kubeless.git","ssh_url":"git@github.com:kubeless/kubeless.git","clone_url":"https://github.com/kubeless/kubeless.git","svn_url":"https://github.com/kubeless/kubeless","homepage":"http://kubeless.io","size":77112,"stargazers_count":2128,"watchers_count":2128,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":191,"mirror_url":null,"archived":false,"open_issues_count":70,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":191,"open_issues":70,"watchers":2128,"default_branch":"master"}},"base":{"label":"kubeless:master","ref":"master","sha":"d3c362d5dcf7f9da9d043d109d6f812daed91925","user":{"login":"kubeless","id":25339039,"avatar_url":"https://avatars3.githubusercontent.com/u/25339039?v=4","gravatar_id":"","url":"https://api.github.com/users/kubeless","html_url":"https://github.com/kubeless","followers_url":"https://api.github.com/users/kubeless/followers","following_url":"https://api.github.com/users/kubeless/following{/other_user}","gists_url":"https://api.github.com/users/kubeless/gists{/gist_id}","starred_url":"https://api.github.com/users/kubeless/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubeless/subscriptions","organizations_url":"https://api.github.com/users/kubeless/orgs","repos_url":"https://api.github.com/users/kubeless/repos","events_url":"https://api.github.com/users/kubeless/events{/privacy}","received_events_url":"https://api.github.com/users/kubeless/received_events","type":"Organization","site_admin":false},"repo":{"id":73902337,"name":"kubeless","full_name":"kubeless/kubeless","owner":{"login":"kubeless","id":25339039,"avatar_url":"https://avatars3.githubusercontent.com/u/25339039?v=4","gravatar_id":"","url":"https://api.github.com/users/kubeless","html_url":"https://github.com/kubeless","followers_url":"https://api.github.com/users/kubeless/followers","following_url":"https://api.github.com/users/kubeless/following{/other_user}","gists_url":"https://api.github.com/users/kubeless/gists{/gist_id}","starred_url":"https://api.github.com/users/kubeless/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubeless/subscriptions","organizations_url":"https://api.github.com/users/kubeless/orgs","repos_url":"https://api.github.com/users/kubeless/repos","events_url":"https://api.github.com/users/kubeless/events{/privacy}","received_events_url":"https://api.github.com/users/kubeless/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/kubeless/kubeless","description":"Kubernetes Native Serverless Framework","fork":false,"url":"https://api.github.com/repos/kubeless/kubeless","forks_url":"https://api.github.com/repos/kubeless/kubeless/forks","keys_url":"https://api.github.com/repos/kubeless/kubeless/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kubeless/kubeless/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kubeless/kubeless/teams","hooks_url":"https://api.github.com/repos/kubeless/kubeless/hooks","issue_events_url":"https://api.github.com/repos/kubeless/kubeless/issues/events{/number}","events_url":"https://api.github.com/repos/kubeless/kubeless/events","assignees_url":"https://api.github.com/repos/kubeless/kubeless/assignees{/user}","branches_url":"https://api.github.com/repos/kubeless/kubeless/branches{/branch}","tags_url":"https://api.github.com/repos/kubeless/kubeless/tags","blobs_url":"https://api.github.com/repos/kubeless/kubeless/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kubeless/kubeless/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kubeless/kubeless/git/refs{/sha}","trees_url":"https://api.github.com/repos/kubeless/kubeless/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kubeless/kubeless/statuses/{sha}","languages_url":"https://api.github.com/repos/kubeless/kubeless/languages","stargazers_url":"https://api.github.com/repos/kubeless/kubeless/stargazers","contributors_url":"https://api.github.com/repos/kubeless/kubeless/contributors","subscribers_url":"https://api.github.com/repos/kubeless/kubeless/subscribers","subscription_url":"https://api.github.com/repos/kubeless/kubeless/subscription","commits_url":"https://api.github.com/repos/kubeless/kubeless/commits{/sha}","git_commits_url":"https://api.github.com/repos/kubeless/kubeless/git/commits{/sha}","comments_url":"https://api.github.com/repos/kubeless/kubeless/comments{/number}","issue_comment_url":"https://api.github.com/repos/kubeless/kubeless/issues/comments{/number}","contents_url":"https://api.github.com/repos/kubeless/kubeless/contents/{+path}","compare_url":"https://api.github.com/repos/kubeless/kubeless/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kubeless/kubeless/merges","archive_url":"https://api.github.com/repos/kubeless/kubeless/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kubeless/kubeless/downloads","issues_url":"https://api.github.com/repos/kubeless/kubeless/issues{/number}","pulls_url":"https://api.github.com/repos/kubeless/kubeless/pulls{/number}","milestones_url":"https://api.github.com/repos/kubeless/kubeless/milestones{/number}","notifications_url":"https://api.github.com/repos/kubeless/kubeless/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kubeless/kubeless/labels{/name}","releases_url":"https://api.github.com/repos/kubeless/kubeless/releases{/id}","deployments_url":"https://api.github.com/repos/kubeless/kubeless/deployments","created_at":"2016-11-16T09:03:03Z","updated_at":"2018-03-19T03:44:04Z","pushed_at":"2018-03-19T03:48:27Z","git_url":"git://github.com/kubeless/kubeless.git","ssh_url":"git@github.com:kubeless/kubeless.git","clone_url":"https://github.com/kubeless/kubeless.git","svn_url":"https://github.com/kubeless/kubeless","homepage":"http://kubeless.io","size":77112,"stargazers_count":2128,"watchers_count":2128,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":191,"mirror_url":null,"archived":false,"open_issues_count":70,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":191,"open_issues":70,"watchers":2128,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/kubeless/kubeless/pulls/620"},"html":{"href":"https://github.com/kubeless/kubeless/pull/620"},"issue":{"href":"https://api.github.com/repos/kubeless/kubeless/issues/620"},"comments":{"href":"https://api.github.com/repos/kubeless/kubeless/issues/620/comments"},"review_comments":{"href":"https://api.github.com/repos/kubeless/kubeless/pulls/620/comments"},"review_comment":{"href":"https://api.github.com/repos/kubeless/kubeless/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/kubeless/kubeless/pulls/620/commits"},"statuses":{"href":"https://api.github.com/repos/kubeless/kubeless/statuses/358f8cbd65d7ca1d5e5b0b7024f6e8a67cfb7315"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"anguslees"}}