{"action":"created","comment":{"url":"https://api.github.com/repos/projectcalico/libcalico-go/pulls/comments/85873605","pull_request_review_id":6562058,"id":85873605,"diff_hunk":"@@ -0,0 +1,536 @@\n+// Copyright (c) 2016 Tigera, Inc. 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+package k8s\n+\n+import (\n+\t\"fmt\"\n+\t\"time\"\n+\n+\tlog \"github.com/Sirupsen/logrus\"\n+\t\"github.com/projectcalico/libcalico-go/lib/backend/api\"\n+\t\"github.com/projectcalico/libcalico-go/lib/backend/compat\"\n+\t\"github.com/projectcalico/libcalico-go/lib/backend/model\"\n+\tk8sapi \"k8s.io/kubernetes/pkg/api\"\n+\t\"k8s.io/kubernetes/pkg/apis/extensions\"\n+\t\"k8s.io/kubernetes/pkg/watch\"\n+\t\"reflect\"\n+)\n+\n+func newSyncer(kc KubeClient, callbacks api.SyncerCallbacks) *kubeSyncer {\n+\treturn &kubeSyncer{\n+\t\tkc:        kc,\n+\t\tcallbacks: callbacks,\n+\t}\n+}\n+\n+type kubeSyncer struct {\n+\tkc        KubeClient\n+\tcallbacks api.SyncerCallbacks\n+\tOneShot   bool\n+}\n+\n+// Holds resource version information.\n+type resourceVersions struct {\n+\tpodVersion           string\n+\tnamespaceVersion     string\n+\tnetworkPolicyVersion string\n+}\n+\n+func getUpdateType(e watch.Event) model.UpdateType {\n+\t// Determine the update type.\n+\tupdateType := model.UpdateTypeKVUnknown\n+\tswitch e.Type {\n+\tcase watch.Added:\n+\t\tupdateType = model.UpdateTypeKVNew\n+\tcase watch.Deleted:\n+\t\tupdateType = model.UpdateTypeKVDeleted\n+\tcase watch.Modified:\n+\t\tupdateType = model.UpdateTypeKVUpdated\n+\t}\n+\treturn updateType\n+}\n+\n+func (syn *kubeSyncer) Start() {\n+\t// Channel for receiving updates from a snapshot.\n+\tsnapshotUpdates := make(chan *[]model.Update)\n+\n+\t// Channel for receiving updates from the watcher.\n+\twatchUpdates := make(chan *model.Update)\n+\n+\t// Channel used by the watcher to trigger a re-sync.\n+\ttriggerResync := make(chan *resourceVersions, 5)\n+\n+\t// Channel to send the index from which to start the snapshot.\n+\tinitialSnapshotIndex := make(chan *resourceVersions)\n+\n+\t// Status channel\n+\tstatusUpdates := make(chan api.SyncStatus)\n+\n+\t// If we're not in one-shot mode, start the API watcher to\n+\t// gather updates.\n+\tif !syn.OneShot {\n+\t\tgo syn.watchKubeAPI(watchUpdates, triggerResync, initialSnapshotIndex)\n+\t}\n+\n+\t// Start a background thread to read snapshots from etcd.  It will\n+\t// read a start-of-day snapshot and then wait to be signalled on the\n+\t// resyncIndex channel.\n+\tgo syn.readSnapshot(snapshotUpdates, triggerResync, initialSnapshotIndex, statusUpdates)\n+\n+\t// Start a routine to merge updates from the snapshot routine and the\n+\t// watch routine (if running), and pass information to callbacks.\n+\t// TODO: We're never actually running both the snapshot thread and the watch thread at the same time\n+\t// so what's the point?\n+\tgo syn.mergeUpdates(snapshotUpdates, watchUpdates, statusUpdates)\n+}\n+\n+// mergeUpdates ensures that callbacks are all executed from the same thread.\n+func (syn *kubeSyncer) mergeUpdates(snapshotUpdates chan *[]model.Update, watchUpdates chan *model.Update, statusUpdates chan api.SyncStatus) {\n+\tvar update *model.Update\n+\tvar updates *[]model.Update\n+\tcurrentStatus := api.WaitForDatastore\n+\tnewStatus := api.WaitForDatastore\n+\tsyn.callbacks.OnStatusUpdated(api.WaitForDatastore)\n+\tfor {\n+\t\tselect {\n+\t\tcase updates = <-snapshotUpdates:\n+\t\t\tlog.Debugf(\"Snapshot update: %+v\", updates)\n+\t\t\tif currentStatus != api.ResyncInProgress {\n+\t\t\t\tpanic(\"Recieved snapshot update while not resyncing\")\n+\t\t\t}\n+\t\t\tsyn.callbacks.OnUpdates(*updates)","path":"lib/backend/k8s/syncer.go","position":113,"original_position":113,"commit_id":"a7446856f40a0c1b85bb6c6e1fd1775eb5dc30f3","original_commit_id":"8fcc400db7cace8f29700a6a7eb5faecf9c818d3","user":{"login":"caseydavenport","id":1944093,"avatar_url":"https://avatars.githubusercontent.com/u/1944093?v=3","gravatar_id":"","url":"https://api.github.com/users/caseydavenport","html_url":"https://github.com/caseydavenport","followers_url":"https://api.github.com/users/caseydavenport/followers","following_url":"https://api.github.com/users/caseydavenport/following{/other_user}","gists_url":"https://api.github.com/users/caseydavenport/gists{/gist_id}","starred_url":"https://api.github.com/users/caseydavenport/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caseydavenport/subscriptions","organizations_url":"https://api.github.com/users/caseydavenport/orgs","repos_url":"https://api.github.com/users/caseydavenport/repos","events_url":"https://api.github.com/users/caseydavenport/events{/privacy}","received_events_url":"https://api.github.com/users/caseydavenport/received_events","type":"User","site_admin":false},"body":"@fasaxc does Felix treat a snapshot different than any other batch of updates it might receive?\r\n\r\nI would have thought that Felix should treat a snapshot as a \"this is the current state\", wiping out any any state it's storing internally and replacing it with the snapshot (so if an update isn't in the snapshot, but was known by Felix before the snapshot, it is essentially deleted from Felix upon receiving the snapshot)\r\n\r\nFor the Kubernetes case, if a resource is deleted _during_ a snapshot, the Kubernetes API will inform us of any deletes that occurred when we start the watches below, since we start with the provided `resourceVersion` from the snapshot for each resource type.\r\n\r\nFrom Felix's point of view this means it will get a snapshot with a bunch of stuff in it, and then subsequent modify / delete events immediately following.\r\n\r\nIf the snapshot takes so long that the resourceVersions are immediately stale, then a new snapshot will be triggered right away.\r\n\r\nAm I missing something?","created_at":"2016-11-01T04:24:28Z","updated_at":"2016-11-01T04:24:28Z","html_url":"https://github.com/projectcalico/libcalico-go/pull/232#discussion_r85873605","pull_request_url":"https://api.github.com/repos/projectcalico/libcalico-go/pulls/232","_links":{"self":{"href":"https://api.github.com/repos/projectcalico/libcalico-go/pulls/comments/85873605"},"html":{"href":"https://github.com/projectcalico/libcalico-go/pull/232#discussion_r85873605"},"pull_request":{"href":"https://api.github.com/repos/projectcalico/libcalico-go/pulls/232"}}},"pull_request":{"url":"https://api.github.com/repos/projectcalico/libcalico-go/pulls/232","id":91630401,"html_url":"https://github.com/projectcalico/libcalico-go/pull/232","diff_url":"https://github.com/projectcalico/libcalico-go/pull/232.diff","patch_url":"https://github.com/projectcalico/libcalico-go/pull/232.patch","issue_url":"https://api.github.com/repos/projectcalico/libcalico-go/issues/232","number":232,"state":"open","locked":false,"title":"Add Kubernetes Datastore Driver","user":{"login":"caseydavenport","id":1944093,"avatar_url":"https://avatars.githubusercontent.com/u/1944093?v=3","gravatar_id":"","url":"https://api.github.com/users/caseydavenport","html_url":"https://github.com/caseydavenport","followers_url":"https://api.github.com/users/caseydavenport/followers","following_url":"https://api.github.com/users/caseydavenport/following{/other_user}","gists_url":"https://api.github.com/users/caseydavenport/gists{/gist_id}","starred_url":"https://api.github.com/users/caseydavenport/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caseydavenport/subscriptions","organizations_url":"https://api.github.com/users/caseydavenport/orgs","repos_url":"https://api.github.com/users/caseydavenport/repos","events_url":"https://api.github.com/users/caseydavenport/events{/privacy}","received_events_url":"https://api.github.com/users/caseydavenport/received_events","type":"User","site_admin":false},"body":"@fasaxc Looks like this PR also has a number of your yet unmerged fixes in it - hopefully you can spot which changes those are :)\r\n\r\nIt also appears to have a couple conflicts that I'll fix up when I get into the office in a little bit.","created_at":"2016-10-31T15:29:39Z","updated_at":"2016-11-01T04:24:28Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f3db502474e4c9e5602accea58bb2e0c0080a764","assignee":{"login":"fasaxc","id":469264,"avatar_url":"https://avatars.githubusercontent.com/u/469264?v=3","gravatar_id":"","url":"https://api.github.com/users/fasaxc","html_url":"https://github.com/fasaxc","followers_url":"https://api.github.com/users/fasaxc/followers","following_url":"https://api.github.com/users/fasaxc/following{/other_user}","gists_url":"https://api.github.com/users/fasaxc/gists{/gist_id}","starred_url":"https://api.github.com/users/fasaxc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fasaxc/subscriptions","organizations_url":"https://api.github.com/users/fasaxc/orgs","repos_url":"https://api.github.com/users/fasaxc/repos","events_url":"https://api.github.com/users/fasaxc/events{/privacy}","received_events_url":"https://api.github.com/users/fasaxc/received_events","type":"User","site_admin":false},"assignees":[{"login":"fasaxc","id":469264,"avatar_url":"https://avatars.githubusercontent.com/u/469264?v=3","gravatar_id":"","url":"https://api.github.com/users/fasaxc","html_url":"https://github.com/fasaxc","followers_url":"https://api.github.com/users/fasaxc/followers","following_url":"https://api.github.com/users/fasaxc/following{/other_user}","gists_url":"https://api.github.com/users/fasaxc/gists{/gist_id}","starred_url":"https://api.github.com/users/fasaxc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fasaxc/subscriptions","organizations_url":"https://api.github.com/users/fasaxc/orgs","repos_url":"https://api.github.com/users/fasaxc/repos","events_url":"https://api.github.com/users/fasaxc/events{/privacy}","received_events_url":"https://api.github.com/users/fasaxc/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/projectcalico/libcalico-go/pulls/232/commits","review_comments_url":"https://api.github.com/repos/projectcalico/libcalico-go/pulls/232/comments","review_comment_url":"https://api.github.com/repos/projectcalico/libcalico-go/pulls/comments{/number}","comments_url":"https://api.github.com/repos/projectcalico/libcalico-go/issues/232/comments","statuses_url":"https://api.github.com/repos/projectcalico/libcalico-go/statuses/a7446856f40a0c1b85bb6c6e1fd1775eb5dc30f3","head":{"label":"caseydavenport:k8s-backend","ref":"k8s-backend","sha":"a7446856f40a0c1b85bb6c6e1fd1775eb5dc30f3","user":{"login":"caseydavenport","id":1944093,"avatar_url":"https://avatars.githubusercontent.com/u/1944093?v=3","gravatar_id":"","url":"https://api.github.com/users/caseydavenport","html_url":"https://github.com/caseydavenport","followers_url":"https://api.github.com/users/caseydavenport/followers","following_url":"https://api.github.com/users/caseydavenport/following{/other_user}","gists_url":"https://api.github.com/users/caseydavenport/gists{/gist_id}","starred_url":"https://api.github.com/users/caseydavenport/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caseydavenport/subscriptions","organizations_url":"https://api.github.com/users/caseydavenport/orgs","repos_url":"https://api.github.com/users/caseydavenport/repos","events_url":"https://api.github.com/users/caseydavenport/events{/privacy}","received_events_url":"https://api.github.com/users/caseydavenport/received_events","type":"User","site_admin":false},"repo":{"id":63621502,"name":"libcalico-go","full_name":"caseydavenport/libcalico-go","owner":{"login":"caseydavenport","id":1944093,"avatar_url":"https://avatars.githubusercontent.com/u/1944093?v=3","gravatar_id":"","url":"https://api.github.com/users/caseydavenport","html_url":"https://github.com/caseydavenport","followers_url":"https://api.github.com/users/caseydavenport/followers","following_url":"https://api.github.com/users/caseydavenport/following{/other_user}","gists_url":"https://api.github.com/users/caseydavenport/gists{/gist_id}","starred_url":"https://api.github.com/users/caseydavenport/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/caseydavenport/subscriptions","organizations_url":"https://api.github.com/users/caseydavenport/orgs","repos_url":"https://api.github.com/users/caseydavenport/repos","events_url":"https://api.github.com/users/caseydavenport/events{/privacy}","received_events_url":"https://api.github.com/users/caseydavenport/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/caseydavenport/libcalico-go","description":"Golang Calico library functions:  https://www.projectcalico.org","fork":true,"url":"https://api.github.com/repos/caseydavenport/libcalico-go","forks_url":"https://api.github.com/repos/caseydavenport/libcalico-go/forks","keys_url":"https://api.github.com/repos/caseydavenport/libcalico-go/keys{/key_id}","collaborators_url":"https://api.github.com/repos/caseydavenport/libcalico-go/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/caseydavenport/libcalico-go/teams","hooks_url":"https://api.github.com/repos/caseydavenport/libcalico-go/hooks","issue_events_url":"https://api.github.com/repos/caseydavenport/libcalico-go/issues/events{/number}","events_url":"https://api.github.com/repos/caseydavenport/libcalico-go/events","assignees_url":"https://api.github.com/repos/caseydavenport/libcalico-go/assignees{/user}","branches_url":"https://api.github.com/repos/caseydavenport/libcalico-go/branches{/branch}","tags_url":"https://api.github.com/repos/caseydavenport/libcalico-go/tags","blobs_url":"https://api.github.com/repos/caseydavenport/libcalico-go/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/caseydavenport/libcalico-go/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/caseydavenport/libcalico-go/git/refs{/sha}","trees_url":"https://api.github.com/repos/caseydavenport/libcalico-go/git/trees{/sha}","statuses_url":"https://api.github.com/repos/caseydavenport/libcalico-go/statuses/{sha}","languages_url":"https://api.github.com/repos/caseydavenport/libcalico-go/languages","stargazers_url":"https://api.github.com/repos/caseydavenport/libcalico-go/stargazers","contributors_url":"https://api.github.com/repos/caseydavenport/libcalico-go/contributors","subscribers_url":"https://api.github.com/repos/caseydavenport/libcalico-go/subscribers","subscription_url":"https://api.github.com/repos/caseydavenport/libcalico-go/subscription","commits_url":"https://api.github.com/repos/caseydavenport/libcalico-go/commits{/sha}","git_commits_url":"https://api.github.com/repos/caseydavenport/libcalico-go/git/commits{/sha}","comments_url":"https://api.github.com/repos/caseydavenport/libcalico-go/comments{/number}","issue_comment_url":"https://api.github.com/repos/caseydavenport/libcalico-go/issues/comments{/number}","contents_url":"https://api.github.com/repos/caseydavenport/libcalico-go/contents/{+path}","compare_url":"https://api.github.com/repos/caseydavenport/libcalico-go/compare/{base}...{head}","merges_url":"https://api.github.com/repos/caseydavenport/libcalico-go/merges","archive_url":"https://api.github.com/repos/caseydavenport/libcalico-go/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/caseydavenport/libcalico-go/downloads","issues_url":"https://api.github.com/repos/caseydavenport/libcalico-go/issues{/number}","pulls_url":"https://api.github.com/repos/caseydavenport/libcalico-go/pulls{/number}","milestones_url":"https://api.github.com/repos/caseydavenport/libcalico-go/milestones{/number}","notifications_url":"https://api.github.com/repos/caseydavenport/libcalico-go/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/caseydavenport/libcalico-go/labels{/name}","releases_url":"https://api.github.com/repos/caseydavenport/libcalico-go/releases{/id}","deployments_url":"https://api.github.com/repos/caseydavenport/libcalico-go/deployments","created_at":"2016-07-18T17:02:22Z","updated_at":"2016-07-18T17:02:23Z","pushed_at":"2016-10-31T21:21:59Z","git_url":"git://github.com/caseydavenport/libcalico-go.git","ssh_url":"git@github.com:caseydavenport/libcalico-go.git","clone_url":"https://github.com/caseydavenport/libcalico-go.git","svn_url":"https://github.com/caseydavenport/libcalico-go","homepage":null,"size":930,"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":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"projectcalico:master","ref":"master","sha":"e5a0c16a3f1ccf72ef91ec6407930cb8d3b793f4","user":{"login":"projectcalico","id":12304728,"avatar_url":"https://avatars.githubusercontent.com/u/12304728?v=3","gravatar_id":"","url":"https://api.github.com/users/projectcalico","html_url":"https://github.com/projectcalico","followers_url":"https://api.github.com/users/projectcalico/followers","following_url":"https://api.github.com/users/projectcalico/following{/other_user}","gists_url":"https://api.github.com/users/projectcalico/gists{/gist_id}","starred_url":"https://api.github.com/users/projectcalico/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/projectcalico/subscriptions","organizations_url":"https://api.github.com/users/projectcalico/orgs","repos_url":"https://api.github.com/users/projectcalico/repos","events_url":"https://api.github.com/users/projectcalico/events{/privacy}","received_events_url":"https://api.github.com/users/projectcalico/received_events","type":"Organization","site_admin":false},"repo":{"id":63438319,"name":"libcalico-go","full_name":"projectcalico/libcalico-go","owner":{"login":"projectcalico","id":12304728,"avatar_url":"https://avatars.githubusercontent.com/u/12304728?v=3","gravatar_id":"","url":"https://api.github.com/users/projectcalico","html_url":"https://github.com/projectcalico","followers_url":"https://api.github.com/users/projectcalico/followers","following_url":"https://api.github.com/users/projectcalico/following{/other_user}","gists_url":"https://api.github.com/users/projectcalico/gists{/gist_id}","starred_url":"https://api.github.com/users/projectcalico/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/projectcalico/subscriptions","organizations_url":"https://api.github.com/users/projectcalico/orgs","repos_url":"https://api.github.com/users/projectcalico/repos","events_url":"https://api.github.com/users/projectcalico/events{/privacy}","received_events_url":"https://api.github.com/users/projectcalico/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/projectcalico/libcalico-go","description":"Golang Calico library functions:  https://www.projectcalico.org","fork":false,"url":"https://api.github.com/repos/projectcalico/libcalico-go","forks_url":"https://api.github.com/repos/projectcalico/libcalico-go/forks","keys_url":"https://api.github.com/repos/projectcalico/libcalico-go/keys{/key_id}","collaborators_url":"https://api.github.com/repos/projectcalico/libcalico-go/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/projectcalico/libcalico-go/teams","hooks_url":"https://api.github.com/repos/projectcalico/libcalico-go/hooks","issue_events_url":"https://api.github.com/repos/projectcalico/libcalico-go/issues/events{/number}","events_url":"https://api.github.com/repos/projectcalico/libcalico-go/events","assignees_url":"https://api.github.com/repos/projectcalico/libcalico-go/assignees{/user}","branches_url":"https://api.github.com/repos/projectcalico/libcalico-go/branches{/branch}","tags_url":"https://api.github.com/repos/projectcalico/libcalico-go/tags","blobs_url":"https://api.github.com/repos/projectcalico/libcalico-go/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/projectcalico/libcalico-go/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/projectcalico/libcalico-go/git/refs{/sha}","trees_url":"https://api.github.com/repos/projectcalico/libcalico-go/git/trees{/sha}","statuses_url":"https://api.github.com/repos/projectcalico/libcalico-go/statuses/{sha}","languages_url":"https://api.github.com/repos/projectcalico/libcalico-go/languages","stargazers_url":"https://api.github.com/repos/projectcalico/libcalico-go/stargazers","contributors_url":"https://api.github.com/repos/projectcalico/libcalico-go/contributors","subscribers_url":"https://api.github.com/repos/projectcalico/libcalico-go/subscribers","subscription_url":"https://api.github.com/repos/projectcalico/libcalico-go/subscription","commits_url":"https://api.github.com/repos/projectcalico/libcalico-go/commits{/sha}","git_commits_url":"https://api.github.com/repos/projectcalico/libcalico-go/git/commits{/sha}","comments_url":"https://api.github.com/repos/projectcalico/libcalico-go/comments{/number}","issue_comment_url":"https://api.github.com/repos/projectcalico/libcalico-go/issues/comments{/number}","contents_url":"https://api.github.com/repos/projectcalico/libcalico-go/contents/{+path}","compare_url":"https://api.github.com/repos/projectcalico/libcalico-go/compare/{base}...{head}","merges_url":"https://api.github.com/repos/projectcalico/libcalico-go/merges","archive_url":"https://api.github.com/repos/projectcalico/libcalico-go/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/projectcalico/libcalico-go/downloads","issues_url":"https://api.github.com/repos/projectcalico/libcalico-go/issues{/number}","pulls_url":"https://api.github.com/repos/projectcalico/libcalico-go/pulls{/number}","milestones_url":"https://api.github.com/repos/projectcalico/libcalico-go/milestones{/number}","notifications_url":"https://api.github.com/repos/projectcalico/libcalico-go/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/projectcalico/libcalico-go/labels{/name}","releases_url":"https://api.github.com/repos/projectcalico/libcalico-go/releases{/id}","deployments_url":"https://api.github.com/repos/projectcalico/libcalico-go/deployments","created_at":"2016-07-15T17:09:40Z","updated_at":"2016-10-28T11:09:44Z","pushed_at":"2016-10-31T22:46:19Z","git_url":"git://github.com/projectcalico/libcalico-go.git","ssh_url":"git@github.com:projectcalico/libcalico-go.git","clone_url":"https://github.com/projectcalico/libcalico-go.git","svn_url":"https://github.com/projectcalico/libcalico-go","homepage":null,"size":1359,"stargazers_count":13,"watchers_count":13,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":14,"mirror_url":null,"open_issues_count":30,"forks":14,"open_issues":30,"watchers":13,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/projectcalico/libcalico-go/pulls/232"},"html":{"href":"https://github.com/projectcalico/libcalico-go/pull/232"},"issue":{"href":"https://api.github.com/repos/projectcalico/libcalico-go/issues/232"},"comments":{"href":"https://api.github.com/repos/projectcalico/libcalico-go/issues/232/comments"},"review_comments":{"href":"https://api.github.com/repos/projectcalico/libcalico-go/pulls/232/comments"},"review_comment":{"href":"https://api.github.com/repos/projectcalico/libcalico-go/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/projectcalico/libcalico-go/pulls/232/commits"},"statuses":{"href":"https://api.github.com/repos/projectcalico/libcalico-go/statuses/a7446856f40a0c1b85bb6c6e1fd1775eb5dc30f3"}}}}
{"actor":{"display_login":"caseydavenport"}}