Skip to content

Commit

Permalink
fix: improved service match labels (#6)
Browse files Browse the repository at this point in the history
Signed-off-by: Ben Meier <ben.meier@humanitec.com>
  • Loading branch information
astromechza authored May 15, 2024
1 parent 507bcc0 commit 283b80f
Show file tree
Hide file tree
Showing 9 changed files with 206 additions and 48 deletions.
18 changes: 15 additions & 3 deletions internal/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,23 @@

package internal

import "slices"
import (
"slices"

score "github.com/score-spec/score-go/types"
)

const (
AnnotationPrefix = "k8s.score.dev/"
WorkloadKindAnnotation = AnnotationPrefix + "kind"
)

func ListAnnotations(metadata map[string]interface{}) []string {
if a, ok := metadata["annotations"].(map[string]interface{}); ok {
a, ok := metadata["annotations"].(map[string]interface{})
if !ok {
a, ok = metadata["annotations"].(score.WorkloadMetadata)
}
if ok {
out := make([]string, 0, len(a))
for s, _ := range a {
out = append(out, s)
Expand All @@ -34,7 +42,11 @@ func ListAnnotations(metadata map[string]interface{}) []string {
}

func FindAnnotation(metadata map[string]interface{}, annotation string) (string, bool) {
if a, ok := metadata["annotations"].(map[string]interface{}); ok {
a, ok := metadata["annotations"].(map[string]interface{})
if !ok {
a, ok = metadata["annotations"].(score.WorkloadMetadata)
}
if ok {
if v, ok := a[annotation].(string); ok {
return v, true
}
Expand Down
39 changes: 24 additions & 15 deletions internal/convert/workloads.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@ import (
)

const (
WorkloadKindDeployment = "Deployment"
WorkloadKindStatefulSet = "StatefulSet"
SelectorLabelWorkloadName = "score-workload"
WorkloadKindDeployment = "Deployment"
WorkloadKindStatefulSet = "StatefulSet"

SelectorLabelName = "app.kubernetes.io/name"
SelectorLabelInstance = "app.kubernetes.io/instance"
SelectorLabelManagedBy = "app.kubernetes.io/managed-by"
)

func ConvertWorkload(state *project.State, workloadName string) ([]machineryMeta.Object, error) {
Expand Down Expand Up @@ -68,6 +71,12 @@ func ConvertWorkload(state *project.State, workloadName string) ([]machineryMeta
}
slices.Sort(containerNames)

commonLabels := map[string]string{
SelectorLabelName: workloadName,
SelectorLabelInstance: workloadName + state.Workloads[workloadName].Extras.InstanceSuffix,
SelectorLabelManagedBy: "score-k8s",
}

for _, containerName := range containerNames {
container := spec.Containers[containerName]
c := coreV1.Container{
Expand Down Expand Up @@ -179,10 +188,11 @@ func ConvertWorkload(state *project.State, workloadName string) ([]machineryMeta
ObjectMeta: machineryMeta.ObjectMeta{
Name: WorkloadServiceName(workloadName),
Annotations: topLevelAnnotations,
Labels: commonLabels,
},
Spec: coreV1.ServiceSpec{
Selector: map[string]string{
SelectorLabelWorkloadName: workloadName,
SelectorLabelInstance: commonLabels[SelectorLabelInstance],
},
Ports: portList,
},
Expand All @@ -196,19 +206,18 @@ func ConvertWorkload(state *project.State, workloadName string) ([]machineryMeta
ObjectMeta: machineryMeta.ObjectMeta{
Name: workloadName,
Annotations: topLevelAnnotations,
Labels: commonLabels,
},
Spec: v1.DeploymentSpec{
Replicas: internal.Ref(int32(1)),
Selector: &machineryMeta.LabelSelector{
MatchExpressions: []machineryMeta.LabelSelectorRequirement{
{SelectorLabelWorkloadName, machineryMeta.LabelSelectorOpIn, []string{workloadName}},
MatchLabels: map[string]string{
SelectorLabelInstance: commonLabels[SelectorLabelInstance],
},
},
Template: coreV1.PodTemplateSpec{
ObjectMeta: machineryMeta.ObjectMeta{
Labels: map[string]string{
SelectorLabelWorkloadName: workloadName,
},
Labels: commonLabels,
Annotations: podAnnotations,
},
Spec: coreV1.PodSpec{
Expand All @@ -227,10 +236,11 @@ func ConvertWorkload(state *project.State, workloadName string) ([]machineryMeta
ObjectMeta: machineryMeta.ObjectMeta{
Name: headlessServiceName,
Annotations: topLevelAnnotations,
Labels: commonLabels,
},
Spec: coreV1.ServiceSpec{
Selector: map[string]string{
SelectorLabelWorkloadName: workloadName,
SelectorLabelInstance: commonLabels[SelectorLabelInstance],
},
ClusterIP: "None",
Ports: []coreV1.ServicePort{{Name: "default", Port: 99, TargetPort: intstr.FromInt32(99)}},
Expand All @@ -242,20 +252,19 @@ func ConvertWorkload(state *project.State, workloadName string) ([]machineryMeta
ObjectMeta: machineryMeta.ObjectMeta{
Name: workloadName,
Annotations: topLevelAnnotations,
Labels: commonLabels,
},
Spec: v1.StatefulSetSpec{
Replicas: internal.Ref(int32(1)),
Selector: &machineryMeta.LabelSelector{
MatchExpressions: []machineryMeta.LabelSelectorRequirement{
{SelectorLabelWorkloadName, machineryMeta.LabelSelectorOpIn, []string{workloadName}},
MatchLabels: map[string]string{
SelectorLabelInstance: commonLabels[SelectorLabelInstance],
},
},
ServiceName: headlessServiceName,
Template: coreV1.PodTemplateSpec{
ObjectMeta: machineryMeta.ObjectMeta{
Labels: map[string]string{
SelectorLabelWorkloadName: workloadName,
},
Labels: commonLabels,
Annotations: podAnnotations,
},
Spec: coreV1.PodSpec{
Expand Down
47 changes: 40 additions & 7 deletions internal/convert/workloads_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ func TestMassive(t *testing.T) {
Image: "other-image",
},
},
Service: &scoretypes.WorkloadService{
Ports: map[string]scoretypes.ServicePort{
"web": {
Port: 80,
TargetPort: internal.Ref(8080),
Protocol: internal.Ref(scoretypes.ServicePortProtocolUDP),
},
},
},
Resources: map[string]scoretypes.Resource{
"foo": {
Type: "thing",
Expand All @@ -94,7 +103,7 @@ func TestMassive(t *testing.T) {
Class: internal.Ref("default"),
},
},
}, nil, framework.NoExtras{})
}, nil, project.WorkloadExtras{InstanceSuffix: "-abcdef"})
require.NoError(t, err)
state.Resources = map[framework.ResourceUid]framework.ScoreResourceState[project.ResourceExtras]{
"thing.default#shared": {
Expand Down Expand Up @@ -131,21 +140,43 @@ kind: ConfigMap
metadata:
creationTimestamp: null
name: example-c1-file-0
apiVersion: v1
kind: Service
metadata:
annotations:
k8s.score.dev/workload-name: example
creationTimestamp: null
labels:
app.kubernetes.io/instance: example-abcdef
app.kubernetes.io/managed-by: score-k8s
app.kubernetes.io/name: example
name: example-svc
spec:
ports:
- name: web
port: 80
protocol: UDP
targetPort: 8080
selector:
app.kubernetes.io/instance: example-abcdef
status:
loadBalancer: {}
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
k8s.score.dev/workload-name: example
creationTimestamp: null
labels:
app.kubernetes.io/instance: example-abcdef
app.kubernetes.io/managed-by: score-k8s
app.kubernetes.io/name: example
name: example
spec:
replicas: 1
selector:
matchExpressions:
- key: score-workload
operator: In
values:
- example
matchLabels:
app.kubernetes.io/instance: example-abcdef
strategy: {}
template:
metadata:
Expand All @@ -154,7 +185,9 @@ spec:
my.custom.scope/annotation: value
creationTimestamp: null
labels:
score-workload: example
app.kubernetes.io/instance: example-abcdef
app.kubernetes.io/managed-by: score-k8s
app.kubernetes.io/name: example
spec:
containers:
- args:
Expand Down
6 changes: 5 additions & 1 deletion internal/project/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,16 @@ const (
StateFileName = "state.yaml"
)

type WorkloadExtras struct {
InstanceSuffix string `yaml:"instance_suffix"`
}

type ResourceExtras struct {
// Don't actually persist these manifests, we just hold them here so we can pass them around.
Manifests []map[string]interface{} `yaml:"-"`
}

type State = framework.State[framework.NoExtras, framework.NoExtras, ResourceExtras]
type State = framework.State[framework.NoExtras, WorkloadExtras, ResourceExtras]

// The StateDirectory holds the local state of the score-k8s project, including any configuration, extensions,
// plugins, or resource provisioning state when possible.
Expand Down
Loading

0 comments on commit 283b80f

Please sign in to comment.