{"action":"created","comment":{"url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments/44862448","id":44862448,"diff_hunk":"@@ -0,0 +1,142 @@\n+/*\n+Copyright 2014 The Kubernetes Authors All rights reserved.\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+\n+package wmftoolsenforcer\n+\n+import (\n+\t\"io\"\n+\t\"strconv\"\n+\t\"time\"\n+\n+\t\"k8s.io/kubernetes/pkg/admission\"\n+\t\"k8s.io/kubernetes/pkg/api\"\n+\tapierrors \"k8s.io/kubernetes/pkg/api/errors\"\n+\t\"k8s.io/kubernetes/pkg/client/cache\"\n+\tclient \"k8s.io/kubernetes/pkg/client/unversioned\"\n+\t\"k8s.io/kubernetes/pkg/fields\"\n+\t\"k8s.io/kubernetes/pkg/labels\"\n+\t\"k8s.io/kubernetes/pkg/runtime\"\n+\t\"k8s.io/kubernetes/pkg/watch\"\n+)\n+\n+func init() {\n+\tadmission.RegisterPlugin(\"UidEnforcer\", func(client client.Interface, config io.Reader) (admission.Interface, error) {\n+\t\treturn NewUidEnforcer(client), nil\n+\t})\n+}\n+\n+// plugin contains the client used by the uidenforcer admin controller\n+type plugin struct {\n+\t*admission.Handler\n+\tclient client.Interface\n+\tstore  cache.Store\n+}\n+\n+// NewSecurityContextDeny creates a new instance of the SecurityContextDeny admission controller\n+func NewUidEnforcer(client client.Interface) admission.Interface {\n+\tstore := cache.NewStore(cache.MetaNamespaceKeyFunc)\n+\treflector := cache.NewReflector(\n+\t\t&cache.ListWatch{\n+\t\t\tListFunc: func() (runtime.Object, error) {\n+\t\t\t\treturn client.Namespaces().List(labels.Everything(), fields.Everything())\n+\t\t\t},\n+\t\t\tWatchFunc: func(options api.ListOptions) (watch.Interface, error) {\n+\t\t\t\treturn client.Namespaces().Watch(labels.Everything(), fields.Everything(), options)\n+\t\t\t},\n+\t\t},\n+\t\t&api.Namespace{},\n+\t\tstore,\n+\t\t5*time.Minute,\n+\t)\n+\treflector.Run()\n+\treturn &plugin{\n+\t\tHandler: admission.NewHandler(admission.Create, admission.Update),\n+\t\tclient:  client,\n+\t\tstore:   store,\n+\t}\n+}\n+\n+// This will verify the following:\n+//  - Not a namespace modification from a namespaced user for their own namespace\n+//  - User object has a numeric uid\n+//  - Namespace object has an annotation called RunAsUser that's an integer\n+//\n+// If after all this there's no SecurityContext on each Container with a RunAsUser set to the same RunAsUser, it'll be set\n+func (p *plugin) Admit(a admission.Attributes) (err error) {\n+\tif a.GetResource() != string(api.ResourcePods) && a.GetResource() != \"namespace\" {\n+\t\treturn nil\n+\t}\n+\n+\t// HACK: This should probably be a separate AdmissionController\n+\thackNamespace, ok := a.GetObject().(*api.Namespace)","path":"plugin/pkg/admission/wmftoolsenforcer/admission.go","position":84,"original_position":84,"commit_id":"e94f4bc6c5ac18624cd6e43496bfbecc2710075e","original_commit_id":"e94f4bc6c5ac18624cd6e43496bfbecc2710075e","user":{"login":"pmorie","id":366488,"avatar_url":"https://avatars.githubusercontent.com/u/366488?v=3","gravatar_id":"","url":"https://api.github.com/users/pmorie","html_url":"https://github.com/pmorie","followers_url":"https://api.github.com/users/pmorie/followers","following_url":"https://api.github.com/users/pmorie/following{/other_user}","gists_url":"https://api.github.com/users/pmorie/gists{/gist_id}","starred_url":"https://api.github.com/users/pmorie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pmorie/subscriptions","organizations_url":"https://api.github.com/users/pmorie/orgs","repos_url":"https://api.github.com/users/pmorie/repos","events_url":"https://api.github.com/users/pmorie/events{/privacy}","received_events_url":"https://api.github.com/users/pmorie/received_events","type":"User","site_admin":false},"body":"Also, as we discussed, if you needed to check for multiple types a type-switch is the idiomatic way to do it in go.","created_at":"2015-11-14T19:26:23Z","updated_at":"2015-11-14T19:26:23Z","html_url":"https://github.com/kubernetes/kubernetes/pull/16250#discussion_r44862448","pull_request_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/16250","_links":{"self":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments/44862448"},"html":{"href":"https://github.com/kubernetes/kubernetes/pull/16250#discussion_r44862448"},"pull_request":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/16250"}}},"pull_request":{"url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/16250","id":48699428,"html_url":"https://github.com/kubernetes/kubernetes/pull/16250","diff_url":"https://github.com/kubernetes/kubernetes/pull/16250.diff","patch_url":"https://github.com/kubernetes/kubernetes/pull/16250.patch","issue_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/16250","number":16250,"state":"open","locked":false,"title":"[WIP]  Add wmftoolsenforcer admission controller","user":{"login":"yuvipanda","id":30430,"avatar_url":"https://avatars.githubusercontent.com/u/30430?v=3","gravatar_id":"","url":"https://api.github.com/users/yuvipanda","html_url":"https://github.com/yuvipanda","followers_url":"https://api.github.com/users/yuvipanda/followers","following_url":"https://api.github.com/users/yuvipanda/following{/other_user}","gists_url":"https://api.github.com/users/yuvipanda/gists{/gist_id}","starred_url":"https://api.github.com/users/yuvipanda/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yuvipanda/subscriptions","organizations_url":"https://api.github.com/users/yuvipanda/orgs","repos_url":"https://api.github.com/users/yuvipanda/repos","events_url":"https://api.github.com/users/yuvipanda/events{/privacy}","received_events_url":"https://api.github.com/users/yuvipanda/received_events","type":"User","site_admin":false},"body":" Enforces that:\r\n    \r\n      - All namespaces have a RunAsUser annotation\r\n      - Namespaced users can't touch annotations on their own namespace\r\n      - Pods in a namespace will have RunAsUser set in all the containers\r\n        to the RunAsUser annotation\r\n\r\nThis wouldn't ever be merged, see https://github.com/kubernetes/kubernetes/pull/16250#issuecomment-155553224 for rationale. This is here for review.","created_at":"2015-10-26T03:53:04Z","updated_at":"2015-11-14T19:26:23Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8216bb93c6786038f6f018b74ebab88910bc0406","assignee":{"login":"erictune","id":8105590,"avatar_url":"https://avatars.githubusercontent.com/u/8105590?v=3","gravatar_id":"","url":"https://api.github.com/users/erictune","html_url":"https://github.com/erictune","followers_url":"https://api.github.com/users/erictune/followers","following_url":"https://api.github.com/users/erictune/following{/other_user}","gists_url":"https://api.github.com/users/erictune/gists{/gist_id}","starred_url":"https://api.github.com/users/erictune/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/erictune/subscriptions","organizations_url":"https://api.github.com/users/erictune/orgs","repos_url":"https://api.github.com/users/erictune/repos","events_url":"https://api.github.com/users/erictune/events{/privacy}","received_events_url":"https://api.github.com/users/erictune/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/16250/commits","review_comments_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/16250/comments","review_comment_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments{/number}","comments_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/16250/comments","statuses_url":"https://api.github.com/repos/kubernetes/kubernetes/statuses/e94f4bc6c5ac18624cd6e43496bfbecc2710075e","head":{"label":"yuvipanda:uidenforcer","ref":"uidenforcer","sha":"e94f4bc6c5ac18624cd6e43496bfbecc2710075e","user":{"login":"yuvipanda","id":30430,"avatar_url":"https://avatars.githubusercontent.com/u/30430?v=3","gravatar_id":"","url":"https://api.github.com/users/yuvipanda","html_url":"https://github.com/yuvipanda","followers_url":"https://api.github.com/users/yuvipanda/followers","following_url":"https://api.github.com/users/yuvipanda/following{/other_user}","gists_url":"https://api.github.com/users/yuvipanda/gists{/gist_id}","starred_url":"https://api.github.com/users/yuvipanda/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yuvipanda/subscriptions","organizations_url":"https://api.github.com/users/yuvipanda/orgs","repos_url":"https://api.github.com/users/yuvipanda/repos","events_url":"https://api.github.com/users/yuvipanda/events{/privacy}","received_events_url":"https://api.github.com/users/yuvipanda/received_events","type":"User","site_admin":false},"repo":{"id":41869701,"name":"kubernetes","full_name":"yuvipanda/kubernetes","owner":{"login":"yuvipanda","id":30430,"avatar_url":"https://avatars.githubusercontent.com/u/30430?v=3","gravatar_id":"","url":"https://api.github.com/users/yuvipanda","html_url":"https://github.com/yuvipanda","followers_url":"https://api.github.com/users/yuvipanda/followers","following_url":"https://api.github.com/users/yuvipanda/following{/other_user}","gists_url":"https://api.github.com/users/yuvipanda/gists{/gist_id}","starred_url":"https://api.github.com/users/yuvipanda/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yuvipanda/subscriptions","organizations_url":"https://api.github.com/users/yuvipanda/orgs","repos_url":"https://api.github.com/users/yuvipanda/repos","events_url":"https://api.github.com/users/yuvipanda/events{/privacy}","received_events_url":"https://api.github.com/users/yuvipanda/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/yuvipanda/kubernetes","description":"Container Cluster Manager from Google","fork":true,"url":"https://api.github.com/repos/yuvipanda/kubernetes","forks_url":"https://api.github.com/repos/yuvipanda/kubernetes/forks","keys_url":"https://api.github.com/repos/yuvipanda/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/yuvipanda/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/yuvipanda/kubernetes/teams","hooks_url":"https://api.github.com/repos/yuvipanda/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/yuvipanda/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/yuvipanda/kubernetes/events","assignees_url":"https://api.github.com/repos/yuvipanda/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/yuvipanda/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/yuvipanda/kubernetes/tags","blobs_url":"https://api.github.com/repos/yuvipanda/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/yuvipanda/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/yuvipanda/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/yuvipanda/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/yuvipanda/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/yuvipanda/kubernetes/languages","stargazers_url":"https://api.github.com/repos/yuvipanda/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/yuvipanda/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/yuvipanda/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/yuvipanda/kubernetes/subscription","commits_url":"https://api.github.com/repos/yuvipanda/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/yuvipanda/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/yuvipanda/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/yuvipanda/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/yuvipanda/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/yuvipanda/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/yuvipanda/kubernetes/merges","archive_url":"https://api.github.com/repos/yuvipanda/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/yuvipanda/kubernetes/downloads","issues_url":"https://api.github.com/repos/yuvipanda/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/yuvipanda/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/yuvipanda/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/yuvipanda/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/yuvipanda/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/yuvipanda/kubernetes/releases{/id}","created_at":"2015-09-03T16:09:10Z","updated_at":"2015-09-03T16:09:17Z","pushed_at":"2015-11-11T22:08:30Z","git_url":"git://github.com/yuvipanda/kubernetes.git","ssh_url":"git@github.com:yuvipanda/kubernetes.git","clone_url":"https://github.com/yuvipanda/kubernetes.git","svn_url":"https://github.com/yuvipanda/kubernetes","homepage":"http://kubernetes.io","size":118778,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"kubernetes:master","ref":"master","sha":"eb89df9bb7e8d3a0241a0a2429f61352367b06ea","user":{"login":"kubernetes","id":13629408,"avatar_url":"https://avatars.githubusercontent.com/u/13629408?v=3","gravatar_id":"","url":"https://api.github.com/users/kubernetes","html_url":"https://github.com/kubernetes","followers_url":"https://api.github.com/users/kubernetes/followers","following_url":"https://api.github.com/users/kubernetes/following{/other_user}","gists_url":"https://api.github.com/users/kubernetes/gists{/gist_id}","starred_url":"https://api.github.com/users/kubernetes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubernetes/subscriptions","organizations_url":"https://api.github.com/users/kubernetes/orgs","repos_url":"https://api.github.com/users/kubernetes/repos","events_url":"https://api.github.com/users/kubernetes/events{/privacy}","received_events_url":"https://api.github.com/users/kubernetes/received_events","type":"Organization","site_admin":false},"repo":{"id":20580498,"name":"kubernetes","full_name":"kubernetes/kubernetes","owner":{"login":"kubernetes","id":13629408,"avatar_url":"https://avatars.githubusercontent.com/u/13629408?v=3","gravatar_id":"","url":"https://api.github.com/users/kubernetes","html_url":"https://github.com/kubernetes","followers_url":"https://api.github.com/users/kubernetes/followers","following_url":"https://api.github.com/users/kubernetes/following{/other_user}","gists_url":"https://api.github.com/users/kubernetes/gists{/gist_id}","starred_url":"https://api.github.com/users/kubernetes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubernetes/subscriptions","organizations_url":"https://api.github.com/users/kubernetes/orgs","repos_url":"https://api.github.com/users/kubernetes/repos","events_url":"https://api.github.com/users/kubernetes/events{/privacy}","received_events_url":"https://api.github.com/users/kubernetes/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/kubernetes/kubernetes","description":"Container Cluster Manager from Google","fork":false,"url":"https://api.github.com/repos/kubernetes/kubernetes","forks_url":"https://api.github.com/repos/kubernetes/kubernetes/forks","keys_url":"https://api.github.com/repos/kubernetes/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kubernetes/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kubernetes/kubernetes/teams","hooks_url":"https://api.github.com/repos/kubernetes/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/kubernetes/kubernetes/events","assignees_url":"https://api.github.com/repos/kubernetes/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/kubernetes/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/kubernetes/kubernetes/tags","blobs_url":"https://api.github.com/repos/kubernetes/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kubernetes/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kubernetes/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/kubernetes/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kubernetes/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/kubernetes/kubernetes/languages","stargazers_url":"https://api.github.com/repos/kubernetes/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/kubernetes/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/kubernetes/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/kubernetes/kubernetes/subscription","commits_url":"https://api.github.com/repos/kubernetes/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/kubernetes/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/kubernetes/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/kubernetes/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/kubernetes/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kubernetes/kubernetes/merges","archive_url":"https://api.github.com/repos/kubernetes/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kubernetes/kubernetes/downloads","issues_url":"https://api.github.com/repos/kubernetes/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/kubernetes/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/kubernetes/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kubernetes/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/kubernetes/kubernetes/releases{/id}","created_at":"2014-06-06T22:56:04Z","updated_at":"2015-11-14T15:09:05Z","pushed_at":"2015-11-14T19:10:30Z","git_url":"git://github.com/kubernetes/kubernetes.git","ssh_url":"git@github.com:kubernetes/kubernetes.git","clone_url":"https://github.com/kubernetes/kubernetes.git","svn_url":"https://github.com/kubernetes/kubernetes","homepage":"http://kubernetes.io","size":524627,"stargazers_count":11261,"watchers_count":11261,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":2964,"mirror_url":null,"open_issues_count":2298,"forks":2964,"open_issues":2298,"watchers":11261,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/16250"},"html":{"href":"https://github.com/kubernetes/kubernetes/pull/16250"},"issue":{"href":"https://api.github.com/repos/kubernetes/kubernetes/issues/16250"},"comments":{"href":"https://api.github.com/repos/kubernetes/kubernetes/issues/16250/comments"},"review_comments":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/16250/comments"},"review_comment":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/16250/commits"},"statuses":{"href":"https://api.github.com/repos/kubernetes/kubernetes/statuses/e94f4bc6c5ac18624cd6e43496bfbecc2710075e"}}}}