Allow users to apply labels and annotations to internal resources (#4400)

This commit is contained in:
Nikola Jokic
2026-03-12 10:32:54 +01:00
committed by GitHub
parent 1f3e5b9027
commit 1d9f626c53
16 changed files with 736 additions and 50 deletions
@@ -69,6 +69,18 @@ type AutoscalingListenerSpec struct {
// +optional // +optional
Template *corev1.PodTemplateSpec `json:"template,omitempty"` Template *corev1.PodTemplateSpec `json:"template,omitempty"`
// +optional
ConfigSecretMetadata *ResourceMeta `json:"configSecretMetadata,omitempty"`
// +optional
ServiceAccountMetadata *ResourceMeta `json:"serviceAccountMetadata,omitempty"`
// +optional
RoleMetadata *ResourceMeta `json:"roleMetadata,omitempty"`
// +optional
RoleBindingMetadata *ResourceMeta `json:"roleBindingMetadata,omitempty"`
} }
// AutoscalingListenerStatus defines the observed state of AutoscalingListener // AutoscalingListenerStatus defines the observed state of AutoscalingListener
@@ -78,12 +78,36 @@ type AutoscalingRunnerSetSpec struct {
// Required // Required
Template corev1.PodTemplateSpec `json:"template,omitempty"` Template corev1.PodTemplateSpec `json:"template,omitempty"`
// +optional
AutoscalingListenerMetadata *ResourceMeta `json:"autoscalingListener,omitempty"`
// +optional // +optional
ListenerMetrics *MetricsConfig `json:"listenerMetrics,omitempty"` ListenerMetrics *MetricsConfig `json:"listenerMetrics,omitempty"`
// +optional // +optional
ListenerTemplate *corev1.PodTemplateSpec `json:"listenerTemplate,omitempty"` ListenerTemplate *corev1.PodTemplateSpec `json:"listenerTemplate,omitempty"`
// +optional
ListenerServiceAccountMetadata *ResourceMeta `json:"listenerServiceAccountMetadata,omitempty"`
// +optional
ListenerRoleMetadata *ResourceMeta `json:"listenerRoleMetadata,omitempty"`
// +optional
ListenerRoleBindingMetadata *ResourceMeta `json:"listenerRoleBindingMetadata,omitempty"`
// +optional
ListenerConfigSecretMetadata *ResourceMeta `json:"listenerConfigSecretMetadata,omitempty"`
// +optional
EphemeralRunnerSetMetadata *ResourceMeta `json:"ephemeralRunnerSetMetadata,omitempty"`
// +optional
EphemeralRunnerMetadata *ResourceMeta `json:"ephemeralRunnerMetadata,omitempty"`
// +optional
EphemeralRunnerConfigSecretMetadata *ResourceMeta `json:"ephemeralRunnerConfigSecretMetadata,omitempty"`
// +optional // +optional
// +kubebuilder:validation:Minimum:=0 // +kubebuilder:validation:Minimum:=0
MaxRunners *int `json:"maxRunners,omitempty"` MaxRunners *int `json:"maxRunners,omitempty"`
@@ -0,0 +1,9 @@
package v1alpha1
// ResourceMeta carries metadata common to all internal resources
type ResourceMeta struct {
// +optional
Labels map[string]string `json:"labels,omitempty"`
// +optional
Annotations map[string]string `json:"annotations,omitempty"`
}
@@ -122,6 +122,9 @@ type EphemeralRunnerSpec struct {
// +optional // +optional
VaultConfig *VaultConfig `json:"vaultConfig,omitempty"` VaultConfig *VaultConfig `json:"vaultConfig,omitempty"`
// +optional
EphemeralRunnerConfigSecretMetadata *ResourceMeta `json:"ephemeralRunnerConfigSecretMetadata,omitempty"`
corev1.PodTemplateSpec `json:",inline"` corev1.PodTemplateSpec `json:",inline"`
} }
@@ -28,6 +28,8 @@ type EphemeralRunnerSetSpec struct {
PatchID int `json:"patchID"` PatchID int `json:"patchID"`
// EphemeralRunnerSpec is the spec of the ephemeral runner // EphemeralRunnerSpec is the spec of the ephemeral runner
EphemeralRunnerSpec EphemeralRunnerSpec `json:"ephemeralRunnerSpec,omitempty"` EphemeralRunnerSpec EphemeralRunnerSpec `json:"ephemeralRunnerSpec,omitempty"`
// +optional
EphemeralRunnerMetadata *ResourceMeta `json:"ephemeralRunnerMetadata,omitempty"`
} }
// EphemeralRunnerSetStatus defines the observed state of EphemeralRunnerSet // EphemeralRunnerSetStatus defines the observed state of EphemeralRunnerSet
@@ -118,6 +118,26 @@ func (in *AutoscalingListenerSpec) DeepCopyInto(out *AutoscalingListenerSpec) {
*out = new(v1.PodTemplateSpec) *out = new(v1.PodTemplateSpec)
(*in).DeepCopyInto(*out) (*in).DeepCopyInto(*out)
} }
if in.ConfigSecretMetadata != nil {
in, out := &in.ConfigSecretMetadata, &out.ConfigSecretMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.ServiceAccountMetadata != nil {
in, out := &in.ServiceAccountMetadata, &out.ServiceAccountMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.RoleMetadata != nil {
in, out := &in.RoleMetadata, &out.RoleMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.RoleBindingMetadata != nil {
in, out := &in.RoleBindingMetadata, &out.RoleBindingMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
} }
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AutoscalingListenerSpec. // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AutoscalingListenerSpec.
@@ -223,6 +243,11 @@ func (in *AutoscalingRunnerSetSpec) DeepCopyInto(out *AutoscalingRunnerSetSpec)
(*in).DeepCopyInto(*out) (*in).DeepCopyInto(*out)
} }
in.Template.DeepCopyInto(&out.Template) in.Template.DeepCopyInto(&out.Template)
if in.AutoscalingListenerMetadata != nil {
in, out := &in.AutoscalingListenerMetadata, &out.AutoscalingListenerMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.ListenerMetrics != nil { if in.ListenerMetrics != nil {
in, out := &in.ListenerMetrics, &out.ListenerMetrics in, out := &in.ListenerMetrics, &out.ListenerMetrics
*out = new(MetricsConfig) *out = new(MetricsConfig)
@@ -233,6 +258,41 @@ func (in *AutoscalingRunnerSetSpec) DeepCopyInto(out *AutoscalingRunnerSetSpec)
*out = new(v1.PodTemplateSpec) *out = new(v1.PodTemplateSpec)
(*in).DeepCopyInto(*out) (*in).DeepCopyInto(*out)
} }
if in.ListenerServiceAccountMetadata != nil {
in, out := &in.ListenerServiceAccountMetadata, &out.ListenerServiceAccountMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.ListenerRoleMetadata != nil {
in, out := &in.ListenerRoleMetadata, &out.ListenerRoleMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.ListenerRoleBindingMetadata != nil {
in, out := &in.ListenerRoleBindingMetadata, &out.ListenerRoleBindingMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.ListenerConfigSecretMetadata != nil {
in, out := &in.ListenerConfigSecretMetadata, &out.ListenerConfigSecretMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.EphemeralRunnerSetMetadata != nil {
in, out := &in.EphemeralRunnerSetMetadata, &out.EphemeralRunnerSetMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.EphemeralRunnerMetadata != nil {
in, out := &in.EphemeralRunnerMetadata, &out.EphemeralRunnerMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.EphemeralRunnerConfigSecretMetadata != nil {
in, out := &in.EphemeralRunnerConfigSecretMetadata, &out.EphemeralRunnerConfigSecretMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
if in.MaxRunners != nil { if in.MaxRunners != nil {
in, out := &in.MaxRunners, &out.MaxRunners in, out := &in.MaxRunners, &out.MaxRunners
*out = new(int) *out = new(int)
@@ -427,6 +487,11 @@ func (in *EphemeralRunnerSetList) DeepCopyObject() runtime.Object {
func (in *EphemeralRunnerSetSpec) DeepCopyInto(out *EphemeralRunnerSetSpec) { func (in *EphemeralRunnerSetSpec) DeepCopyInto(out *EphemeralRunnerSetSpec) {
*out = *in *out = *in
in.EphemeralRunnerSpec.DeepCopyInto(&out.EphemeralRunnerSpec) in.EphemeralRunnerSpec.DeepCopyInto(&out.EphemeralRunnerSpec)
if in.EphemeralRunnerMetadata != nil {
in, out := &in.EphemeralRunnerMetadata, &out.EphemeralRunnerMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
} }
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EphemeralRunnerSetSpec. // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EphemeralRunnerSetSpec.
@@ -472,6 +537,11 @@ func (in *EphemeralRunnerSpec) DeepCopyInto(out *EphemeralRunnerSpec) {
*out = new(VaultConfig) *out = new(VaultConfig)
(*in).DeepCopyInto(*out) (*in).DeepCopyInto(*out)
} }
if in.EphemeralRunnerConfigSecretMetadata != nil {
in, out := &in.EphemeralRunnerConfigSecretMetadata, &out.EphemeralRunnerConfigSecretMetadata
*out = new(ResourceMeta)
(*in).DeepCopyInto(*out)
}
in.PodTemplateSpec.DeepCopyInto(&out.PodTemplateSpec) in.PodTemplateSpec.DeepCopyInto(&out.PodTemplateSpec)
} }
@@ -660,6 +730,35 @@ func (in *ProxyServerConfig) DeepCopy() *ProxyServerConfig {
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ResourceMeta) DeepCopyInto(out *ResourceMeta) {
*out = *in
if in.Labels != nil {
in, out := &in.Labels, &out.Labels
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.Annotations != nil {
in, out := &in.Annotations, &out.Annotations
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceMeta.
func (in *ResourceMeta) DeepCopy() *ResourceMeta {
if in == nil {
return nil
}
out := new(ResourceMeta)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TLSCertificateSource) DeepCopyInto(out *TLSCertificateSource) { func (in *TLSCertificateSource) DeepCopyInto(out *TLSCertificateSource) {
*out = *in *out = *in
@@ -56,6 +56,19 @@ spec:
autoscalingRunnerSetNamespace: autoscalingRunnerSetNamespace:
description: Required description: Required
type: string type: string
configSecretMetadata:
description: ResourceMeta carries metadata common to all internal
resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
ephemeralRunnerSetName: ephemeralRunnerSetName:
description: Required description: Required
type: string type: string
@@ -196,9 +209,48 @@ spec:
type: string type: string
type: array type: array
type: object type: object
roleBindingMetadata:
description: ResourceMeta carries metadata common to all internal
resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
roleMetadata:
description: ResourceMeta carries metadata common to all internal
resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
runnerScaleSetId: runnerScaleSetId:
description: Required description: Required
type: integer type: integer
serviceAccountMetadata:
description: ResourceMeta carries metadata common to all internal
resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
template: template:
description: PodTemplateSpec describes the data a pod should have description: PodTemplateSpec describes the data a pod should have
when created from a template when created from a template
@@ -64,6 +64,54 @@ spec:
spec: spec:
description: AutoscalingRunnerSetSpec defines the desired state of AutoscalingRunnerSet description: AutoscalingRunnerSetSpec defines the desired state of AutoscalingRunnerSet
properties: properties:
autoscalingListener:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
ephemeralRunnerConfigSecretMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
ephemeralRunnerMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
ephemeralRunnerSetMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
githubConfigSecret: githubConfigSecret:
description: Required description: Required
type: string type: string
@@ -99,6 +147,18 @@ spec:
x-kubernetes-map-type: atomic x-kubernetes-map-type: atomic
type: object type: object
type: object type: object
listenerConfigSecretMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
listenerMetrics: listenerMetrics:
description: MetricsConfig holds configuration parameters for each metric type description: MetricsConfig holds configuration parameters for each metric type
properties: properties:
@@ -143,6 +203,42 @@ spec:
type: object type: object
type: object type: object
type: object type: object
listenerRoleBindingMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
listenerRoleMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
listenerServiceAccountMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
listenerTemplate: listenerTemplate:
description: PodTemplateSpec describes the data a pod should have when created from a template description: PodTemplateSpec describes the data a pod should have when created from a template
properties: properties:
@@ -70,6 +70,18 @@ spec:
spec: spec:
description: EphemeralRunnerSpec defines the desired state of EphemeralRunner description: EphemeralRunnerSpec defines the desired state of EphemeralRunner
properties: properties:
ephemeralRunnerConfigSecretMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
githubConfigSecret: githubConfigSecret:
type: string type: string
githubConfigUrl: githubConfigUrl:
@@ -58,9 +58,33 @@ spec:
spec: spec:
description: EphemeralRunnerSetSpec defines the desired state of EphemeralRunnerSet description: EphemeralRunnerSetSpec defines the desired state of EphemeralRunnerSet
properties: properties:
ephemeralRunnerMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
ephemeralRunnerSpec: ephemeralRunnerSpec:
description: EphemeralRunnerSpec is the spec of the ephemeral runner description: EphemeralRunnerSpec is the spec of the ephemeral runner
properties: properties:
ephemeralRunnerConfigSecretMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
githubConfigSecret: githubConfigSecret:
type: string type: string
githubConfigUrl: githubConfigUrl:
@@ -56,6 +56,19 @@ spec:
autoscalingRunnerSetNamespace: autoscalingRunnerSetNamespace:
description: Required description: Required
type: string type: string
configSecretMetadata:
description: ResourceMeta carries metadata common to all internal
resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
ephemeralRunnerSetName: ephemeralRunnerSetName:
description: Required description: Required
type: string type: string
@@ -196,9 +209,48 @@ spec:
type: string type: string
type: array type: array
type: object type: object
roleBindingMetadata:
description: ResourceMeta carries metadata common to all internal
resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
roleMetadata:
description: ResourceMeta carries metadata common to all internal
resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
runnerScaleSetId: runnerScaleSetId:
description: Required description: Required
type: integer type: integer
serviceAccountMetadata:
description: ResourceMeta carries metadata common to all internal
resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
template: template:
description: PodTemplateSpec describes the data a pod should have description: PodTemplateSpec describes the data a pod should have
when created from a template when created from a template
@@ -64,6 +64,54 @@ spec:
spec: spec:
description: AutoscalingRunnerSetSpec defines the desired state of AutoscalingRunnerSet description: AutoscalingRunnerSetSpec defines the desired state of AutoscalingRunnerSet
properties: properties:
autoscalingListener:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
ephemeralRunnerConfigSecretMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
ephemeralRunnerMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
ephemeralRunnerSetMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
githubConfigSecret: githubConfigSecret:
description: Required description: Required
type: string type: string
@@ -99,6 +147,18 @@ spec:
x-kubernetes-map-type: atomic x-kubernetes-map-type: atomic
type: object type: object
type: object type: object
listenerConfigSecretMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
listenerMetrics: listenerMetrics:
description: MetricsConfig holds configuration parameters for each metric type description: MetricsConfig holds configuration parameters for each metric type
properties: properties:
@@ -143,6 +203,42 @@ spec:
type: object type: object
type: object type: object
type: object type: object
listenerRoleBindingMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
listenerRoleMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
listenerServiceAccountMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
listenerTemplate: listenerTemplate:
description: PodTemplateSpec describes the data a pod should have when created from a template description: PodTemplateSpec describes the data a pod should have when created from a template
properties: properties:
@@ -70,6 +70,18 @@ spec:
spec: spec:
description: EphemeralRunnerSpec defines the desired state of EphemeralRunner description: EphemeralRunnerSpec defines the desired state of EphemeralRunner
properties: properties:
ephemeralRunnerConfigSecretMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
githubConfigSecret: githubConfigSecret:
type: string type: string
githubConfigUrl: githubConfigUrl:
@@ -58,9 +58,33 @@ spec:
spec: spec:
description: EphemeralRunnerSetSpec defines the desired state of EphemeralRunnerSet description: EphemeralRunnerSetSpec defines the desired state of EphemeralRunnerSet
properties: properties:
ephemeralRunnerMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
ephemeralRunnerSpec: ephemeralRunnerSpec:
description: EphemeralRunnerSpec is the spec of the ephemeral runner description: EphemeralRunnerSpec is the spec of the ephemeral runner
properties: properties:
ephemeralRunnerConfigSecretMetadata:
description: ResourceMeta carries metadata common to all internal resources
properties:
annotations:
additionalProperties:
type: string
type: object
labels:
additionalProperties:
type: string
type: object
type: object
githubConfigSecret: githubConfigSecret:
type: string type: string
githubConfigUrl: githubConfigUrl:
+125 -40
View File
@@ -96,7 +96,7 @@ func (b *ResourceBuilder) newAutoScalingListener(autoscalingRunnerSet *v1alpha1.
effectiveMinRunners = *autoscalingRunnerSet.Spec.MinRunners effectiveMinRunners = *autoscalingRunnerSet.Spec.MinRunners
} }
labels := b.mergeLabels(autoscalingRunnerSet.Labels, map[string]string{ labels := b.filterAndMergeLabels(autoscalingRunnerSet.Labels, map[string]string{
LabelKeyGitHubScaleSetNamespace: autoscalingRunnerSet.Namespace, LabelKeyGitHubScaleSetNamespace: autoscalingRunnerSet.Namespace,
LabelKeyGitHubScaleSetName: autoscalingRunnerSet.Name, LabelKeyGitHubScaleSetName: autoscalingRunnerSet.Name,
LabelKeyKubernetesPartOf: labelValueKubernetesPartOf, LabelKeyKubernetesPartOf: labelValueKubernetesPartOf,
@@ -104,13 +104,18 @@ func (b *ResourceBuilder) newAutoScalingListener(autoscalingRunnerSet *v1alpha1.
LabelKeyKubernetesVersion: autoscalingRunnerSet.Labels[LabelKeyKubernetesVersion], LabelKeyKubernetesVersion: autoscalingRunnerSet.Labels[LabelKeyKubernetesVersion],
}) })
if err := applyGitHubURLLabels(autoscalingRunnerSet.Spec.GitHubConfigUrl, labels); err != nil {
return nil, fmt.Errorf("failed to apply GitHub URL labels: %v", err)
}
annotations := map[string]string{ annotations := map[string]string{
annotationKeyRunnerSpecHash: autoscalingRunnerSet.ListenerSpecHash(), annotationKeyRunnerSpecHash: autoscalingRunnerSet.ListenerSpecHash(),
annotationKeyValuesHash: autoscalingRunnerSet.Annotations[annotationKeyValuesHash], annotationKeyValuesHash: autoscalingRunnerSet.Annotations[annotationKeyValuesHash],
} }
if err := applyGitHubURLLabels(autoscalingRunnerSet.Spec.GitHubConfigUrl, labels); err != nil { if autoscalingRunnerSet.Spec.AutoscalingListenerMetadata != nil {
return nil, fmt.Errorf("failed to apply GitHub URL labels: %v", err) labels = b.filterAndMergeLabels(autoscalingRunnerSet.Spec.AutoscalingListenerMetadata.Labels, labels)
annotations = b.mergeAnnotations(autoscalingRunnerSet.Spec.AutoscalingListenerMetadata.Annotations, annotations)
} }
autoscalingListener := &v1alpha1.AutoscalingListener{ autoscalingListener := &v1alpha1.AutoscalingListener{
@@ -136,6 +141,10 @@ func (b *ResourceBuilder) newAutoScalingListener(autoscalingRunnerSet *v1alpha1.
GitHubServerTLS: autoscalingRunnerSet.Spec.GitHubServerTLS, GitHubServerTLS: autoscalingRunnerSet.Spec.GitHubServerTLS,
Metrics: autoscalingRunnerSet.Spec.ListenerMetrics, Metrics: autoscalingRunnerSet.Spec.ListenerMetrics,
Template: autoscalingRunnerSet.Spec.ListenerTemplate, Template: autoscalingRunnerSet.Spec.ListenerTemplate,
ServiceAccountMetadata: autoscalingRunnerSet.Spec.ListenerServiceAccountMetadata,
RoleMetadata: autoscalingRunnerSet.Spec.ListenerRoleMetadata,
RoleBindingMetadata: autoscalingRunnerSet.Spec.ListenerRoleBindingMetadata,
ConfigSecretMetadata: autoscalingRunnerSet.Spec.ListenerConfigSecretMetadata,
}, },
} }
@@ -212,10 +221,22 @@ func (b *ResourceBuilder) newScaleSetListenerConfig(autoscalingListener *v1alpha
return nil, fmt.Errorf("failed to encode config: %w", err) return nil, fmt.Errorf("failed to encode config: %w", err)
} }
var labels map[string]string
if autoscalingListener.Spec.ConfigSecretMetadata != nil && len(autoscalingListener.Spec.ConfigSecretMetadata.Labels) > 0 {
labels = b.filterAndMergeLabels(autoscalingListener.Spec.ConfigSecretMetadata.Labels, nil)
}
var annotations map[string]string
if autoscalingListener.Spec.ConfigSecretMetadata != nil && len(autoscalingListener.Spec.ConfigSecretMetadata.Annotations) > 0 {
annotations = autoscalingListener.Spec.ConfigSecretMetadata.Annotations
}
return &corev1.Secret{ return &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: scaleSetListenerConfigName(autoscalingListener), Name: scaleSetListenerConfigName(autoscalingListener),
Namespace: autoscalingListener.Namespace, Namespace: autoscalingListener.Namespace,
Labels: labels,
Annotations: annotations,
}, },
Data: map[string][]byte{ Data: map[string][]byte{
"config.json": buf.Bytes(), "config.json": buf.Bytes(),
@@ -431,32 +452,49 @@ func mergeListenerContainer(base, from *corev1.Container) {
} }
func (b *ResourceBuilder) newScaleSetListenerServiceAccount(autoscalingListener *v1alpha1.AutoscalingListener) *corev1.ServiceAccount { func (b *ResourceBuilder) newScaleSetListenerServiceAccount(autoscalingListener *v1alpha1.AutoscalingListener) *corev1.ServiceAccount {
return &corev1.ServiceAccount{ base := &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: autoscalingListener.Name, Name: autoscalingListener.Name,
Namespace: autoscalingListener.Namespace, Namespace: autoscalingListener.Namespace,
Labels: b.mergeLabels(autoscalingListener.Labels, map[string]string{ Labels: b.filterAndMergeLabels(autoscalingListener.Labels, map[string]string{
LabelKeyGitHubScaleSetNamespace: autoscalingListener.Spec.AutoscalingRunnerSetNamespace, LabelKeyGitHubScaleSetNamespace: autoscalingListener.Spec.AutoscalingRunnerSetNamespace,
LabelKeyGitHubScaleSetName: autoscalingListener.Spec.AutoscalingRunnerSetName, LabelKeyGitHubScaleSetName: autoscalingListener.Spec.AutoscalingRunnerSetName,
}), }),
}, },
} }
if autoscalingListener.Spec.ServiceAccountMetadata != nil {
base.Labels = b.filterAndMergeLabels(autoscalingListener.Spec.ServiceAccountMetadata.Labels, base.Labels)
base.Annotations = b.mergeAnnotations(autoscalingListener.Spec.ServiceAccountMetadata.Annotations, base.Annotations)
}
return base
} }
func (b *ResourceBuilder) newScaleSetListenerRole(autoscalingListener *v1alpha1.AutoscalingListener) *rbacv1.Role { func (b *ResourceBuilder) newScaleSetListenerRole(autoscalingListener *v1alpha1.AutoscalingListener) *rbacv1.Role {
rules := rulesForListenerRole([]string{autoscalingListener.Spec.EphemeralRunnerSetName}) rules := rulesForListenerRole([]string{autoscalingListener.Spec.EphemeralRunnerSetName})
rulesHash := hash.ComputeTemplateHash(&rules) rulesHash := hash.ComputeTemplateHash(&rules)
labels := b.filterAndMergeLabels(autoscalingListener.Labels, map[string]string{
LabelKeyGitHubScaleSetNamespace: autoscalingListener.Spec.AutoscalingRunnerSetNamespace,
LabelKeyGitHubScaleSetName: autoscalingListener.Spec.AutoscalingRunnerSetName,
labelKeyListenerNamespace: autoscalingListener.Namespace,
labelKeyListenerName: autoscalingListener.Name,
"role-policy-rules-hash": rulesHash,
})
var annotations map[string]string
if autoscalingListener.Spec.RoleMetadata != nil {
labels = b.filterAndMergeLabels(autoscalingListener.Spec.RoleMetadata.Labels, labels)
annotations = b.mergeAnnotations(autoscalingListener.Spec.RoleMetadata.Annotations, nil)
}
newRole := &rbacv1.Role{ newRole := &rbacv1.Role{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: autoscalingListener.Name, Name: autoscalingListener.Name,
Namespace: autoscalingListener.Spec.AutoscalingRunnerSetNamespace, Namespace: autoscalingListener.Spec.AutoscalingRunnerSetNamespace,
Labels: b.mergeLabels(autoscalingListener.Labels, map[string]string{ Labels: labels,
LabelKeyGitHubScaleSetNamespace: autoscalingListener.Spec.AutoscalingRunnerSetNamespace, Annotations: annotations,
LabelKeyGitHubScaleSetName: autoscalingListener.Spec.AutoscalingRunnerSetName,
labelKeyListenerNamespace: autoscalingListener.Namespace,
labelKeyListenerName: autoscalingListener.Name,
"role-policy-rules-hash": rulesHash,
}),
}, },
Rules: rules, Rules: rules,
} }
@@ -480,18 +518,28 @@ func (b *ResourceBuilder) newScaleSetListenerRoleBinding(autoscalingListener *v1
} }
subjectHash := hash.ComputeTemplateHash(&subjects) subjectHash := hash.ComputeTemplateHash(&subjects)
labels := b.filterAndMergeLabels(autoscalingListener.Labels, map[string]string{
LabelKeyGitHubScaleSetNamespace: autoscalingListener.Spec.AutoscalingRunnerSetNamespace,
LabelKeyGitHubScaleSetName: autoscalingListener.Spec.AutoscalingRunnerSetName,
labelKeyListenerNamespace: autoscalingListener.Namespace,
labelKeyListenerName: autoscalingListener.Name,
"role-binding-role-ref-hash": roleRefHash,
"role-binding-subject-hash": subjectHash,
})
var annotations map[string]string
if autoscalingListener.Spec.RoleBindingMetadata != nil {
labels = b.filterAndMergeLabels(autoscalingListener.Spec.RoleBindingMetadata.Labels, labels)
annotations = autoscalingListener.Spec.RoleBindingMetadata.Annotations
}
newRoleBinding := &rbacv1.RoleBinding{ newRoleBinding := &rbacv1.RoleBinding{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: autoscalingListener.Name, Name: autoscalingListener.Name,
Namespace: autoscalingListener.Spec.AutoscalingRunnerSetNamespace, Namespace: autoscalingListener.Spec.AutoscalingRunnerSetNamespace,
Labels: b.mergeLabels(autoscalingListener.Labels, map[string]string{ Labels: labels,
LabelKeyGitHubScaleSetNamespace: autoscalingListener.Spec.AutoscalingRunnerSetNamespace, Annotations: annotations,
LabelKeyGitHubScaleSetName: autoscalingListener.Spec.AutoscalingRunnerSetName,
labelKeyListenerNamespace: autoscalingListener.Namespace,
labelKeyListenerName: autoscalingListener.Name,
"role-binding-role-ref-hash": roleRefHash,
"role-binding-subject-hash": subjectHash,
}),
}, },
RoleRef: roleRef, RoleRef: roleRef,
Subjects: subjects, Subjects: subjects,
@@ -507,7 +555,7 @@ func (b *ResourceBuilder) newEphemeralRunnerSet(autoscalingRunnerSet *v1alpha1.A
} }
runnerSpecHash := autoscalingRunnerSet.RunnerSetSpecHash() runnerSpecHash := autoscalingRunnerSet.RunnerSetSpecHash()
labels := b.mergeLabels(autoscalingRunnerSet.Labels, map[string]string{ labels := b.filterAndMergeLabels(autoscalingRunnerSet.Labels, map[string]string{
LabelKeyKubernetesPartOf: labelValueKubernetesPartOf, LabelKeyKubernetesPartOf: labelValueKubernetesPartOf,
LabelKeyKubernetesComponent: "runner-set", LabelKeyKubernetesComponent: "runner-set",
LabelKeyKubernetesVersion: autoscalingRunnerSet.Labels[LabelKeyKubernetesVersion], LabelKeyKubernetesVersion: autoscalingRunnerSet.Labels[LabelKeyKubernetesVersion],
@@ -519,19 +567,24 @@ func (b *ResourceBuilder) newEphemeralRunnerSet(autoscalingRunnerSet *v1alpha1.A
return nil, fmt.Errorf("failed to apply GitHub URL labels: %v", err) return nil, fmt.Errorf("failed to apply GitHub URL labels: %v", err)
} }
newAnnotations := map[string]string{ annotations := map[string]string{
AnnotationKeyGitHubRunnerGroupName: autoscalingRunnerSet.Annotations[AnnotationKeyGitHubRunnerGroupName], AnnotationKeyGitHubRunnerGroupName: autoscalingRunnerSet.Annotations[AnnotationKeyGitHubRunnerGroupName],
AnnotationKeyGitHubRunnerScaleSetName: autoscalingRunnerSet.Annotations[AnnotationKeyGitHubRunnerScaleSetName], AnnotationKeyGitHubRunnerScaleSetName: autoscalingRunnerSet.Annotations[AnnotationKeyGitHubRunnerScaleSetName],
annotationKeyRunnerSpecHash: runnerSpecHash, annotationKeyRunnerSpecHash: runnerSpecHash,
} }
if autoscalingRunnerSet.Spec.EphemeralRunnerSetMetadata != nil {
labels = b.filterAndMergeLabels(autoscalingRunnerSet.Spec.EphemeralRunnerSetMetadata.Labels, labels)
annotations = b.mergeAnnotations(autoscalingRunnerSet.Spec.EphemeralRunnerSetMetadata.Annotations, annotations)
}
newEphemeralRunnerSet := &v1alpha1.EphemeralRunnerSet{ newEphemeralRunnerSet := &v1alpha1.EphemeralRunnerSet{
TypeMeta: metav1.TypeMeta{}, TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
GenerateName: autoscalingRunnerSet.Name + "-", GenerateName: autoscalingRunnerSet.Name + "-",
Namespace: autoscalingRunnerSet.Namespace, Namespace: autoscalingRunnerSet.Namespace,
Labels: labels, Labels: labels,
Annotations: newAnnotations, Annotations: annotations,
OwnerReferences: []metav1.OwnerReference{ OwnerReferences: []metav1.OwnerReference{
{ {
APIVersion: autoscalingRunnerSet.GetObjectKind().GroupVersionKind().GroupVersion().String(), APIVersion: autoscalingRunnerSet.GetObjectKind().GroupVersionKind().GroupVersion().String(),
@@ -546,14 +599,16 @@ func (b *ResourceBuilder) newEphemeralRunnerSet(autoscalingRunnerSet *v1alpha1.A
Spec: v1alpha1.EphemeralRunnerSetSpec{ Spec: v1alpha1.EphemeralRunnerSetSpec{
Replicas: 0, Replicas: 0,
EphemeralRunnerSpec: v1alpha1.EphemeralRunnerSpec{ EphemeralRunnerSpec: v1alpha1.EphemeralRunnerSpec{
RunnerScaleSetId: runnerScaleSetID, RunnerScaleSetId: runnerScaleSetID,
GitHubConfigUrl: autoscalingRunnerSet.Spec.GitHubConfigUrl, GitHubConfigUrl: autoscalingRunnerSet.Spec.GitHubConfigUrl,
GitHubConfigSecret: autoscalingRunnerSet.Spec.GitHubConfigSecret, GitHubConfigSecret: autoscalingRunnerSet.Spec.GitHubConfigSecret,
Proxy: autoscalingRunnerSet.Spec.Proxy, Proxy: autoscalingRunnerSet.Spec.Proxy,
GitHubServerTLS: autoscalingRunnerSet.Spec.GitHubServerTLS, GitHubServerTLS: autoscalingRunnerSet.Spec.GitHubServerTLS,
PodTemplateSpec: autoscalingRunnerSet.Spec.Template, PodTemplateSpec: autoscalingRunnerSet.Spec.Template,
VaultConfig: autoscalingRunnerSet.VaultConfig(), VaultConfig: autoscalingRunnerSet.VaultConfig(),
EphemeralRunnerConfigSecretMetadata: autoscalingRunnerSet.Spec.EphemeralRunnerConfigSecretMetadata,
}, },
EphemeralRunnerMetadata: autoscalingRunnerSet.Spec.EphemeralRunnerMetadata,
}, },
} }
@@ -568,6 +623,12 @@ func (b *ResourceBuilder) newEphemeralRunner(ephemeralRunnerSet *v1alpha1.Epheme
annotations := make(map[string]string, len(ephemeralRunnerSet.Annotations)+1) annotations := make(map[string]string, len(ephemeralRunnerSet.Annotations)+1)
maps.Copy(annotations, ephemeralRunnerSet.Annotations) maps.Copy(annotations, ephemeralRunnerSet.Annotations)
annotations[AnnotationKeyPatchID] = strconv.Itoa(ephemeralRunnerSet.Spec.PatchID) annotations[AnnotationKeyPatchID] = strconv.Itoa(ephemeralRunnerSet.Spec.PatchID)
if ephemeralRunnerSet.Spec.EphemeralRunnerMetadata != nil {
labels = b.filterAndMergeLabels(ephemeralRunnerSet.Spec.EphemeralRunnerMetadata.Labels, labels)
annotations = b.mergeAnnotations(ephemeralRunnerSet.Spec.EphemeralRunnerMetadata.Annotations, annotations)
}
return &v1alpha1.EphemeralRunner{ return &v1alpha1.EphemeralRunner{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
GenerateName: ephemeralRunnerSet.Name + "-runner-", GenerateName: ephemeralRunnerSet.Name + "-runner-",
@@ -662,10 +723,22 @@ func (b *ResourceBuilder) newEphemeralRunnerPod(runner *v1alpha1.EphemeralRunner
} }
func (b *ResourceBuilder) newEphemeralRunnerJitSecret(ephemeralRunner *v1alpha1.EphemeralRunner, jitConfig *actions.RunnerScaleSetJitRunnerConfig) *corev1.Secret { func (b *ResourceBuilder) newEphemeralRunnerJitSecret(ephemeralRunner *v1alpha1.EphemeralRunner, jitConfig *actions.RunnerScaleSetJitRunnerConfig) *corev1.Secret {
var (
labels map[string]string
annotations map[string]string
)
if ephemeralRunner.Spec.EphemeralRunnerConfigSecretMetadata != nil {
labels = b.filterAndMergeLabels(ephemeralRunner.Spec.EphemeralRunnerConfigSecretMetadata.Labels, nil)
annotations = ephemeralRunner.Spec.EphemeralRunnerConfigSecretMetadata.Annotations
}
return &corev1.Secret{ return &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: ephemeralRunner.Name, Name: ephemeralRunner.Name,
Namespace: ephemeralRunner.Namespace, Namespace: ephemeralRunner.Namespace,
Labels: labels,
Annotations: annotations,
}, },
Data: map[string][]byte{ Data: map[string][]byte{
jitTokenKey: []byte(jitConfig.EncodedJITConfig), jitTokenKey: []byte(jitConfig.EncodedJITConfig),
@@ -756,9 +829,12 @@ func trimLabelValue(val string) string {
return strings.Trim(val, "-_.") return strings.Trim(val, "-_.")
} }
func (b *ResourceBuilder) mergeLabels(base, overwrite map[string]string) map[string]string { func (b *ResourceBuilder) filterAndMergeLabels(base, overwrite map[string]string) map[string]string {
mergedLabels := make(map[string]string, len(base)) if base == nil && overwrite == nil {
return nil
}
mergedLabels := make(map[string]string, len(base))
base: base:
for k, v := range base { for k, v := range base {
for _, prefix := range b.ExcludeLabelPropagationPrefixes { for _, prefix := range b.ExcludeLabelPropagationPrefixes {
@@ -781,3 +857,12 @@ overwrite:
return mergedLabels return mergedLabels
} }
func (b *ResourceBuilder) mergeAnnotations(base, overwrite map[string]string) map[string]string {
if base == nil && overwrite == nil {
return nil
}
base = maps.Clone(base)
maps.Copy(base, overwrite)
return base
}
@@ -6,13 +6,14 @@ import (
"testing" "testing"
"github.com/actions/actions-runner-controller/apis/actions.github.com/v1alpha1" "github.com/actions/actions-runner-controller/apis/actions.github.com/v1alpha1"
"github.com/actions/actions-runner-controller/github/actions"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
func TestLabelPropagation(t *testing.T) { func TestMetadataPropagation(t *testing.T) {
autoscalingRunnerSet := v1alpha1.AutoscalingRunnerSet{ autoscalingRunnerSet := v1alpha1.AutoscalingRunnerSet{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "test-scale-set", Name: "test-scale-set",
@@ -34,6 +35,70 @@ func TestLabelPropagation(t *testing.T) {
}, },
Spec: v1alpha1.AutoscalingRunnerSetSpec{ Spec: v1alpha1.AutoscalingRunnerSetSpec{
GitHubConfigUrl: "https://github.com/org/repo", GitHubConfigUrl: "https://github.com/org/repo",
AutoscalingListenerMetadata: &v1alpha1.ResourceMeta{
Labels: map[string]string{
"test.com/autoscaling-listener-label": "autoscaling-listener-label",
},
Annotations: map[string]string{
"test.com/autoscaling-listener-annotation": "autoscaling-listener-annotation",
},
},
ListenerServiceAccountMetadata: &v1alpha1.ResourceMeta{
Labels: map[string]string{
"test.com/listener-service-account-label": "listener-service-account-label",
},
Annotations: map[string]string{
"test.com/listener-service-account-annotation": "listener-service-account-annotation",
},
},
ListenerRoleMetadata: &v1alpha1.ResourceMeta{
Labels: map[string]string{
"test.com/listener-role-label": "listener-role-label",
},
Annotations: map[string]string{
"test.com/listener-role-annotation": "listener-role-annotation",
},
},
ListenerRoleBindingMetadata: &v1alpha1.ResourceMeta{
Labels: map[string]string{
"test.com/listener-role-binding-label": "listener-role-binding-label",
},
Annotations: map[string]string{
"test.com/listener-role-binding-annotation": "listener-role-binding-annotation",
},
},
ListenerConfigSecretMetadata: &v1alpha1.ResourceMeta{
Labels: map[string]string{
"test.com/listener-config-secret-label": "listener-config-secret-label",
},
Annotations: map[string]string{
"test.com/listener-config-secret-annotation": "listener-config-secret-annotation",
},
},
EphemeralRunnerSetMetadata: &v1alpha1.ResourceMeta{
Labels: map[string]string{
"test.com/ephemeral-runner-set-label": "ephemeral-runner-set-label",
},
Annotations: map[string]string{
"test.com/ephemeral-runner-set-annotation": "ephemeral-runner-set-annotation",
},
},
EphemeralRunnerMetadata: &v1alpha1.ResourceMeta{
Labels: map[string]string{
"test.com/ephemeral-runner-label": "ephemeral-runner-label",
},
Annotations: map[string]string{
"test.com/ephemeral-runner-annotation": "ephemeral-runner-annotation",
},
},
EphemeralRunnerConfigSecretMetadata: &v1alpha1.ResourceMeta{
Labels: map[string]string{
"test.com/ephemeral-runner-config-secret-label": "ephemeral-runner-config-secret-label",
},
Annotations: map[string]string{
"test.com/ephemeral-runner-config-secret-annotation": "ephemeral-runner-config-secret-annotation",
},
},
}, },
} }
@@ -57,6 +122,8 @@ func TestLabelPropagation(t *testing.T) {
assert.Equal(t, autoscalingRunnerSet.Annotations[AnnotationKeyGitHubRunnerGroupName], ephemeralRunnerSet.Annotations[AnnotationKeyGitHubRunnerGroupName]) assert.Equal(t, autoscalingRunnerSet.Annotations[AnnotationKeyGitHubRunnerGroupName], ephemeralRunnerSet.Annotations[AnnotationKeyGitHubRunnerGroupName])
assert.Equal(t, autoscalingRunnerSet.Annotations[AnnotationKeyGitHubRunnerScaleSetName], ephemeralRunnerSet.Annotations[AnnotationKeyGitHubRunnerScaleSetName]) assert.Equal(t, autoscalingRunnerSet.Annotations[AnnotationKeyGitHubRunnerScaleSetName], ephemeralRunnerSet.Annotations[AnnotationKeyGitHubRunnerScaleSetName])
assert.Equal(t, autoscalingRunnerSet.Labels["arbitrary-label"], ephemeralRunnerSet.Labels["arbitrary-label"]) assert.Equal(t, autoscalingRunnerSet.Labels["arbitrary-label"], ephemeralRunnerSet.Labels["arbitrary-label"])
assert.Equal(t, "ephemeral-runner-set-label", ephemeralRunnerSet.Labels["test.com/ephemeral-runner-set-label"])
assert.Equal(t, "ephemeral-runner-set-annotation", ephemeralRunnerSet.Annotations["test.com/ephemeral-runner-set-annotation"])
listener, err := b.newAutoScalingListener(&autoscalingRunnerSet, ephemeralRunnerSet, autoscalingRunnerSet.Namespace, "test:latest", nil) listener, err := b.newAutoScalingListener(&autoscalingRunnerSet, ephemeralRunnerSet, autoscalingRunnerSet.Namespace, "test:latest", nil)
require.NoError(t, err) require.NoError(t, err)
@@ -70,17 +137,26 @@ func TestLabelPropagation(t *testing.T) {
assert.Equal(t, "org", listener.Labels[LabelKeyGitHubOrganization]) assert.Equal(t, "org", listener.Labels[LabelKeyGitHubOrganization])
assert.Equal(t, "repo", listener.Labels[LabelKeyGitHubRepository]) assert.Equal(t, "repo", listener.Labels[LabelKeyGitHubRepository])
assert.Equal(t, autoscalingRunnerSet.Labels["arbitrary-label"], listener.Labels["arbitrary-label"]) assert.Equal(t, autoscalingRunnerSet.Labels["arbitrary-label"], listener.Labels["arbitrary-label"])
assert.Equal(t, "autoscaling-listener-label", listener.Labels["test.com/autoscaling-listener-label"])
assert.Equal(t, "autoscaling-listener-annotation", listener.Annotations["test.com/autoscaling-listener-annotation"])
assert.NotContains(t, listener.Labels, "example.com/label") assert.NotContains(t, listener.Labels, "example.com/label")
assert.NotContains(t, listener.Labels, "example.com/example") assert.NotContains(t, listener.Labels, "example.com/example")
assert.NotContains(t, listener.Labels, "directly.excluded.org/label") assert.NotContains(t, listener.Labels, "directly.excluded.org/label")
assert.Equal(t, "not-excluded-value", listener.Labels["directly.excluded.org/arbitrary"]) assert.Equal(t, "not-excluded-value", listener.Labels["directly.excluded.org/arbitrary"])
listenerServiceAccount := &corev1.ServiceAccount{ listenerServiceAccount := b.newScaleSetListenerServiceAccount(listener)
ObjectMeta: metav1.ObjectMeta{ assert.Equal(t, "listener-service-account-label", listenerServiceAccount.Labels["test.com/listener-service-account-label"])
Name: "test", assert.Equal(t, "listener-service-account-annotation", listenerServiceAccount.Annotations["test.com/listener-service-account-annotation"])
},
} listenerRole := b.newScaleSetListenerRole(listener)
assert.Equal(t, "listener-role-label", listenerRole.Labels["test.com/listener-role-label"])
assert.Equal(t, "listener-role-annotation", listenerRole.Annotations["test.com/listener-role-annotation"])
listenerRoleBinding := b.newScaleSetListenerRoleBinding(listener, listenerRole, listenerServiceAccount)
assert.Equal(t, "listener-role-binding-label", listenerRoleBinding.Labels["test.com/listener-role-binding-label"])
assert.Equal(t, "listener-role-binding-annotation", listenerRoleBinding.Annotations["test.com/listener-role-binding-annotation"])
listenerPod, err := b.newScaleSetListenerPod(listener, &corev1.Secret{}, listenerServiceAccount, nil) listenerPod, err := b.newScaleSetListenerPod(listener, &corev1.Secret{}, listenerServiceAccount, nil)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, listenerPod.Labels, listener.Labels) assert.Equal(t, listenerPod.Labels, listener.Labels)
@@ -97,12 +173,20 @@ func TestLabelPropagation(t *testing.T) {
assert.Equal(t, "runner", ephemeralRunner.Labels[LabelKeyKubernetesComponent]) assert.Equal(t, "runner", ephemeralRunner.Labels[LabelKeyKubernetesComponent])
assert.Equal(t, autoscalingRunnerSet.Annotations[AnnotationKeyGitHubRunnerGroupName], ephemeralRunner.Annotations[AnnotationKeyGitHubRunnerGroupName]) assert.Equal(t, autoscalingRunnerSet.Annotations[AnnotationKeyGitHubRunnerGroupName], ephemeralRunner.Annotations[AnnotationKeyGitHubRunnerGroupName])
assert.Equal(t, autoscalingRunnerSet.Annotations[AnnotationKeyGitHubRunnerScaleSetName], ephemeralRunnerSet.Annotations[AnnotationKeyGitHubRunnerScaleSetName]) assert.Equal(t, autoscalingRunnerSet.Annotations[AnnotationKeyGitHubRunnerScaleSetName], ephemeralRunnerSet.Annotations[AnnotationKeyGitHubRunnerScaleSetName])
assert.Equal(t, "ephemeral-runner-label", ephemeralRunner.Labels["test.com/ephemeral-runner-label"])
assert.Equal(t, "ephemeral-runner-annotation", ephemeralRunner.Annotations["test.com/ephemeral-runner-annotation"])
runnerSecret := &corev1.Secret{ runnerSecret := b.newEphemeralRunnerJitSecret(ephemeralRunner, &actions.RunnerScaleSetJitRunnerConfig{
ObjectMeta: metav1.ObjectMeta{ Runner: &actions.RunnerReference{
Name: "test", Id: 1,
Name: "test",
RunnerScaleSetId: 1,
}, },
} EncodedJITConfig: "",
})
assert.Equal(t, "ephemeral-runner-config-secret-label", runnerSecret.Labels["test.com/ephemeral-runner-config-secret-label"])
assert.Equal(t, "ephemeral-runner-config-secret-annotation", runnerSecret.Annotations["test.com/ephemeral-runner-config-secret-annotation"])
pod := b.newEphemeralRunnerPod(ephemeralRunner, runnerSecret) pod := b.newEphemeralRunnerPod(ephemeralRunner, runnerSecret)
for key := range ephemeralRunner.Labels { for key := range ephemeralRunner.Labels {
assert.Equal(t, ephemeralRunner.Labels[key], pod.Labels[key]) assert.Equal(t, ephemeralRunner.Labels[key], pod.Labels[key])