From 62962e2198a2bd18044b1e25e7ccbc2d34da55a8 Mon Sep 17 00:00:00 2001 From: Mikkel Oscar Lyderik Larsen Date: Tue, 26 Nov 2019 18:02:49 +0100 Subject: [PATCH] Enable scale command to be used for stacks (#174) * Enable scale command to be used for stacks Signed-off-by: Mikkel Oscar Lyderik Larsen * Add labelSelector to stack status Signed-off-by: Mikkel Oscar Lyderik Larsen * Add labelSelector to stack status test Signed-off-by: Mikkel Oscar Lyderik Larsen --- docs/stack_crd.yaml | 5 +++++ pkg/apis/zalando.org/v1/types.go | 3 +++ pkg/core/stack_resources.go | 10 ++++++++-- pkg/core/stack_resources_test.go | 26 +++++++++++++++++++++----- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/docs/stack_crd.yaml b/docs/stack_crd.yaml index dad8ea84..8a4a76e9 100644 --- a/docs/stack_crd.yaml +++ b/docs/stack_crd.yaml @@ -45,6 +45,11 @@ spec: subresources: # status enables the status subresource. status: {} + # scale enables the scale subresource. + scale: + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + labelSelectorPath: .status.labelSelector # validation depends on Kubernetes >= v1.11.0 validation: openAPIV3Schema: diff --git a/pkg/apis/zalando.org/v1/types.go b/pkg/apis/zalando.org/v1/types.go index f8de0e02..0d6d9d4b 100644 --- a/pkg/apis/zalando.org/v1/types.go +++ b/pkg/apis/zalando.org/v1/types.go @@ -286,6 +286,9 @@ type StackStatus struct { // NoTrafficSince is the timestamp defining the last time the stack was // observed getting traffic. NoTrafficSince *metav1.Time `json:"noTrafficSince,omitempty"` + // LabelSelector is the label selector used to find all pods managed by + // a stack. + LabelSelector string `json:"labelSelector,omitempty"` } // Prescaling hold prescaling information diff --git a/pkg/core/stack_resources.go b/pkg/core/stack_resources.go index 8b26d035..9dbb18f8 100644 --- a/pkg/core/stack_resources.go +++ b/pkg/core/stack_resources.go @@ -10,6 +10,7 @@ import ( v1 "k8s.io/api/core/v1" extensions "k8s.io/api/extensions/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -135,6 +136,10 @@ func servicePortsFromContainers(containers []v1.Container) []v1.ServicePort { return ports } +func (sc *StackContainer) selector() map[string]string { + return limitLabels(sc.Stack.Labels, selectorLabels) +} + func (sc *StackContainer) GenerateDeployment() *appsv1.Deployment { stack := sc.Stack @@ -166,7 +171,7 @@ func (sc *StackContainer) GenerateDeployment() *appsv1.Deployment { Spec: appsv1.DeploymentSpec{ Replicas: updatedReplicas, Selector: &metav1.LabelSelector{ - MatchLabels: limitLabels(stack.Labels, selectorLabels), + MatchLabels: sc.selector(), }, Template: *templateInjectLabels(stack.Spec.PodTemplate.DeepCopy(), stack.Labels), }, @@ -237,7 +242,7 @@ func (sc *StackContainer) GenerateService() (*v1.Service, error) { return &v1.Service{ ObjectMeta: sc.resourceMeta(), Spec: v1.ServiceSpec{ - Selector: limitLabels(sc.Stack.Labels, selectorLabels), + Selector: sc.selector(), Type: v1.ServiceTypeClusterIP, Ports: servicePorts, }, @@ -309,5 +314,6 @@ func (sc *StackContainer) GenerateStackStatus() *zv1.StackStatus { DesiredReplicas: sc.desiredReplicas, Prescaling: prescaling, NoTrafficSince: wrapTime(sc.noTrafficSince), + LabelSelector: labels.Set(sc.selector()).String(), } } diff --git a/pkg/core/stack_resources_test.go b/pkg/core/stack_resources_test.go index dfaecb2f..b469eff6 100644 --- a/pkg/core/stack_resources_test.go +++ b/pkg/core/stack_resources_test.go @@ -571,6 +571,8 @@ func TestGenerateStackStatus(t *testing.T) { for _, tc := range []struct { name string + labels map[string]string + expectedLabelSelector string actualTrafficWeight float64 desiredTrafficWeight float64 noTrafficSince time.Time @@ -580,16 +582,24 @@ func TestGenerateStackStatus(t *testing.T) { prescalingLastTrafficIncrease time.Time }{ { - name: "with traffic", - actualTrafficWeight: 0.25, - desiredTrafficWeight: 0.75, + name: "with traffic", + labels: map[string]string{}, + expectedLabelSelector: "", + actualTrafficWeight: 0.25, + desiredTrafficWeight: 0.75, }, { - name: "without traffic", - noTrafficSince: hourAgo, + name: "without traffic", + labels: map[string]string{ + StacksetHeritageLabelKey: "stackset-x", + }, + expectedLabelSelector: "stackset=stackset-x", + noTrafficSince: hourAgo, }, { name: "prescaled", + labels: map[string]string{}, + expectedLabelSelector: "", actualTrafficWeight: 0.25, desiredTrafficWeight: 0.25, prescalingActive: true, @@ -600,6 +610,11 @@ func TestGenerateStackStatus(t *testing.T) { } { t.Run(tc.name, func(t *testing.T) { c := &StackContainer{ + Stack: &zv1.Stack{ + ObjectMeta: metav1.ObjectMeta{ + Labels: tc.labels, + }, + }, actualTrafficWeight: tc.actualTrafficWeight, desiredTrafficWeight: tc.desiredTrafficWeight, createdReplicas: 3, @@ -621,6 +636,7 @@ func TestGenerateStackStatus(t *testing.T) { UpdatedReplicas: 1, DesiredReplicas: 4, NoTrafficSince: wrapTime(tc.noTrafficSince), + LabelSelector: tc.expectedLabelSelector, Prescaling: zv1.PrescalingStatus{ Active: tc.prescalingActive, Replicas: tc.prescalingReplicas,