{"action":"created","comment":{"url":"https://api.github.com/repos/openshift/cluster-operator/pulls/comments/188953165","pull_request_review_id":121035092,"id":188953165,"diff_hunk":"@@ -0,0 +1,301 @@\n+/*\n+Copyright 2018 The Kubernetes Authors.\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 clusterapimachine\n+\n+import (\n+\t\"fmt\"\n+\t\"time\"\n+\n+\t\"k8s.io/apimachinery/pkg/api/errors\"\n+\t//metav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n+\tapiequality \"k8s.io/apimachinery/pkg/api/equality\"\n+\tutilruntime \"k8s.io/apimachinery/pkg/util/runtime\"\n+\t\"k8s.io/apimachinery/pkg/util/wait\"\n+\tkubeclientset \"k8s.io/client-go/kubernetes\"\n+\tv1core \"k8s.io/client-go/kubernetes/typed/core/v1\"\n+\t\"k8s.io/client-go/tools/cache\"\n+\t\"k8s.io/client-go/tools/record\"\n+\t\"k8s.io/client-go/util/workqueue\"\n+\n+\t\"github.com/golang/glog\"\n+\tlog \"github.com/sirupsen/logrus\"\n+\n+\t\"github.com/openshift/cluster-operator/pkg/kubernetes/pkg/util/metrics\"\n+\n+\t//clustopv1 \"github.com/openshift/cluster-operator/pkg/apis/clusteroperator/v1alpha1\"\n+\tclustopclientset \"github.com/openshift/cluster-operator/pkg/client/clientset_generated/clientset\"\n+\tclustopinformers \"github.com/openshift/cluster-operator/pkg/client/informers_generated/externalversions/clusteroperator/v1alpha1\"\n+\tclustoplisters \"github.com/openshift/cluster-operator/pkg/client/listers_generated/clusteroperator/v1alpha1\"\n+\t\"github.com/openshift/cluster-operator/pkg/controller\"\n+\tclustoplog \"github.com/openshift/cluster-operator/pkg/logging\"\n+\n+\tcapiv1 \"sigs.k8s.io/cluster-api/pkg/apis/cluster/v1alpha1\"\n+\tcapiclientset \"sigs.k8s.io/cluster-api/pkg/client/clientset_generated/clientset\"\n+\tcapiinformers \"sigs.k8s.io/cluster-api/pkg/client/informers_generated/externalversions/cluster/v1alpha1\"\n+\tcapilisters \"sigs.k8s.io/cluster-api/pkg/client/listers_generated/cluster/v1alpha1\"\n+)\n+\n+const (\n+\tcontrollerLogName = \"capi-machine\"\n+\n+\tclusterNameLabel = \"clusteroperator.openshift.io/cluster\"\n+)\n+\n+// NewController returns a new controller.\n+func NewController(\n+\tclusterInformer capiinformers.ClusterInformer,\n+\tmsInformer capiinformers.MachineInformer,\n+\tcvInformer clustopinformers.ClusterVersionInformer,\n+\tkubeClient kubeclientset.Interface,\n+\tclustopClient clustopclientset.Interface,\n+\tcapiClient capiclientset.Interface) *Controller {\n+\n+\teventBroadcaster := record.NewBroadcaster()\n+\teventBroadcaster.StartLogging(glog.Infof)\n+\t// TODO: remove the wrapper when every clients have moved to use the clientset.\n+\teventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.CoreV1().RESTClient()).Events(\"\")})\n+\n+\tif kubeClient != nil && kubeClient.CoreV1().RESTClient().GetRateLimiter() != nil {\n+\t\tmetrics.RegisterMetricAndTrackRateLimiterUsage(\"clusteroperator_capi_machine_controller\", kubeClient.CoreV1().RESTClient().GetRateLimiter())\n+\t}\n+\n+\tlogger := log.WithField(\"controller\", controllerLogName)\n+\tc := &Controller{\n+\t\tclustopClient:  clustopClient,\n+\t\tcapiClient:     capiClient,\n+\t\tclustersLister: clusterInformer.Lister(),\n+\t\tcvLister:       cvInformer.Lister(),\n+\t\tqueue:          workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), \"capi-machine\"),\n+\t\tlogger:         logger,\n+\t}\n+\n+\tmsInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{\n+\t\tAddFunc:    c.addMachine,\n+\t\tUpdateFunc: c.updateMachine,\n+\t\tDeleteFunc: c.deleteMachine,\n+\t})\n+\tc.machinesLister = msInformer.Lister()\n+\tc.machinesSynced = msInformer.Informer().HasSynced\n+\n+\tc.syncHandler = c.syncMachine\n+\tc.enqueueMachine = c.enqueue\n+\n+\treturn c\n+}\n+\n+// Controller manages clusters.\n+type Controller struct {\n+\tclustopClient clustopclientset.Interface\n+\tcapiClient    capiclientset.Interface\n+\n+\t// To allow injection of syncMachine for testing.\n+\tsyncHandler func(hKey string) error\n+\t// used for unit testing\n+\tenqueueMachine func(cluster *capiv1.Machine)\n+\n+\t// clustersLister is able to list/get clusters and is populated by the shared informer passed to\n+\t// NewController.\n+\tclustersLister capilisters.ClusterLister\n+\n+\t// machinesLister is able to list/get machines and is populated by the shared informer passed to\n+\t// NewController.\n+\tmachinesLister capilisters.MachineLister\n+\t// machinesSynced returns true if the machineset shared informer has been synced at least once.\n+\t// Added as a member to the struct to allow injection for testing.\n+\tmachinesSynced cache.InformerSynced\n+\n+\t// cvLister is able to list/get cluster versions and is populated by the shared infromer passed\n+\t// to NewController.\n+\tcvLister clustoplisters.ClusterVersionLister\n+\n+\t// Clusters that need to be synced\n+\tqueue workqueue.RateLimitingInterface\n+\n+\tlogger log.FieldLogger\n+}\n+\n+func (c *Controller) addMachine(obj interface{}) {\n+\tm := obj.(*capiv1.Machine)\n+\tclustoplog.WithClusterAPIMachine(c.logger, m).Debugf(\"adding machine\")\n+\tc.enqueueMachine(m)\n+}\n+\n+func (c *Controller) updateMachine(old, cur interface{}) {\n+\toldM := old.(*capiv1.Machine)\n+\tnewM := cur.(*capiv1.Machine)\n+\tclustoplog.WithClusterAPIMachine(c.logger, oldM).Debugf(\"updating machine\")\n+\tc.enqueueMachine(newM)\n+}\n+\n+func (c *Controller) deleteMachine(obj interface{}) {\n+\tm, ok := obj.(*capiv1.Machine)\n+\tif !ok {\n+\t\ttombstone, ok := obj.(cache.DeletedFinalStateUnknown)\n+\t\tif !ok {\n+\t\t\tutilruntime.HandleError(fmt.Errorf(\"Couldn't get object from tombstone %#v\", obj))\n+\t\t\treturn\n+\t\t}\n+\t\tm, ok = tombstone.Obj.(*capiv1.Machine)\n+\t\tif !ok {\n+\t\t\tutilruntime.HandleError(fmt.Errorf(\"Tombstone contained object that is not a Machine %#v\", obj))\n+\t\t\treturn\n+\t\t}\n+\t}\n+\tclustoplog.WithClusterAPIMachine(c.logger, m).Debugf(\"deleting machine\")\n+\tc.enqueueMachine(m)\n+}\n+\n+// Run runs c; will not return until stopCh is closed. workers determines how\n+// many machines will be handled in parallel.\n+func (c *Controller) Run(workers int, stopCh <-chan struct{}) {\n+\tdefer utilruntime.HandleCrash()\n+\tdefer c.queue.ShutDown()\n+\n+\tc.logger.Infof(\"starting %s controller\", controllerLogName)\n+\tdefer c.logger.Infof(\"shutting down %s controller\", controllerLogName)\n+\n+\tif !controller.WaitForCacheSync(\"capi-machine\", stopCh, c.machinesSynced) {\n+\t\tc.logger.Info(\"waiting for caches to sync\")\n+\t\treturn\n+\t}\n+\n+\tfor i := 0; i < workers; i++ {\n+\t\tgo wait.Until(c.worker, time.Second, stopCh)\n+\t}\n+\n+\t<-stopCh\n+}\n+\n+func (c *Controller) enqueue(ms *capiv1.Machine) {\n+\tkey, err := controller.KeyFunc(ms)\n+\tif err != nil {\n+\t\tutilruntime.HandleError(fmt.Errorf(\"Couldn't get key for object %#v: %v\", ms, err))\n+\t\treturn\n+\t}\n+\n+\tc.queue.Add(key)\n+}\n+\n+// worker runs a worker thread that just dequeues items, processes them, and marks them done.\n+// It enforces that the syncHandler is never invoked concurrently with the same key.\n+func (c *Controller) worker() {\n+\tfor c.processNextWorkItem() {\n+\t}\n+}\n+\n+func (c *Controller) processNextWorkItem() bool {\n+\tkey, quit := c.queue.Get()\n+\tif quit {\n+\t\treturn false\n+\t}\n+\tdefer c.queue.Done(key)\n+\n+\terr := c.syncHandler(key.(string))\n+\tif err == nil {\n+\t\tc.queue.Forget(key)\n+\t\treturn true\n+\t}\n+\n+\tutilruntime.HandleError(fmt.Errorf(\"Sync %q failed with %v\", key, err))\n+\tc.queue.AddRateLimited(key)\n+\n+\treturn true\n+}\n+\n+// syncMachine will sync the machine with the given key.\n+// This function is not meant to be invoked concurrently with the same key.\n+func (c *Controller) syncMachine(key string) error {\n+\tstartTime := time.Now()\n+\tc.logger.WithField(\"key\", key).Debug(\"syncing machine\")\n+\tdefer func() {\n+\t\tc.logger.WithFields(log.Fields{\n+\t\t\t\"key\":      key,\n+\t\t\t\"duration\": time.Now().Sub(startTime),\n+\t\t}).Debug(\"finished syncing machine\")\n+\t}()\n+\n+\tnamespace, name, err := cache.SplitMetaNamespaceKey(key)\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\n+\tmachine, err := c.machinesLister.Machines(namespace).Get(name)\n+\tif errors.IsNotFound(err) {\n+\t\tc.logger.WithField(\"key\", key).Debug(\"machine has been deleted\")\n+\t\treturn nil\n+\t}\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\n+\tmLog := clustoplog.WithClusterAPIMachine(c.logger, machine)\n+\tmLog.Debugf(\"found machine\")\n+\n+\t// Lookup the cluster for this machine:\n+\tclusterName, ok := machine.Labels[clusterNameLabel]\n+\tif !ok {\n+\t\treturn fmt.Errorf(\"no cluster label set on machine\")\n+\t}\n+\tcluster, err := c.clustersLister.Clusters(namespace).Get(clusterName)\n+\tif errors.IsNotFound(err) {\n+\t\tmLog.WithField(\"cluster\", clusterName).Errorf(\"no cluster found for machine\")\n+\t\treturn nil","path":"pkg/controller/clusterapimachine/machine_controller.go","position":277,"original_position":256,"commit_id":"d1ce6f2ad1b31f38da6d4cb45abaae001dd3fd04","original_commit_id":"867c61e1072a999089f2ad7e370744c94a2f4cf4","user":{"login":"staebler","id":30120115,"avatar_url":"https://avatars1.githubusercontent.com/u/30120115?v=4","gravatar_id":"","url":"https://api.github.com/users/staebler","html_url":"https://github.com/staebler","followers_url":"https://api.github.com/users/staebler/followers","following_url":"https://api.github.com/users/staebler/following{/other_user}","gists_url":"https://api.github.com/users/staebler/gists{/gist_id}","starred_url":"https://api.github.com/users/staebler/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/staebler/subscriptions","organizations_url":"https://api.github.com/users/staebler/orgs","repos_url":"https://api.github.com/users/staebler/repos","events_url":"https://api.github.com/users/staebler/events{/privacy}","received_events_url":"https://api.github.com/users/staebler/received_events","type":"User","site_admin":false},"body":"No, I don't think that is reasonable.\r\n1) The user should be able to update the Cluster.\r\n2) We will very soon be inspecting the ClusterVersionRef from the Status, which will certainly be done on an update rather than at creation.","created_at":"2018-05-17T13:18:21Z","updated_at":"2018-05-17T13:18:22Z","html_url":"https://github.com/openshift/cluster-operator/pull/217#discussion_r188953165","pull_request_url":"https://api.github.com/repos/openshift/cluster-operator/pulls/217","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/openshift/cluster-operator/pulls/comments/188953165"},"html":{"href":"https://github.com/openshift/cluster-operator/pull/217#discussion_r188953165"},"pull_request":{"href":"https://api.github.com/repos/openshift/cluster-operator/pulls/217"}},"in_reply_to_id":188823959},"pull_request":{"url":"https://api.github.com/repos/openshift/cluster-operator/pulls/217","id":187894187,"html_url":"https://github.com/openshift/cluster-operator/pull/217","diff_url":"https://github.com/openshift/cluster-operator/pull/217.diff","patch_url":"https://github.com/openshift/cluster-operator/pull/217.patch","issue_url":"https://api.github.com/repos/openshift/cluster-operator/issues/217","number":217,"state":"open","locked":false,"title":"WIP: Add cluster-api machine/machineset controllers.","user":{"login":"dgoodwin","id":51265,"avatar_url":"https://avatars3.githubusercontent.com/u/51265?v=4","gravatar_id":"","url":"https://api.github.com/users/dgoodwin","html_url":"https://github.com/dgoodwin","followers_url":"https://api.github.com/users/dgoodwin/followers","following_url":"https://api.github.com/users/dgoodwin/following{/other_user}","gists_url":"https://api.github.com/users/dgoodwin/gists{/gist_id}","starred_url":"https://api.github.com/users/dgoodwin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dgoodwin/subscriptions","organizations_url":"https://api.github.com/users/dgoodwin/orgs","repos_url":"https://api.github.com/users/dgoodwin/repos","events_url":"https://api.github.com/users/dgoodwin/events{/privacy}","received_events_url":"https://api.github.com/users/dgoodwin/received_events","type":"User","site_admin":false},"body":"These are responsible for populating some portions of the machineSpec\r\nproviderConfig on both machines and machinesets.\r\n\r\n- calculate the VMImage to use (uses cluster version and we expect\r\nadditional logic in future, which will only need to exist in the root\r\ncluster)\r\n- copy the cluster hardware spec for use in deletion (when cluster may\r\nno longer exist)\r\n- apply hardware defaults if applicable\r\n\r\nThese are only used in the root cluster, when we decide to send a\r\nmachineset down to the target cluster, we will update the spec\r\nbeforehand.\r\n\r\nAWS actuator is updated to use the correct data going forward. (followup\r\nPR will solve credentials to the actuator can actually create the master\r\nmachineset in the root cluster, presently this is still broken)","created_at":"2018-05-14T17:14:04Z","updated_at":"2018-05-17T13:18:22Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3ecb33b6d49b4464f77114ab55c691774ee5c251","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":770572208,"url":"https://api.github.com/repos/openshift/cluster-operator/labels/do-not-merge/work-in-progress","name":"do-not-merge/work-in-progress","color":"e11d21","default":false},{"id":770478179,"url":"https://api.github.com/repos/openshift/cluster-operator/labels/size/XXL","name":"size/XXL","color":"ee0000","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/openshift/cluster-operator/pulls/217/commits","review_comments_url":"https://api.github.com/repos/openshift/cluster-operator/pulls/217/comments","review_comment_url":"https://api.github.com/repos/openshift/cluster-operator/pulls/comments{/number}","comments_url":"https://api.github.com/repos/openshift/cluster-operator/issues/217/comments","statuses_url":"https://api.github.com/repos/openshift/cluster-operator/statuses/d1ce6f2ad1b31f38da6d4cb45abaae001dd3fd04","head":{"label":"dgoodwin:cluster-api","ref":"cluster-api","sha":"d1ce6f2ad1b31f38da6d4cb45abaae001dd3fd04","user":{"login":"dgoodwin","id":51265,"avatar_url":"https://avatars3.githubusercontent.com/u/51265?v=4","gravatar_id":"","url":"https://api.github.com/users/dgoodwin","html_url":"https://github.com/dgoodwin","followers_url":"https://api.github.com/users/dgoodwin/followers","following_url":"https://api.github.com/users/dgoodwin/following{/other_user}","gists_url":"https://api.github.com/users/dgoodwin/gists{/gist_id}","starred_url":"https://api.github.com/users/dgoodwin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dgoodwin/subscriptions","organizations_url":"https://api.github.com/users/dgoodwin/orgs","repos_url":"https://api.github.com/users/dgoodwin/repos","events_url":"https://api.github.com/users/dgoodwin/events{/privacy}","received_events_url":"https://api.github.com/users/dgoodwin/received_events","type":"User","site_admin":false},"repo":{"id":113201123,"name":"cluster-operator","full_name":"dgoodwin/cluster-operator","owner":{"login":"dgoodwin","id":51265,"avatar_url":"https://avatars3.githubusercontent.com/u/51265?v=4","gravatar_id":"","url":"https://api.github.com/users/dgoodwin","html_url":"https://github.com/dgoodwin","followers_url":"https://api.github.com/users/dgoodwin/followers","following_url":"https://api.github.com/users/dgoodwin/following{/other_user}","gists_url":"https://api.github.com/users/dgoodwin/gists{/gist_id}","starred_url":"https://api.github.com/users/dgoodwin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dgoodwin/subscriptions","organizations_url":"https://api.github.com/users/dgoodwin/orgs","repos_url":"https://api.github.com/users/dgoodwin/repos","events_url":"https://api.github.com/users/dgoodwin/events{/privacy}","received_events_url":"https://api.github.com/users/dgoodwin/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/dgoodwin/cluster-operator","description":null,"fork":true,"url":"https://api.github.com/repos/dgoodwin/cluster-operator","forks_url":"https://api.github.com/repos/dgoodwin/cluster-operator/forks","keys_url":"https://api.github.com/repos/dgoodwin/cluster-operator/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dgoodwin/cluster-operator/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dgoodwin/cluster-operator/teams","hooks_url":"https://api.github.com/repos/dgoodwin/cluster-operator/hooks","issue_events_url":"https://api.github.com/repos/dgoodwin/cluster-operator/issues/events{/number}","events_url":"https://api.github.com/repos/dgoodwin/cluster-operator/events","assignees_url":"https://api.github.com/repos/dgoodwin/cluster-operator/assignees{/user}","branches_url":"https://api.github.com/repos/dgoodwin/cluster-operator/branches{/branch}","tags_url":"https://api.github.com/repos/dgoodwin/cluster-operator/tags","blobs_url":"https://api.github.com/repos/dgoodwin/cluster-operator/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dgoodwin/cluster-operator/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dgoodwin/cluster-operator/git/refs{/sha}","trees_url":"https://api.github.com/repos/dgoodwin/cluster-operator/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dgoodwin/cluster-operator/statuses/{sha}","languages_url":"https://api.github.com/repos/dgoodwin/cluster-operator/languages","stargazers_url":"https://api.github.com/repos/dgoodwin/cluster-operator/stargazers","contributors_url":"https://api.github.com/repos/dgoodwin/cluster-operator/contributors","subscribers_url":"https://api.github.com/repos/dgoodwin/cluster-operator/subscribers","subscription_url":"https://api.github.com/repos/dgoodwin/cluster-operator/subscription","commits_url":"https://api.github.com/repos/dgoodwin/cluster-operator/commits{/sha}","git_commits_url":"https://api.github.com/repos/dgoodwin/cluster-operator/git/commits{/sha}","comments_url":"https://api.github.com/repos/dgoodwin/cluster-operator/comments{/number}","issue_comment_url":"https://api.github.com/repos/dgoodwin/cluster-operator/issues/comments{/number}","contents_url":"https://api.github.com/repos/dgoodwin/cluster-operator/contents/{+path}","compare_url":"https://api.github.com/repos/dgoodwin/cluster-operator/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dgoodwin/cluster-operator/merges","archive_url":"https://api.github.com/repos/dgoodwin/cluster-operator/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dgoodwin/cluster-operator/downloads","issues_url":"https://api.github.com/repos/dgoodwin/cluster-operator/issues{/number}","pulls_url":"https://api.github.com/repos/dgoodwin/cluster-operator/pulls{/number}","milestones_url":"https://api.github.com/repos/dgoodwin/cluster-operator/milestones{/number}","notifications_url":"https://api.github.com/repos/dgoodwin/cluster-operator/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dgoodwin/cluster-operator/labels{/name}","releases_url":"https://api.github.com/repos/dgoodwin/cluster-operator/releases{/id}","deployments_url":"https://api.github.com/repos/dgoodwin/cluster-operator/deployments","created_at":"2017-12-05T15:44:11Z","updated_at":"2018-04-18T12:08:21Z","pushed_at":"2018-05-17T13:14:18Z","git_url":"git://github.com/dgoodwin/cluster-operator.git","ssh_url":"git@github.com:dgoodwin/cluster-operator.git","clone_url":"https://github.com/dgoodwin/cluster-operator.git","svn_url":"https://github.com/dgoodwin/cluster-operator","homepage":null,"size":94945,"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,"open_issues_count":0,"license":null,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"openshift:master","ref":"master","sha":"75bf5f409f8cbf5fddd2b467f8b2d23824b28b16","user":{"login":"openshift","id":792337,"avatar_url":"https://avatars3.githubusercontent.com/u/792337?v=4","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":113197161,"name":"cluster-operator","full_name":"openshift/cluster-operator","owner":{"login":"openshift","id":792337,"avatar_url":"https://avatars3.githubusercontent.com/u/792337?v=4","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/cluster-operator","description":null,"fork":false,"url":"https://api.github.com/repos/openshift/cluster-operator","forks_url":"https://api.github.com/repos/openshift/cluster-operator/forks","keys_url":"https://api.github.com/repos/openshift/cluster-operator/keys{/key_id}","collaborators_url":"https://api.github.com/repos/openshift/cluster-operator/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/openshift/cluster-operator/teams","hooks_url":"https://api.github.com/repos/openshift/cluster-operator/hooks","issue_events_url":"https://api.github.com/repos/openshift/cluster-operator/issues/events{/number}","events_url":"https://api.github.com/repos/openshift/cluster-operator/events","assignees_url":"https://api.github.com/repos/openshift/cluster-operator/assignees{/user}","branches_url":"https://api.github.com/repos/openshift/cluster-operator/branches{/branch}","tags_url":"https://api.github.com/repos/openshift/cluster-operator/tags","blobs_url":"https://api.github.com/repos/openshift/cluster-operator/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/openshift/cluster-operator/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/openshift/cluster-operator/git/refs{/sha}","trees_url":"https://api.github.com/repos/openshift/cluster-operator/git/trees{/sha}","statuses_url":"https://api.github.com/repos/openshift/cluster-operator/statuses/{sha}","languages_url":"https://api.github.com/repos/openshift/cluster-operator/languages","stargazers_url":"https://api.github.com/repos/openshift/cluster-operator/stargazers","contributors_url":"https://api.github.com/repos/openshift/cluster-operator/contributors","subscribers_url":"https://api.github.com/repos/openshift/cluster-operator/subscribers","subscription_url":"https://api.github.com/repos/openshift/cluster-operator/subscription","commits_url":"https://api.github.com/repos/openshift/cluster-operator/commits{/sha}","git_commits_url":"https://api.github.com/repos/openshift/cluster-operator/git/commits{/sha}","comments_url":"https://api.github.com/repos/openshift/cluster-operator/comments{/number}","issue_comment_url":"https://api.github.com/repos/openshift/cluster-operator/issues/comments{/number}","contents_url":"https://api.github.com/repos/openshift/cluster-operator/contents/{+path}","compare_url":"https://api.github.com/repos/openshift/cluster-operator/compare/{base}...{head}","merges_url":"https://api.github.com/repos/openshift/cluster-operator/merges","archive_url":"https://api.github.com/repos/openshift/cluster-operator/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/openshift/cluster-operator/downloads","issues_url":"https://api.github.com/repos/openshift/cluster-operator/issues{/number}","pulls_url":"https://api.github.com/repos/openshift/cluster-operator/pulls{/number}","milestones_url":"https://api.github.com/repos/openshift/cluster-operator/milestones{/number}","notifications_url":"https://api.github.com/repos/openshift/cluster-operator/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/openshift/cluster-operator/labels{/name}","releases_url":"https://api.github.com/repos/openshift/cluster-operator/releases{/id}","deployments_url":"https://api.github.com/repos/openshift/cluster-operator/deployments","created_at":"2017-12-05T15:09:17Z","updated_at":"2018-05-16T22:07:24Z","pushed_at":"2018-05-17T13:14:19Z","git_url":"git://github.com/openshift/cluster-operator.git","ssh_url":"git@github.com:openshift/cluster-operator.git","clone_url":"https://github.com/openshift/cluster-operator.git","svn_url":"https://github.com/openshift/cluster-operator","homepage":null,"size":90027,"stargazers_count":22,"watchers_count":22,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":18,"mirror_url":null,"archived":false,"open_issues_count":21,"license":null,"forks":18,"open_issues":21,"watchers":22,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/openshift/cluster-operator/pulls/217"},"html":{"href":"https://github.com/openshift/cluster-operator/pull/217"},"issue":{"href":"https://api.github.com/repos/openshift/cluster-operator/issues/217"},"comments":{"href":"https://api.github.com/repos/openshift/cluster-operator/issues/217/comments"},"review_comments":{"href":"https://api.github.com/repos/openshift/cluster-operator/pulls/217/comments"},"review_comment":{"href":"https://api.github.com/repos/openshift/cluster-operator/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/openshift/cluster-operator/pulls/217/commits"},"statuses":{"href":"https://api.github.com/repos/openshift/cluster-operator/statuses/d1ce6f2ad1b31f38da6d4cb45abaae001dd3fd04"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"staebler"}}