Make HPA Controller use Namespacers

The HPA controller had previously used a single Client
object to act as three different Namespacers.  To improve
ease of extensibility and to make it clearer what the HPA
controller actually needs to use from the client, it should
use separate Namespacers for each of its needs (Scales, HPAs,
and Events).
This commit is contained in:
Solly Ross 2015-11-02 10:18:53 -05:00
parent 775369a8f1
commit 15fc230a59
3 changed files with 15 additions and 12 deletions

View File

@ -365,7 +365,7 @@ func (s *CMServer) Run(_ []string) error {
metrics.DefaultHeapsterService, metrics.DefaultHeapsterService,
metrics.DefaultHeapsterPort, metrics.DefaultHeapsterPort,
) )
podautoscaler.NewHorizontalController(hpaClient, metricsClient). podautoscaler.NewHorizontalController(hpaClient, hpaClient, hpaClient, metricsClient).
Run(s.HorizontalPodAutoscalerSyncPeriod) Run(s.HorizontalPodAutoscalerSyncPeriod)
} }

View File

@ -38,7 +38,9 @@ const (
) )
type HorizontalController struct { type HorizontalController struct {
client client.Interface scaleNamespacer client.ScaleNamespacer
hpaNamespacer client.HorizontalPodAutoscalersNamespacer
metricsClient metrics.MetricsClient metricsClient metrics.MetricsClient
eventRecorder record.EventRecorder eventRecorder record.EventRecorder
} }
@ -46,15 +48,16 @@ type HorizontalController struct {
var downscaleForbiddenWindow = 5 * time.Minute var downscaleForbiddenWindow = 5 * time.Minute
var upscaleForbiddenWindow = 3 * time.Minute var upscaleForbiddenWindow = 3 * time.Minute
func NewHorizontalController(client client.Interface, metricsClient metrics.MetricsClient) *HorizontalController { func NewHorizontalController(evtNamespacer client.EventNamespacer, scaleNamespacer client.ScaleNamespacer, hpaNamespacer client.HorizontalPodAutoscalersNamespacer, metricsClient metrics.MetricsClient) *HorizontalController {
broadcaster := record.NewBroadcaster() broadcaster := record.NewBroadcaster()
broadcaster.StartRecordingToSink(client.Events("")) broadcaster.StartRecordingToSink(evtNamespacer.Events(""))
recorder := broadcaster.NewRecorder(api.EventSource{Component: "horizontal-pod-autoscaler"}) recorder := broadcaster.NewRecorder(api.EventSource{Component: "horizontal-pod-autoscaler"})
return &HorizontalController{ return &HorizontalController{
client: client, metricsClient: metricsClient,
metricsClient: metricsClient, eventRecorder: recorder,
eventRecorder: recorder, scaleNamespacer: scaleNamespacer,
hpaNamespacer: hpaNamespacer,
} }
} }
@ -93,7 +96,7 @@ func (a *HorizontalController) computeReplicasForCPUUtilization(hpa extensions.H
func (a *HorizontalController) reconcileAutoscaler(hpa extensions.HorizontalPodAutoscaler) error { func (a *HorizontalController) reconcileAutoscaler(hpa extensions.HorizontalPodAutoscaler) error {
reference := fmt.Sprintf("%s/%s/%s", hpa.Spec.ScaleRef.Kind, hpa.Namespace, hpa.Spec.ScaleRef.Name) reference := fmt.Sprintf("%s/%s/%s", hpa.Spec.ScaleRef.Kind, hpa.Namespace, hpa.Spec.ScaleRef.Name)
scale, err := a.client.Extensions().Scales(hpa.Namespace).Get(hpa.Spec.ScaleRef.Kind, hpa.Spec.ScaleRef.Name) scale, err := a.scaleNamespacer.Scales(hpa.Namespace).Get(hpa.Spec.ScaleRef.Kind, hpa.Spec.ScaleRef.Name)
if err != nil { if err != nil {
a.eventRecorder.Event(&hpa, api.EventTypeWarning, "FailedGetScale", err.Error()) a.eventRecorder.Event(&hpa, api.EventTypeWarning, "FailedGetScale", err.Error())
return fmt.Errorf("failed to query scale subresource for %s: %v", reference, err) return fmt.Errorf("failed to query scale subresource for %s: %v", reference, err)
@ -140,7 +143,7 @@ func (a *HorizontalController) reconcileAutoscaler(hpa extensions.HorizontalPodA
if rescale { if rescale {
scale.Spec.Replicas = desiredReplicas scale.Spec.Replicas = desiredReplicas
_, err = a.client.Extensions().Scales(hpa.Namespace).Update(hpa.Spec.ScaleRef.Kind, scale) _, err = a.scaleNamespacer.Scales(hpa.Namespace).Update(hpa.Spec.ScaleRef.Kind, scale)
if err != nil { if err != nil {
a.eventRecorder.Eventf(&hpa, api.EventTypeWarning, "FailedRescale", "New size: %d; error: %v", desiredReplicas, err.Error()) a.eventRecorder.Eventf(&hpa, api.EventTypeWarning, "FailedRescale", "New size: %d; error: %v", desiredReplicas, err.Error())
return fmt.Errorf("failed to rescale %s: %v", reference, err) return fmt.Errorf("failed to rescale %s: %v", reference, err)
@ -163,7 +166,7 @@ func (a *HorizontalController) reconcileAutoscaler(hpa extensions.HorizontalPodA
hpa.Status.LastScaleTime = &now hpa.Status.LastScaleTime = &now
} }
_, err = a.client.Extensions().HorizontalPodAutoscalers(hpa.Namespace).UpdateStatus(&hpa) _, err = a.hpaNamespacer.HorizontalPodAutoscalers(hpa.Namespace).UpdateStatus(&hpa)
if err != nil { if err != nil {
a.eventRecorder.Event(&hpa, api.EventTypeWarning, "FailedUpdateStatus", err.Error()) a.eventRecorder.Event(&hpa, api.EventTypeWarning, "FailedUpdateStatus", err.Error())
return fmt.Errorf("failed to update status for %s: %v", hpa.Name, err) return fmt.Errorf("failed to update status for %s: %v", hpa.Name, err)
@ -173,7 +176,7 @@ func (a *HorizontalController) reconcileAutoscaler(hpa extensions.HorizontalPodA
func (a *HorizontalController) reconcileAutoscalers() error { func (a *HorizontalController) reconcileAutoscalers() error {
ns := api.NamespaceAll ns := api.NamespaceAll
list, err := a.client.Extensions().HorizontalPodAutoscalers(ns).List(api.ListOptions{}) list, err := a.hpaNamespacer.HorizontalPodAutoscalers(ns).List(api.ListOptions{})
if err != nil { if err != nil {
return fmt.Errorf("error listing nodes: %v", err) return fmt.Errorf("error listing nodes: %v", err)
} }

View File

@ -206,7 +206,7 @@ func (tc *testCase) verifyResults(t *testing.T) {
func (tc *testCase) runTest(t *testing.T) { func (tc *testCase) runTest(t *testing.T) {
testClient := tc.prepareTestClient(t) testClient := tc.prepareTestClient(t)
metricsClient := metrics.NewHeapsterMetricsClient(testClient, metrics.DefaultHeapsterNamespace, metrics.DefaultHeapsterScheme, metrics.DefaultHeapsterService, metrics.DefaultHeapsterPort) metricsClient := metrics.NewHeapsterMetricsClient(testClient, metrics.DefaultHeapsterNamespace, metrics.DefaultHeapsterScheme, metrics.DefaultHeapsterService, metrics.DefaultHeapsterPort)
hpaController := NewHorizontalController(testClient, metricsClient) hpaController := NewHorizontalController(testClient, testClient.Extensions(), testClient.Extensions(), metricsClient)
err := hpaController.reconcileAutoscalers() err := hpaController.reconcileAutoscalers()
assert.Equal(t, nil, err) assert.Equal(t, nil, err)
if tc.verifyEvents { if tc.verifyEvents {