{"action":"created","comment":{"url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments/59424766","id":59424766,"diff_hunk":"@@ -0,0 +1,189 @@\n+/*\n+Copyright 2016 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 genericapiserver\n+\n+import (\n+\t\"fmt\"\n+\n+\t\"k8s.io/kubernetes/pkg/api/unversioned\"\n+\t\"k8s.io/kubernetes/pkg/runtime\"\n+\t\"k8s.io/kubernetes/pkg/runtime/serializer/versioning\"\n+\t\"k8s.io/kubernetes/pkg/storage\"\n+\tetcdstorage \"k8s.io/kubernetes/pkg/storage/etcd\"\n+\t\"k8s.io/kubernetes/pkg/util/sets\"\n+\n+\t\"github.com/golang/glog\"\n+)\n+\n+// StorageDestinations takes a GroupResource and returns back its storage interface.  This result includes:\n+// 1. Merged etcd config, including: auth, server locations, prefixes\n+// 2. Resource encodings for storage: group,version,kind to store as\n+// 3. Cohabitating default: some resources like hpa are exposed through multiple APIs.  They must agree on 1 and 2\n+type StorageDestinations struct {\n+\t// DefaultEtcdConfig describes how to connect to etcd in general.  It's authentication information will be used for\n+\t// every storage.Interface returned.\n+\tDefaultEtcdConfig etcdstorage.EtcdConfig\n+\n+\t// EtcdLocationOverrides contains the list of \"special\" locations that are used for particular GroupResources\n+\t// These are merged on top of the default DefaultEtcdConfig when requesting the storage.Interface for a given GroupResource\n+\tEtcdLocationOverrides map[unversioned.GroupResource][]string\n+\n+\t// EtcdPrefixOverrides contains the list of \"special\" prefixes for a GroupResource.  Resource=* means for the entire group\n+\tEtcdPrefixOverrides map[unversioned.GroupResource]string\n+\n+\t// DefaultSerializer is used to create encoders and decoders for the storage.Interface.\n+\tDefaultSerializer runtime.NegotiatedSerializer\n+\n+\t// SerializerOverrides contains the list of \"special\" serializers for a GroupResource.  Resource=* means for the entire group\n+\tSerializerOverrides map[unversioned.GroupResource]runtime.NegotiatedSerializer\n+\n+\t// ResourceEncodingConfig describes how to encode a particular GroupVersionResource\n+\tResourceEncodingConfig ResourceEncodingConfig\n+\n+\t// CohabitatingResources keeps track of which resources must be stored together.  This happens when we have multiple ways\n+\t// of exposing one set of concepts.  autoscaling.HPA and extensions.HPA as a for instance\n+\t// The order of the slice matters!  It is the priority order of lookup for finding a storage location\n+\tCohabitatingResources map[unversioned.GroupResource][]unversioned.GroupResource\n+\n+\t// APIResourceConfigSource indicates whether the *storage* is enabled, NOT the API\n+\tAPIResourceConfigSource APIResourceConfigSource\n+}\n+\n+const AllResources = \"*\"\n+\n+func NewStorageDestinations(defaultEtcdConfig etcdstorage.EtcdConfig, defaultSerializer runtime.NegotiatedSerializer, resourceEncodingConfig ResourceEncodingConfig, resourceEnablement APIResourceConfigSource) StorageDestinations {\n+\treturn StorageDestinations{\n+\t\tDefaultEtcdConfig:       defaultEtcdConfig,\n+\t\tEtcdLocationOverrides:   map[unversioned.GroupResource][]string{},\n+\t\tEtcdPrefixOverrides:     map[unversioned.GroupResource]string{},\n+\t\tDefaultSerializer:       defaultSerializer,\n+\t\tSerializerOverrides:     map[unversioned.GroupResource]runtime.NegotiatedSerializer{},\n+\t\tResourceEncodingConfig:  resourceEncodingConfig,\n+\t\tCohabitatingResources:   map[unversioned.GroupResource][]unversioned.GroupResource{},\n+\t\tAPIResourceConfigSource: resourceEnablement,\n+\t}\n+}\n+\n+func (s *StorageDestinations) SetEtcdLocation(groupResource unversioned.GroupResource, location []string) {\n+\ts.EtcdLocationOverrides[groupResource] = location\n+}\n+\n+func (s *StorageDestinations) SetEtcdPrefix(groupResource unversioned.GroupResource, prefix string) {\n+\ts.EtcdPrefixOverrides[groupResource] = prefix\n+}\n+\n+func (s *StorageDestinations) SetSerializer(groupResource unversioned.GroupResource, serializer runtime.NegotiatedSerializer) {\n+\ts.SerializerOverrides[groupResource] = serializer\n+}\n+\n+// AddCohabitatingResources links resources together the order of the slice matters!  its the priority order of lookup for finding a storage location\n+func (s *StorageDestinations) AddCohabitatingResources(groupResources ...unversioned.GroupResource) {\n+\tfor _, resource := range groupResources {\n+\t\ts.CohabitatingResources[resource] = groupResources\n+\t}\n+}\n+\n+func getAllResourcesAlias(resource unversioned.GroupResource) unversioned.GroupResource {\n+\treturn unversioned.GroupResource{Group: resource.Group, Resource: AllResources}\n+}\n+\n+func (s *StorageDestinations) getStorageGroupResource(groupResource unversioned.GroupResource) unversioned.GroupResource {\n+\tfor _, potentialStorageResource := range s.CohabitatingResources[groupResource] {\n+\t\tif s.APIResourceConfigSource.AnyVersionOfResourceEnabled(potentialStorageResource) {\n+\t\t\treturn potentialStorageResource\n+\t\t}\n+\t}\n+\n+\treturn groupResource\n+}\n+\n+// Get finds the storage destination for the given group and resource. It will\n+// return an error if the group has no storage destination configured.\n+func (s *StorageDestinations) Get(groupResource unversioned.GroupResource) (storage.Interface, error) {","path":"pkg/genericapiserver/storage_destinations.go","position":116,"original_position":116,"commit_id":"15c1af757e68285a5b900c2b37adafc433512a5a","original_commit_id":"15c1af757e68285a5b900c2b37adafc433512a5a","user":{"login":"lavalamp","id":647318,"avatar_url":"https://avatars.githubusercontent.com/u/647318?v=3","gravatar_id":"","url":"https://api.github.com/users/lavalamp","html_url":"https://github.com/lavalamp","followers_url":"https://api.github.com/users/lavalamp/followers","following_url":"https://api.github.com/users/lavalamp/following{/other_user}","gists_url":"https://api.github.com/users/lavalamp/gists{/gist_id}","starred_url":"https://api.github.com/users/lavalamp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lavalamp/subscriptions","organizations_url":"https://api.github.com/users/lavalamp/orgs","repos_url":"https://api.github.com/users/lavalamp/repos","events_url":"https://api.github.com/users/lavalamp/events{/privacy}","received_events_url":"https://api.github.com/users/lavalamp/received_events","type":"User","site_admin":false},"body":"Also could use Construct(), Create(), Manufacture(), etc","created_at":"2016-04-12T18:08:59Z","updated_at":"2016-04-12T18:08:59Z","html_url":"https://github.com/kubernetes/kubernetes/pull/23208#discussion_r59424766","pull_request_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/23208","_links":{"self":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments/59424766"},"html":{"href":"https://github.com/kubernetes/kubernetes/pull/23208#discussion_r59424766"},"pull_request":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/23208"}}},"pull_request":{"url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/23208","id":63428382,"html_url":"https://github.com/kubernetes/kubernetes/pull/23208","diff_url":"https://github.com/kubernetes/kubernetes/pull/23208.diff","patch_url":"https://github.com/kubernetes/kubernetes/pull/23208.patch","issue_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/23208","number":23208,"state":"open","locked":false,"title":"make storage enablement, serialization, and location orthogonal","user":{"login":"deads2k","id":8225098,"avatar_url":"https://avatars.githubusercontent.com/u/8225098?v=3","gravatar_id":"","url":"https://api.github.com/users/deads2k","html_url":"https://github.com/deads2k","followers_url":"https://api.github.com/users/deads2k/followers","following_url":"https://api.github.com/users/deads2k/following{/other_user}","gists_url":"https://api.github.com/users/deads2k/gists{/gist_id}","starred_url":"https://api.github.com/users/deads2k/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/deads2k/subscriptions","organizations_url":"https://api.github.com/users/deads2k/orgs","repos_url":"https://api.github.com/users/deads2k/repos","events_url":"https://api.github.com/users/deads2k/events{/privacy}","received_events_url":"https://api.github.com/users/deads2k/received_events","type":"User","site_admin":false},"body":"This allows a caller (command-line, config, code) to specify multiple separate pieces of config information regarding storage and have them properly composed at runtime.  The information provided is exposed through interfaces to allow alternate implementations, which allows us to change the expression of the config moving forward.  I also fixed up the types to be correct as I moved through.\r\n\r\nThe same options still exist, but they're composed slightly differently\r\n 1. specify target etcd servers per Group or per GroupResource\r\n 1. specify storage GroupVersions per Groups or per GroupResource\r\n 1. specify etcd prefixes per GroupVersion or per GroupResource\r\n 1. specify that multiple GroupResources share the same location in etcd\r\n 1. enable GroupResources by GroupVersion or by GroupResource whitelist or GroupResource blacklist\r\n\r\nThe `storage.Interface` is built per GroupResource by:\r\n 1. find the set of possible storage GroupResource based on the priority list of cohabitators\r\n 1. choose a GroupResource from the set by looking at which Groups have the resource enabled\r\n 1. find the target etcd server, etcd prefix, and storage encoding based on the GroupResource\r\n\r\nThe API server can have its resources separately enabled, but for now I've kept them linked.\r\n\r\n@liggitt I think we need this (or something like it) to be able to go from config to these interfaces.  Given another round of refactoring, we may be able to reshape these to be more forward driving.\r\n\r\n@smarterclayton this is important for rebasing and for a seamless 1.2 to 1.3 migration for us.\r\n","created_at":"2016-03-18T19:58:50Z","updated_at":"2016-04-12T18:08:59Z","closed_at":null,"merged_at":null,"merge_commit_sha":"5835492c03a8e751cb326992019299b6a0c964cb","assignee":{"login":"nikhiljindal","id":10199099,"avatar_url":"https://avatars.githubusercontent.com/u/10199099?v=3","gravatar_id":"","url":"https://api.github.com/users/nikhiljindal","html_url":"https://github.com/nikhiljindal","followers_url":"https://api.github.com/users/nikhiljindal/followers","following_url":"https://api.github.com/users/nikhiljindal/following{/other_user}","gists_url":"https://api.github.com/users/nikhiljindal/gists{/gist_id}","starred_url":"https://api.github.com/users/nikhiljindal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nikhiljindal/subscriptions","organizations_url":"https://api.github.com/users/nikhiljindal/orgs","repos_url":"https://api.github.com/users/nikhiljindal/repos","events_url":"https://api.github.com/users/nikhiljindal/events{/privacy}","received_events_url":"https://api.github.com/users/nikhiljindal/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/23208/commits","review_comments_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/23208/comments","review_comment_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments{/number}","comments_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/23208/comments","statuses_url":"https://api.github.com/repos/kubernetes/kubernetes/statuses/15c1af757e68285a5b900c2b37adafc433512a5a","head":{"label":"deads2k:fix-version-override","ref":"fix-version-override","sha":"15c1af757e68285a5b900c2b37adafc433512a5a","user":{"login":"deads2k","id":8225098,"avatar_url":"https://avatars.githubusercontent.com/u/8225098?v=3","gravatar_id":"","url":"https://api.github.com/users/deads2k","html_url":"https://github.com/deads2k","followers_url":"https://api.github.com/users/deads2k/followers","following_url":"https://api.github.com/users/deads2k/following{/other_user}","gists_url":"https://api.github.com/users/deads2k/gists{/gist_id}","starred_url":"https://api.github.com/users/deads2k/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/deads2k/subscriptions","organizations_url":"https://api.github.com/users/deads2k/orgs","repos_url":"https://api.github.com/users/deads2k/repos","events_url":"https://api.github.com/users/deads2k/events{/privacy}","received_events_url":"https://api.github.com/users/deads2k/received_events","type":"User","site_admin":false},"repo":{"id":24939417,"name":"kubernetes","full_name":"deads2k/kubernetes","owner":{"login":"deads2k","id":8225098,"avatar_url":"https://avatars.githubusercontent.com/u/8225098?v=3","gravatar_id":"","url":"https://api.github.com/users/deads2k","html_url":"https://github.com/deads2k","followers_url":"https://api.github.com/users/deads2k/followers","following_url":"https://api.github.com/users/deads2k/following{/other_user}","gists_url":"https://api.github.com/users/deads2k/gists{/gist_id}","starred_url":"https://api.github.com/users/deads2k/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/deads2k/subscriptions","organizations_url":"https://api.github.com/users/deads2k/orgs","repos_url":"https://api.github.com/users/deads2k/repos","events_url":"https://api.github.com/users/deads2k/events{/privacy}","received_events_url":"https://api.github.com/users/deads2k/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/deads2k/kubernetes","description":"Container Cluster Manager","fork":true,"url":"https://api.github.com/repos/deads2k/kubernetes","forks_url":"https://api.github.com/repos/deads2k/kubernetes/forks","keys_url":"https://api.github.com/repos/deads2k/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/deads2k/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/deads2k/kubernetes/teams","hooks_url":"https://api.github.com/repos/deads2k/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/deads2k/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/deads2k/kubernetes/events","assignees_url":"https://api.github.com/repos/deads2k/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/deads2k/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/deads2k/kubernetes/tags","blobs_url":"https://api.github.com/repos/deads2k/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/deads2k/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/deads2k/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/deads2k/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/deads2k/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/deads2k/kubernetes/languages","stargazers_url":"https://api.github.com/repos/deads2k/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/deads2k/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/deads2k/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/deads2k/kubernetes/subscription","commits_url":"https://api.github.com/repos/deads2k/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/deads2k/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/deads2k/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/deads2k/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/deads2k/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/deads2k/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/deads2k/kubernetes/merges","archive_url":"https://api.github.com/repos/deads2k/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/deads2k/kubernetes/downloads","issues_url":"https://api.github.com/repos/deads2k/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/deads2k/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/deads2k/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/deads2k/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/deads2k/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/deads2k/kubernetes/releases{/id}","deployments_url":"https://api.github.com/repos/deads2k/kubernetes/deployments","created_at":"2014-10-08T12:24:01Z","updated_at":"2016-01-11T16:12:51Z","pushed_at":"2016-04-12T11:44:06Z","git_url":"git://github.com/deads2k/kubernetes.git","ssh_url":"git@github.com:deads2k/kubernetes.git","clone_url":"https://github.com/deads2k/kubernetes.git","svn_url":"https://github.com/deads2k/kubernetes","homepage":null,"size":182567,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"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":"4f329516ae7312420577b10ee10005bbe17c87c8","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}","deployments_url":"https://api.github.com/repos/kubernetes/kubernetes/deployments","created_at":"2014-06-06T22:56:04Z","updated_at":"2016-04-12T17:30:12Z","pushed_at":"2016-04-12T18:05:08Z","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":363422,"stargazers_count":13820,"watchers_count":13820,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":4078,"mirror_url":null,"open_issues_count":3361,"forks":4078,"open_issues":3361,"watchers":13820,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/23208"},"html":{"href":"https://github.com/kubernetes/kubernetes/pull/23208"},"issue":{"href":"https://api.github.com/repos/kubernetes/kubernetes/issues/23208"},"comments":{"href":"https://api.github.com/repos/kubernetes/kubernetes/issues/23208/comments"},"review_comments":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/23208/comments"},"review_comment":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/23208/commits"},"statuses":{"href":"https://api.github.com/repos/kubernetes/kubernetes/statuses/15c1af757e68285a5b900c2b37adafc433512a5a"}}}}