payload: {"action":"opened","number":20,"pull_request":{"url":"https://api.github.com/repos/dougbtv/whereabouts/pulls/20","id":326469676,"node_id":"MDExOlB1bGxSZXF1ZXN0MzI2NDY5Njc2","html_url":"https://github.com/dougbtv/whereabouts/pull/20","diff_url":"https://github.com/dougbtv/whereabouts/pull/20.diff","patch_url":"https://github.com/dougbtv/whereabouts/pull/20.patch","issue_url":"https://api.github.com/repos/dougbtv/whereabouts/issues/20","number":20,"state":"open","locked":false,"title":"add kubernetes CRD backend","user":{"login":"crandles","id":190343,"node_id":"MDQ6VXNlcjE5MDM0Mw==","avatar_url":"https://avatars1.githubusercontent.com/u/190343?v=4","gravatar_id":"","url":"https://api.github.com/users/crandles","html_url":"https://github.com/crandles","followers_url":"https://api.github.com/users/crandles/followers","following_url":"https://api.github.com/users/crandles/following{/other_user}","gists_url":"https://api.github.com/users/crandles/gists{/gist_id}","starred_url":"https://api.github.com/users/crandles/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/crandles/subscriptions","organizations_url":"https://api.github.com/users/crandles/orgs","repos_url":"https://api.github.com/users/crandles/repos","events_url":"https://api.github.com/users/crandles/events{/privacy}","received_events_url":"https://api.github.com/users/crandles/received_events","type":"User","site_admin":false},"body":"This adds support for using a [Kubernetes CRD](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) as a backend for tracking IP allocations.\r\n\r\n## example cni-config\r\n```json\r\n{\r\n    \"cniVersion\": \"0.3.1\",\r\n    \"name\": \"macvlan-app\",\r\n    \"type\": \"macvlan\",\r\n    \"master\": \"eth0\",\r\n    \"mode\": \"bridge\",\r\n    \"ipam\": {\r\n      \"name\": \"whereabouts\",\r\n      \"datastore\": \"kubernetes\",\r\n      \"range\": \"10.38.177.240-10.38.177.254/27\",\r\n      \"kubernetes\": {\r\n        \"kubeconfig\": \"/etc/cni/net.d/whereabouts.d/whereabouts.kubeconfig\",\r\n      },\r\n      \"type\": \"whereabouts\",\r\n      \"log_file\" : \"/tmp/whereabouts.log\",\r\n      \"log_level\" : \"debug\"\r\n    }\r\n}\r\n```\r\n\r\n## example pool resource\r\n\r\n```yaml\r\n- apiVersion: whereabouts.cni.k8s.io/v1alpha1\r\n  kind: IPPool\r\n  metadata:\r\n    creationTimestamp: \"2019-10-08T23:01:17Z\"\r\n    generation: 155\r\n    name: 10.60.12.0-22\r\n    namespace: kube-system\r\n    resourceVersion: \"10101129\"\r\n    selfLink: /apis/whereabouts.cni.k8s.io/v1alpha1/namespaces/kube-system/ippools/10.60.12.0-22\r\n    uid: 88ba4054-ea1f-11e9-9676-48df378ac3f0\r\n  spec:\r\n    allocations:\r\n      \"36\":\r\n        id: 654ebfa2b434730351877c2be47fc71a06dcda09e72c9e15bd85b611597b9b13\r\n      \"37\":\r\n        id: b7a894bb485c4030db28704ce4ea2b5bc6a4e64ddad45e114daf44238b6db412\r\n      \"38\":\r\n        id: 7297ed8fddbeb33309599256ef88f23bb7026f96910717262e89cc000edfe70f\r\n      \"39\":\r\n        id: 85afbd8886326c7e021ef674bbab6c3a9d4091fafd01af46517cd582626c4634\r\n      \"40\":\r\n        id: 01ce0e96f3388d1707900783bed3964c8019351f06a45c63cc6304a0cb76f66a\r\n      \"41\":\r\n        id: 67a74578c853ae314eb106030cf2207485d438e5b20a50747479cc1c9ee5b664\r\n      \"42\":\r\n        id: 3cc0111c7c9f5f50e46385ab4817821bb703e831130fd6426c2ca44b5b3d0042\r\n      \"43\":\r\n        id: e5501baf0244cf25ffcbe5085b05ae4d0b3ef0052451e31417ddbc45926f9825\r\n      \"44\":\r\n        id: 9163aacb0d458d7c1fceb0dee51eb951eddaffab55fa420674241b34fbbd726f\r\n      \"45\":\r\n        id: 0f380bfe3f8d042fa504e89ee51f2b5857b2430db21f800f9707fa4eaf985c4c\r\n      \"46\":\r\n        id: 99b53907242f58113c6f550d69a5df504895efa31be80c77deb8b1530c595e60\r\n      \"47\":\r\n        id: e01430da4e804a1046f3d7570ba926360d894e0d09124a4bb37bcbe47db136ed\r\n      \"48\":\r\n        id: 195bbc53358d844d3bd3d36eda6a505e9e7f5ab9f2d0433d408ae0f8c6a0ff41\r\n      \"49\":\r\n        id: 50b3ecb8f2015c7f8267f8808782ec5b69295e8f95521d368cc91f69a106192f\r\n    range: 10.60.12.0/22\r\n```\r\n\r\nThe main `storage.IPManagement` function is modified to support whichever backend is specified in the cni config, and allows for the storage interactions to retry in certain error conditions.\r\n\r\nThe kubernetes backend uses [kubebuilder](https://book.kubebuilder.io) tooling to generate code and artifacts necessary for the CRDs. \r\n\r\n## Additional changes:\r\nAdditionally, while refactoring the code to support multiple backends, and after some experimentation with the recent #13 feature and etcd refactorings, I made  additional changes:\r\n- etcd keys are prefixed with `/whereabouts`\r\n  - I meant to include this in #10\r\n- etcd binary used for tests instead of etcd docker container\r\n  * provided by controller-runtime's [envtest](https://godoc.org/sigs.k8s.io/controller-runtime/pkg/envtest)/[integration](https://godoc.org/sigs.k8s.io/testing_frameworks/integration) packages\r\n- kubernetes apiserver & etcd is used for kubernetes and etcd backend tests\r\n  - existing etcd via docker usage removed\r\n- some changes to the allocation package for code reuse\r\n- bumped Go version to 1.13\r\n- minor changes to allocate package for code reuse around IP addresses\r\n\r\nIf it helps, I can back out any of the changes that aren't specifically relevant to the kubernetes backend.\r\n\r\nI have updated the `daemonset-install.yaml` in anticipation of the next version to: `dougbtv/whereabouts:v0.2`.\r\n\r\nIt may take a few tries to get the travis changes working.\r\n\r\nCloses #12 ","created_at":"2019-10-09T22:12:28Z","updated_at":"2019-10-09T22:12:28Z","closed_at":null,"merged_at":null,"merge_commit_sha":null,"assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/dougbtv/whereabouts/pulls/20/commits","review_comments_url":"https://api.github.com/repos/dougbtv/whereabouts/pulls/20/comments","review_comment_url":"https://api.github.com/repos/dougbtv/whereabouts/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dougbtv/whereabouts/issues/20/comments","statuses_url":"https://api.github.com/repos/dougbtv/whereabouts/statuses/73ffd2b5f34793b73e1cec255a6f13615511cfc8","head":{"label":"crandles:k8s","ref":"k8s","sha":"73ffd2b5f34793b73e1cec255a6f13615511cfc8","user":{"login":"crandles","id":190343,"node_id":"MDQ6VXNlcjE5MDM0Mw==","avatar_url":"https://avatars1.githubusercontent.com/u/190343?v=4","gravatar_id":"","url":"https://api.github.com/users/crandles","html_url":"https://github.com/crandles","followers_url":"https://api.github.com/users/crandles/followers","following_url":"https://api.github.com/users/crandles/following{/other_user}","gists_url":"https://api.github.com/users/crandles/gists{/gist_id}","starred_url":"https://api.github.com/users/crandles/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/crandles/subscriptions","organizations_url":"https://api.github.com/users/crandles/orgs","repos_url":"https://api.github.com/users/crandles/repos","events_url":"https://api.github.com/users/crandles/events{/privacy}","received_events_url":"https://api.github.com/users/crandles/received_events","type":"User","site_admin":false},"repo":{"id":203826232,"node_id":"MDEwOlJlcG9zaXRvcnkyMDM4MjYyMzI=","name":"whereabouts","full_name":"crandles/whereabouts","private":false,"owner":{"login":"crandles","id":190343,"node_id":"MDQ6VXNlcjE5MDM0Mw==","avatar_url":"https://avatars1.githubusercontent.com/u/190343?v=4","gravatar_id":"","url":"https://api.github.com/users/crandles","html_url":"https://github.com/crandles","followers_url":"https://api.github.com/users/crandles/followers","following_url":"https://api.github.com/users/crandles/following{/other_user}","gists_url":"https://api.github.com/users/crandles/gists{/gist_id}","starred_url":"https://api.github.com/users/crandles/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/crandles/subscriptions","organizations_url":"https://api.github.com/users/crandles/orgs","repos_url":"https://api.github.com/users/crandles/repos","events_url":"https://api.github.com/users/crandles/events{/privacy}","received_events_url":"https://api.github.com/users/crandles/received_events","type":"User","site_admin":false},"html_url":"https://github.com/crandles/whereabouts","description":"A CNI IPAM plugin that assigns IP addresses cluster-wide","fork":true,"url":"https://api.github.com/repos/crandles/whereabouts","forks_url":"https://api.github.com/repos/crandles/whereabouts/forks","keys_url":"https://api.github.com/repos/crandles/whereabouts/keys{/key_id}","collaborators_url":"https://api.github.com/repos/crandles/whereabouts/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/crandles/whereabouts/teams","hooks_url":"https://api.github.com/repos/crandles/whereabouts/hooks","issue_events_url":"https://api.github.com/repos/crandles/whereabouts/issues/events{/number}","events_url":"https://api.github.com/repos/crandles/whereabouts/events","assignees_url":"https://api.github.com/repos/crandles/whereabouts/assignees{/user}","branches_url":"https://api.github.com/repos/crandles/whereabouts/branches{/branch}","tags_url":"https://api.github.com/repos/crandles/whereabouts/tags","blobs_url":"https://api.github.com/repos/crandles/whereabouts/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/crandles/whereabouts/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/crandles/whereabouts/git/refs{/sha}","trees_url":"https://api.github.com/repos/crandles/whereabouts/git/trees{/sha}","statuses_url":"https://api.github.com/repos/crandles/whereabouts/statuses/{sha}","languages_url":"https://api.github.com/repos/crandles/whereabouts/languages","stargazers_url":"https://api.github.com/repos/crandles/whereabouts/stargazers","contributors_url":"https://api.github.com/repos/crandles/whereabouts/contributors","subscribers_url":"https://api.github.com/repos/crandles/whereabouts/subscribers","subscription_url":"https://api.github.com/repos/crandles/whereabouts/subscription","commits_url":"https://api.github.com/repos/crandles/whereabouts/commits{/sha}","git_commits_url":"https://api.github.com/repos/crandles/whereabouts/git/commits{/sha}","comments_url":"https://api.github.com/repos/crandles/whereabouts/comments{/number}","issue_comment_url":"https://api.github.com/repos/crandles/whereabouts/issues/comments{/number}","contents_url":"https://api.github.com/repos/crandles/whereabouts/contents/{+path}","compare_url":"https://api.github.com/repos/crandles/whereabouts/compare/{base}...{head}","merges_url":"https://api.github.com/repos/crandles/whereabouts/merges","archive_url":"https://api.github.com/repos/crandles/whereabouts/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/crandles/whereabouts/downloads","issues_url":"https://api.github.com/repos/crandles/whereabouts/issues{/number}","pulls_url":"https://api.github.com/repos/crandles/whereabouts/pulls{/number}","milestones_url":"https://api.github.com/repos/crandles/whereabouts/milestones{/number}","notifications_url":"https://api.github.com/repos/crandles/whereabouts/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/crandles/whereabouts/labels{/name}","releases_url":"https://api.github.com/repos/crandles/whereabouts/releases{/id}","deployments_url":"https://api.github.com/repos/crandles/whereabouts/deployments","created_at":"2019-08-22T15:47:27Z","updated_at":"2019-08-22T15:47:30Z","pushed_at":"2019-10-09T21:45:56Z","git_url":"git://github.com/crandles/whereabouts.git","ssh_url":"git@github.com:crandles/whereabouts.git","clone_url":"https://github.com/crandles/whereabouts.git","svn_url":"https://github.com/crandles/whereabouts","homepage":null,"size":21200,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":0,"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":0,"watchers":0,"default_branch":"master"}},"base":{"label":"dougbtv:master","ref":"master","sha":"ff690e80e06b27cdb821e338b85624664c8989ec","user":{"login":"dougbtv","id":5472189,"node_id":"MDQ6VXNlcjU0NzIxODk=","avatar_url":"https://avatars3.githubusercontent.com/u/5472189?v=4","gravatar_id":"","url":"https://api.github.com/users/dougbtv","html_url":"https://github.com/dougbtv","followers_url":"https://api.github.com/users/dougbtv/followers","following_url":"https://api.github.com/users/dougbtv/following{/other_user}","gists_url":"https://api.github.com/users/dougbtv/gists{/gist_id}","starred_url":"https://api.github.com/users/dougbtv/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dougbtv/subscriptions","organizations_url":"https://api.github.com/users/dougbtv/orgs","repos_url":"https://api.github.com/users/dougbtv/repos","events_url":"https://api.github.com/users/dougbtv/events{/privacy}","received_events_url":"https://api.github.com/users/dougbtv/received_events","type":"User","site_admin":false},"repo":{"id":180179052,"node_id":"MDEwOlJlcG9zaXRvcnkxODAxNzkwNTI=","name":"whereabouts","full_name":"dougbtv/whereabouts","private":false,"owner":{"login":"dougbtv","id":5472189,"node_id":"MDQ6VXNlcjU0NzIxODk=","avatar_url":"https://avatars3.githubusercontent.com/u/5472189?v=4","gravatar_id":"","url":"https://api.github.com/users/dougbtv","html_url":"https://github.com/dougbtv","followers_url":"https://api.github.com/users/dougbtv/followers","following_url":"https://api.github.com/users/dougbtv/following{/other_user}","gists_url":"https://api.github.com/users/dougbtv/gists{/gist_id}","starred_url":"https://api.github.com/users/dougbtv/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dougbtv/subscriptions","organizations_url":"https://api.github.com/users/dougbtv/orgs","repos_url":"https://api.github.com/users/dougbtv/repos","events_url":"https://api.github.com/users/dougbtv/events{/privacy}","received_events_url":"https://api.github.com/users/dougbtv/received_events","type":"User","site_admin":false},"html_url":"https://github.com/dougbtv/whereabouts","description":"A CNI IPAM plugin that assigns IP addresses cluster-wide","fork":false,"url":"https://api.github.com/repos/dougbtv/whereabouts","forks_url":"https://api.github.com/repos/dougbtv/whereabouts/forks","keys_url":"https://api.github.com/repos/dougbtv/whereabouts/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dougbtv/whereabouts/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dougbtv/whereabouts/teams","hooks_url":"https://api.github.com/repos/dougbtv/whereabouts/hooks","issue_events_url":"https://api.github.com/repos/dougbtv/whereabouts/issues/events{/number}","events_url":"https://api.github.com/repos/dougbtv/whereabouts/events","assignees_url":"https://api.github.com/repos/dougbtv/whereabouts/assignees{/user}","branches_url":"https://api.github.com/repos/dougbtv/whereabouts/branches{/branch}","tags_url":"https://api.github.com/repos/dougbtv/whereabouts/tags","blobs_url":"https://api.github.com/repos/dougbtv/whereabouts/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dougbtv/whereabouts/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dougbtv/whereabouts/git/refs{/sha}","trees_url":"https://api.github.com/repos/dougbtv/whereabouts/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dougbtv/whereabouts/statuses/{sha}","languages_url":"https://api.github.com/repos/dougbtv/whereabouts/languages","stargazers_url":"https://api.github.com/repos/dougbtv/whereabouts/stargazers","contributors_url":"https://api.github.com/repos/dougbtv/whereabouts/contributors","subscribers_url":"https://api.github.com/repos/dougbtv/whereabouts/subscribers","subscription_url":"https://api.github.com/repos/dougbtv/whereabouts/subscription","commits_url":"https://api.github.com/repos/dougbtv/whereabouts/commits{/sha}","git_commits_url":"https://api.github.com/repos/dougbtv/whereabouts/git/commits{/sha}","comments_url":"https://api.github.com/repos/dougbtv/whereabouts/comments{/number}","issue_comment_url":"https://api.github.com/repos/dougbtv/whereabouts/issues/comments{/number}","contents_url":"https://api.github.com/repos/dougbtv/whereabouts/contents/{+path}","compare_url":"https://api.github.com/repos/dougbtv/whereabouts/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dougbtv/whereabouts/merges","archive_url":"https://api.github.com/repos/dougbtv/whereabouts/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dougbtv/whereabouts/downloads","issues_url":"https://api.github.com/repos/dougbtv/whereabouts/issues{/number}","pulls_url":"https://api.github.com/repos/dougbtv/whereabouts/pulls{/number}","milestones_url":"https://api.github.com/repos/dougbtv/whereabouts/milestones{/number}","notifications_url":"https://api.github.com/repos/dougbtv/whereabouts/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dougbtv/whereabouts/labels{/name}","releases_url":"https://api.github.com/repos/dougbtv/whereabouts/releases{/id}","deployments_url":"https://api.github.com/repos/dougbtv/whereabouts/deployments","created_at":"2019-04-08T15:29:54Z","updated_at":"2019-10-09T14:27:07Z","pushed_at":"2019-10-09T14:27:05Z","git_url":"git://github.com/dougbtv/whereabouts.git","ssh_url":"git@github.com:dougbtv/whereabouts.git","clone_url":"https://github.com/dougbtv/whereabouts.git","svn_url":"https://github.com/dougbtv/whereabouts","homepage":null,"size":21214,"stargazers_count":14,"watchers_count":14,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":9,"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":3,"open_issues":9,"watchers":14,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dougbtv/whereabouts/pulls/20"},"html":{"href":"https://github.com/dougbtv/whereabouts/pull/20"},"issue":{"href":"https://api.github.com/repos/dougbtv/whereabouts/issues/20"},"comments":{"href":"https://api.github.com/repos/dougbtv/whereabouts/issues/20/comments"},"review_comments":{"href":"https://api.github.com/repos/dougbtv/whereabouts/pulls/20/comments"},"review_comment":{"href":"https://api.github.com/repos/dougbtv/whereabouts/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dougbtv/whereabouts/pulls/20/commits"},"statuses":{"href":"https://api.github.com/repos/dougbtv/whereabouts/statuses/73ffd2b5f34793b73e1cec255a6f13615511cfc8"}},"author_association":"CONTRIBUTOR","merged":false,"mergeable":null,"rebaseable":null,"mergeable_state":"unknown","merged_by":null,"comments":0,"review_comments":0,"maintainer_can_modify":true,"commits":1,"additions":448085,"deletions":21475,"changed_files":1679}}
other: {"actor":{"display_login":"crandles"}}