{"action":"created","comment":{"url":"https://api.github.com/repos/openshift/origin/pulls/comments/29059852","id":29059852,"diff_hunk":"@@ -0,0 +1,173 @@\n+package ipfailover\n+\n+import (\n+\t\"fmt\"\n+\t\"io\"\n+\n+\tcmdutil \"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util\"\n+\t\"github.com/golang/glog\"\n+\t\"github.com/spf13/cobra\"\n+\n+\t\"github.com/openshift/origin/pkg/cmd/util/clientcmd\"\n+\t\"github.com/openshift/origin/pkg/cmd/util/variable\"\n+\tipf \"github.com/openshift/origin/pkg/ipfailover\"\n+\t\"github.com/openshift/origin/pkg/ipfailover/keepalived\"\n+)\n+\n+const shortDesc = \"Configure or view IP Failover configuration\"\n+const description = `\n+Configure or view IP Failover configuration\n+\n+This command helps to setup IP Failover configuration for an OpenShift\n+environment. An administrator can configure IP failover on an entire\n+cluster or as would normally be the case on a subset of nodes (as defined\n+via a labelled selector).\n+\n+If an IP failover configuration does not exist with the given name,\n+the --create flag can be passed to create a deployment configuration and\n+service that will provide IP failover capability. If you are running in\n+production, it is recommended that the labelled selector for the nodes\n+matches atleast 2 nodes to ensure you have failover protection and that\n+you provide a --replicas=<n> value that matches the number of nodes for\n+the given labelled selector.\n+\n+\n+Examples:\n+  Check the default IP failover configuration (\"ipfailover\"):\n+\n+  $ %[1]s %[2]s\n+\n+  See what the IP failover configuration would look like if it is created:\n+\n+  $ %[1]s %[2]s -o json\n+\n+  Create an IP failover configuration if it does not already exist:\n+\n+  $ %[1]s %[2]s ipf --virtual-ips=\"10.1.1.1-4\" --create\n+\n+  Create an IP failover configuration on a selection of nodes labelled\n+  \"router=us-west-ha\" (on 4 nodes with 7 virtual IPs monitoring a service\n+  listening on port 80 (aka the OpenShift router process).\n+\n+  $ %[1]s %[2]s ipfailover --selector=\"router=us-west-ha\" --virtual-ips=\"1.2.3.4,10.1.1.100-104,5.6.7.8\" --watch-port=80 --replicas=4 --create\n+\n+  Use a different IP failover config image and see the configuration:\n+\n+  $ %[1]s %[2]s ipf-alt --selector=\"jack=the-vipper\" --virtual-ips=\"1.2.3.4\" -o yaml --images=myrepo/myipfailover:mytag\n+\n+ALPHA: This command is currently being actively developed. It is intended\n+       to simplify the administrative tasks of setting up a highly\n+       available failover configuration.\n+`\n+\n+func NewCmdIPFailoverConfig(f *clientcmd.Factory, parentName, name string, out io.Writer) *cobra.Command {\n+\toptions := &ipf.IPFailoverConfigCmdOptions{\n+\t\tImageTemplate:    variable.NewDefaultImageTemplate(),\n+\t\tSelector:         ipf.DefaultSelector,\n+\t\tServicePort:      ipf.DefaultServicePort,\n+\t\tWatchPort:        ipf.DefaultWatchPort,\n+\t\tNetworkInterface: ipf.DefaultInterface,\n+\t\tReplicas:         1,\n+\t}\n+\n+\tcmd := &cobra.Command{\n+\t\tUse:   fmt.Sprintf(\"%s [<name>]\", name),\n+\t\tShort: shortDesc,\n+\t\tLong:  fmt.Sprintf(description, parentName, name),\n+\t\tRun: func(cmd *cobra.Command, args []string) {","path":"pkg/cmd/experimental/ipfailover/ipfailover.go","position":77,"original_position":77,"commit_id":"15bc8ba46f1b43bd0295b7a16b82931735b01e1a","original_commit_id":"15bc8ba46f1b43bd0295b7a16b82931735b01e1a","user":{"login":"smarterclayton","id":1163175,"avatar_url":"https://avatars.githubusercontent.com/u/1163175?v=3","gravatar_id":"","url":"https://api.github.com/users/smarterclayton","html_url":"https://github.com/smarterclayton","followers_url":"https://api.github.com/users/smarterclayton/followers","following_url":"https://api.github.com/users/smarterclayton/following{/other_user}","gists_url":"https://api.github.com/users/smarterclayton/gists{/gist_id}","starred_url":"https://api.github.com/users/smarterclayton/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/smarterclayton/subscriptions","organizations_url":"https://api.github.com/users/smarterclayton/orgs","repos_url":"https://api.github.com/users/smarterclayton/repos","events_url":"https://api.github.com/users/smarterclayton/events{/privacy}","received_events_url":"https://api.github.com/users/smarterclayton/received_events","type":"User","site_admin":false},"body":"This command needs to follow the pattern for the rest of our CLI commands - a RunProcess method that returns an error with cmdutil.CheckErr(err).  Also, you should always be returning errors from functions and glog fatal is reserved for a very few specific locations.","created_at":"2015-04-24T15:45:07Z","updated_at":"2015-04-24T15:45:07Z","html_url":"https://github.com/openshift/origin/pull/1807#discussion_r29059852","pull_request_url":"https://api.github.com/repos/openshift/origin/pulls/1807","_links":{"self":{"href":"https://api.github.com/repos/openshift/origin/pulls/comments/29059852"},"html":{"href":"https://github.com/openshift/origin/pull/1807#discussion_r29059852"},"pull_request":{"href":"https://api.github.com/repos/openshift/origin/pulls/1807"}}},"pull_request":{"url":"https://api.github.com/repos/openshift/origin/pulls/1807","id":33632869,"html_url":"https://github.com/openshift/origin/pull/1807","diff_url":"https://github.com/openshift/origin/pull/1807.diff","patch_url":"https://github.com/openshift/origin/pull/1807.patch","issue_url":"https://api.github.com/repos/openshift/origin/issues/1807","number":1807,"state":"open","locked":false,"title":"HA config implementation based on proposal in PR 1730","user":{"login":"ramr","id":928868,"avatar_url":"https://avatars.githubusercontent.com/u/928868?v=3","gravatar_id":"","url":"https://api.github.com/users/ramr","html_url":"https://github.com/ramr","followers_url":"https://api.github.com/users/ramr/followers","following_url":"https://api.github.com/users/ramr/following{/other_user}","gists_url":"https://api.github.com/users/ramr/gists{/gist_id}","starred_url":"https://api.github.com/users/ramr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ramr/subscriptions","organizations_url":"https://api.github.com/users/ramr/orgs","repos_url":"https://api.github.com/users/ramr/repos","events_url":"https://api.github.com/users/ramr/events{/privacy}","received_events_url":"https://api.github.com/users/ramr/received_events","type":"User","site_admin":false},"body":"Initial cut of the HA config implementation based on the proposal in https://github.com/openshift/origin/pull/1730\r\n\r\nExample usage: \r\n```  \r\n#  label some nodes router=us-west-ha\r\nopenshift kube label node minion-1 \"router=us-west-ha\"  \r\nopenshift kube label node minion-2 \"router=us-west-ha\"  \r\n\r\n#  create router and ha sidecar on the labelled nodes.  \r\nopenshift ex router --create --labels=\"router=us-west-ha\" --credentials=\"${KUBECONFIG}\" --replicas=2  \r\nopenshift ex ha-config har --virtual-ips=10.0.2.100-102 --credentials=$KUBECONFIG  --replicas=2 -w 80 --latest-images --selector=\"router=us-west-ha\" --create  \r\n```\r\n\r\nFYI, @smarterclayton @pweil-   PTAL and  let me know if this approach seems okay. \r\n\r\nThis PR is dependent on the proposal PR - so don't merge till https://github.com/openshift/origin/pull/1730  is merged in. \r\nSo there's probably going to be duplicate cruft  in here (the cleaned up version of the keepalived demo pieces).  \r\n\r\nAlso there is more work to do to handle nodes joining/leaving the cluster and on their labels changing. \r\n","created_at":"2015-04-20T03:10:47Z","updated_at":"2015-04-24T15:45:07Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b9be0515e0a03e3b302987d95a7284028ea8288d","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/openshift/origin/pulls/1807/commits","review_comments_url":"https://api.github.com/repos/openshift/origin/pulls/1807/comments","review_comment_url":"https://api.github.com/repos/openshift/origin/pulls/comments{/number}","comments_url":"https://api.github.com/repos/openshift/origin/issues/1807/comments","statuses_url":"https://api.github.com/repos/openshift/origin/statuses/15bc8ba46f1b43bd0295b7a16b82931735b01e1a","head":{"label":"ramr:haconfig","ref":"haconfig","sha":"15bc8ba46f1b43bd0295b7a16b82931735b01e1a","user":{"login":"ramr","id":928868,"avatar_url":"https://avatars.githubusercontent.com/u/928868?v=3","gravatar_id":"","url":"https://api.github.com/users/ramr","html_url":"https://github.com/ramr","followers_url":"https://api.github.com/users/ramr/followers","following_url":"https://api.github.com/users/ramr/following{/other_user}","gists_url":"https://api.github.com/users/ramr/gists{/gist_id}","starred_url":"https://api.github.com/users/ramr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ramr/subscriptions","organizations_url":"https://api.github.com/users/ramr/orgs","repos_url":"https://api.github.com/users/ramr/repos","events_url":"https://api.github.com/users/ramr/events{/privacy}","received_events_url":"https://api.github.com/users/ramr/received_events","type":"User","site_admin":false},"repo":{"id":31566423,"name":"origin","full_name":"ramr/origin","owner":{"login":"ramr","id":928868,"avatar_url":"https://avatars.githubusercontent.com/u/928868?v=3","gravatar_id":"","url":"https://api.github.com/users/ramr","html_url":"https://github.com/ramr","followers_url":"https://api.github.com/users/ramr/followers","following_url":"https://api.github.com/users/ramr/following{/other_user}","gists_url":"https://api.github.com/users/ramr/gists{/gist_id}","starred_url":"https://api.github.com/users/ramr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ramr/subscriptions","organizations_url":"https://api.github.com/users/ramr/orgs","repos_url":"https://api.github.com/users/ramr/repos","events_url":"https://api.github.com/users/ramr/events{/privacy}","received_events_url":"https://api.github.com/users/ramr/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ramr/origin","description":"OpenShift 3 - build, deploy, and manage your applications with Docker and Kubernetes","fork":true,"url":"https://api.github.com/repos/ramr/origin","forks_url":"https://api.github.com/repos/ramr/origin/forks","keys_url":"https://api.github.com/repos/ramr/origin/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ramr/origin/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ramr/origin/teams","hooks_url":"https://api.github.com/repos/ramr/origin/hooks","issue_events_url":"https://api.github.com/repos/ramr/origin/issues/events{/number}","events_url":"https://api.github.com/repos/ramr/origin/events","assignees_url":"https://api.github.com/repos/ramr/origin/assignees{/user}","branches_url":"https://api.github.com/repos/ramr/origin/branches{/branch}","tags_url":"https://api.github.com/repos/ramr/origin/tags","blobs_url":"https://api.github.com/repos/ramr/origin/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ramr/origin/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ramr/origin/git/refs{/sha}","trees_url":"https://api.github.com/repos/ramr/origin/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ramr/origin/statuses/{sha}","languages_url":"https://api.github.com/repos/ramr/origin/languages","stargazers_url":"https://api.github.com/repos/ramr/origin/stargazers","contributors_url":"https://api.github.com/repos/ramr/origin/contributors","subscribers_url":"https://api.github.com/repos/ramr/origin/subscribers","subscription_url":"https://api.github.com/repos/ramr/origin/subscription","commits_url":"https://api.github.com/repos/ramr/origin/commits{/sha}","git_commits_url":"https://api.github.com/repos/ramr/origin/git/commits{/sha}","comments_url":"https://api.github.com/repos/ramr/origin/comments{/number}","issue_comment_url":"https://api.github.com/repos/ramr/origin/issues/comments{/number}","contents_url":"https://api.github.com/repos/ramr/origin/contents/{+path}","compare_url":"https://api.github.com/repos/ramr/origin/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ramr/origin/merges","archive_url":"https://api.github.com/repos/ramr/origin/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ramr/origin/downloads","issues_url":"https://api.github.com/repos/ramr/origin/issues{/number}","pulls_url":"https://api.github.com/repos/ramr/origin/pulls{/number}","milestones_url":"https://api.github.com/repos/ramr/origin/milestones{/number}","notifications_url":"https://api.github.com/repos/ramr/origin/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ramr/origin/labels{/name}","releases_url":"https://api.github.com/repos/ramr/origin/releases{/id}","created_at":"2015-03-02T22:18:42Z","updated_at":"2015-03-30T17:04:15Z","pushed_at":"2015-04-22T19:01:49Z","git_url":"git://github.com/ramr/origin.git","ssh_url":"git@github.com:ramr/origin.git","clone_url":"https://github.com/ramr/origin.git","svn_url":"https://github.com/ramr/origin","homepage":"https://openshift.github.io","size":79204,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":false,"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":"openshift:master","ref":"master","sha":"f8f02726e0078baa0fe04727daa89c1a1fa04104","user":{"login":"openshift","id":792337,"avatar_url":"https://avatars.githubusercontent.com/u/792337?v=3","gravatar_id":"","url":"https://api.github.com/users/openshift","html_url":"https://github.com/openshift","followers_url":"https://api.github.com/users/openshift/followers","following_url":"https://api.github.com/users/openshift/following{/other_user}","gists_url":"https://api.github.com/users/openshift/gists{/gist_id}","starred_url":"https://api.github.com/users/openshift/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openshift/subscriptions","organizations_url":"https://api.github.com/users/openshift/orgs","repos_url":"https://api.github.com/users/openshift/repos","events_url":"https://api.github.com/users/openshift/events{/privacy}","received_events_url":"https://api.github.com/users/openshift/received_events","type":"Organization","site_admin":false},"repo":{"id":22442668,"name":"origin","full_name":"openshift/origin","owner":{"login":"openshift","id":792337,"avatar_url":"https://avatars.githubusercontent.com/u/792337?v=3","gravatar_id":"","url":"https://api.github.com/users/openshift","html_url":"https://github.com/openshift","followers_url":"https://api.github.com/users/openshift/followers","following_url":"https://api.github.com/users/openshift/following{/other_user}","gists_url":"https://api.github.com/users/openshift/gists{/gist_id}","starred_url":"https://api.github.com/users/openshift/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openshift/subscriptions","organizations_url":"https://api.github.com/users/openshift/orgs","repos_url":"https://api.github.com/users/openshift/repos","events_url":"https://api.github.com/users/openshift/events{/privacy}","received_events_url":"https://api.github.com/users/openshift/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/openshift/origin","description":"OpenShift 3 - build, deploy, and manage your applications with Docker and Kubernetes","fork":false,"url":"https://api.github.com/repos/openshift/origin","forks_url":"https://api.github.com/repos/openshift/origin/forks","keys_url":"https://api.github.com/repos/openshift/origin/keys{/key_id}","collaborators_url":"https://api.github.com/repos/openshift/origin/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/openshift/origin/teams","hooks_url":"https://api.github.com/repos/openshift/origin/hooks","issue_events_url":"https://api.github.com/repos/openshift/origin/issues/events{/number}","events_url":"https://api.github.com/repos/openshift/origin/events","assignees_url":"https://api.github.com/repos/openshift/origin/assignees{/user}","branches_url":"https://api.github.com/repos/openshift/origin/branches{/branch}","tags_url":"https://api.github.com/repos/openshift/origin/tags","blobs_url":"https://api.github.com/repos/openshift/origin/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/openshift/origin/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/openshift/origin/git/refs{/sha}","trees_url":"https://api.github.com/repos/openshift/origin/git/trees{/sha}","statuses_url":"https://api.github.com/repos/openshift/origin/statuses/{sha}","languages_url":"https://api.github.com/repos/openshift/origin/languages","stargazers_url":"https://api.github.com/repos/openshift/origin/stargazers","contributors_url":"https://api.github.com/repos/openshift/origin/contributors","subscribers_url":"https://api.github.com/repos/openshift/origin/subscribers","subscription_url":"https://api.github.com/repos/openshift/origin/subscription","commits_url":"https://api.github.com/repos/openshift/origin/commits{/sha}","git_commits_url":"https://api.github.com/repos/openshift/origin/git/commits{/sha}","comments_url":"https://api.github.com/repos/openshift/origin/comments{/number}","issue_comment_url":"https://api.github.com/repos/openshift/origin/issues/comments{/number}","contents_url":"https://api.github.com/repos/openshift/origin/contents/{+path}","compare_url":"https://api.github.com/repos/openshift/origin/compare/{base}...{head}","merges_url":"https://api.github.com/repos/openshift/origin/merges","archive_url":"https://api.github.com/repos/openshift/origin/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/openshift/origin/downloads","issues_url":"https://api.github.com/repos/openshift/origin/issues{/number}","pulls_url":"https://api.github.com/repos/openshift/origin/pulls{/number}","milestones_url":"https://api.github.com/repos/openshift/origin/milestones{/number}","notifications_url":"https://api.github.com/repos/openshift/origin/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/openshift/origin/labels{/name}","releases_url":"https://api.github.com/repos/openshift/origin/releases{/id}","created_at":"2014-07-30T20:04:05Z","updated_at":"2015-04-24T14:51:28Z","pushed_at":"2015-04-24T15:44:06Z","git_url":"git://github.com/openshift/origin.git","ssh_url":"git@github.com:openshift/origin.git","clone_url":"https://github.com/openshift/origin.git","svn_url":"https://github.com/openshift/origin","homepage":"http://www.openshift.org","size":137093,"stargazers_count":383,"watchers_count":383,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":192,"mirror_url":null,"open_issues_count":232,"forks":192,"open_issues":232,"watchers":383,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/openshift/origin/pulls/1807"},"html":{"href":"https://github.com/openshift/origin/pull/1807"},"issue":{"href":"https://api.github.com/repos/openshift/origin/issues/1807"},"comments":{"href":"https://api.github.com/repos/openshift/origin/issues/1807/comments"},"review_comments":{"href":"https://api.github.com/repos/openshift/origin/pulls/1807/comments"},"review_comment":{"href":"https://api.github.com/repos/openshift/origin/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/openshift/origin/pulls/1807/commits"},"statuses":{"href":"https://api.github.com/repos/openshift/origin/statuses/15bc8ba46f1b43bd0295b7a16b82931735b01e1a"}}}}