{"action":"created","comment":{"url":"https://api.github.com/repos/openshift/origin/pulls/comments/29060060","id":29060060,"diff_hunk":"@@ -0,0 +1,130 @@\n+package keepalived\n+\n+import (\n+\t\"io\"\n+\t\"os\"\n+\t\"strings\"\n+\n+\tkapi \"github.com/GoogleCloudPlatform/kubernetes/pkg/api\"\n+\t\"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors\"\n+\t\"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime\"\n+\t\"github.com/golang/glog\"\n+\n+\t\"github.com/openshift/origin/pkg/cmd/util/clientcmd\"\n+\tconfigcmd \"github.com/openshift/origin/pkg/config/cmd\"\n+\t\"github.com/openshift/origin/pkg/generate/app\"\n+\t\"github.com/openshift/origin/pkg/ipfailover\"\n+)\n+\n+//  IP Failover configurator plugin for keepalived sidecar.\n+type KeepalivedPlugin struct {\n+\tName    string\n+\tFactory *clientcmd.Factory\n+\tOptions *ipfailover.IPFailoverConfigCmdOptions\n+}\n+\n+//  Create a new IPFailoverConfigurator (keepalived) plugin instance.\n+func NewIPFailoverConfiguratorPlugin(name string, f *clientcmd.Factory, options *ipfailover.IPFailoverConfigCmdOptions) (*KeepalivedPlugin, error) {\n+\tglog.V(4).Infof(\"Creating new KeepAlived plugin: %q\", name)\n+\n+\tp := &KeepalivedPlugin{\n+\t\tName:    name,\n+\t\tFactory: f,\n+\t\tOptions: options,\n+\t}\n+\n+\treturn p, nil\n+}\n+\n+//  Get the port to monitor for the IP Failover configuration.\n+func (p *KeepalivedPlugin) GetWatchPort() int {\n+\tport := p.Options.WatchPort\n+\tif port < 1 {\n+\t\tport = ipfailover.DefaultWatchPort\n+\t}\n+\n+\tglog.V(4).Infof(\"KeepAlived IP Failover config: %q - WatchPort: %+v\", p.Name, port)\n+\n+\treturn port\n+}\n+\n+//  Get the selector associated with this IP Failover configurator plugin.\n+func (p *KeepalivedPlugin) GetSelector() map[string]string {\n+\tif p.Options.Selector == ipfailover.DefaultSelector {\n+\t\treturn map[string]string{ipfailover.DefaultName: p.Name}\n+\t}\n+\n+\tlabels, remove, err := app.LabelsFromSpec(strings.Split(p.Options.Selector, \",\"))\n+\tif err != nil {\n+\t\tglog.Fatal(err)\n+\t}\n+\n+\tif len(remove) > 0 {\n+\t\tglog.Fatalf(\"You may not pass negative labels in %q\", p.Options.Selector)\n+\t}\n+\n+\tglog.V(4).Infof(\"KeepAlived IP Failover config: %q - selector: %+v\", p.Name, labels)\n+\n+\treturn labels\n+}\n+\n+//  Get the namespace associated with this IP Failover configurator plugin.\n+func (p *KeepalivedPlugin) GetNamespace() string {\n+\tnamespace, err := p.Factory.OpenShiftClientConfig.Namespace()\n+\tif err != nil {\n+\t\tglog.Fatalf(\"Error get OS client config: %v\", err)\n+\t}\n+\n+\tglog.V(4).Infof(\"KeepAlived IP Failover config: %q - namespace: %q\", p.Name, namespace)\n+\n+\treturn namespace\n+}\n+\n+//  Get the service associated with this IP Failover configurator plugin.\n+func (p *KeepalivedPlugin) GetService() *kapi.Service {\n+\t_, kClient, err := p.Factory.Clients()\n+\tif err != nil {\n+\t\tglog.Fatalf(\"Error getting client: %v\", err)\n+\t}\n+\n+\tnamespace := p.GetNamespace()\n+\tservice, err := kClient.Services(namespace).Get(p.Name)\n+\tif err != nil {\n+\t\tif errors.IsNotFound(err) {\n+\t\t\tglog.V(4).Infof(\"KeepAlived IP Failover config: %s - no service found\", p.Name)\n+\t\t\treturn nil\n+\t\t}\n+\t\tglog.Fatalf(\"Error getting KeepAlived IP Failover config service %q: %v\", p.Name, err)\n+\t}\n+\n+\tglog.V(4).Infof(\"KeepAlived IP Failover config: %q service: %+v\", p.Name, service)\n+\n+\treturn service\n+}\n+\n+//  Generate the config and services for this IP Failover configuration plugin.\n+func (p *KeepalivedPlugin) Generate() *kapi.List {\n+\tdc := GenerateDeploymentConfig(p.Name, p.Options, p.GetSelector())\n+\tobjects := []runtime.Object{dc}\n+\n+\tservices := &kapi.List{Items: app.AddServices(objects)}\n+\tglog.V(4).Infof(\"KeepAlived IP Failover config: %q - generated services: %+v\", p.Name, services)\n+\n+\treturn services\n+}\n+\n+//  Create the config and services associated with this IP Failover configuration.\n+func (p *KeepalivedPlugin) Create(out io.Writer) {\n+\tnamespace := p.GetNamespace()\n+\n+\tbulk := configcmd.Bulk{\n+\t\tFactory: p.Factory.Factory,\n+\t\tAfter:   configcmd.NewPrintNameOrErrorAfter(out, os.Stderr),\n+\t}\n+\n+\tif errs := bulk.Create(p.Generate(), namespace); len(errs) != 0 {\n+\t\tglog.Fatalf(\"Error creating config: %+v\", errs)","path":"pkg/ipfailover/keepalived/plugin.go","position":126,"original_position":126,"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":"return error","created_at":"2015-04-24T15:47:22Z","updated_at":"2015-04-24T15:47:22Z","html_url":"https://github.com/openshift/origin/pull/1807#discussion_r29060060","pull_request_url":"https://api.github.com/repos/openshift/origin/pulls/1807","_links":{"self":{"href":"https://api.github.com/repos/openshift/origin/pulls/comments/29060060"},"html":{"href":"https://github.com/openshift/origin/pull/1807#discussion_r29060060"},"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:47:22Z","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:47:19Z","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"}}}}