package manifests import ( "fmt" "path" "testing" lokiv1 "github.com/grafana/loki/operator/apis/loki/v1" "github.com/grafana/loki/operator/internal/manifests/internal/config" "github.com/stretchr/testify/require" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func TestNewQueryFrontendDeployment_SelectorMatchesLabels(t *testing.T) { ss := NewQueryFrontendDeployment(Options{ Name: "abcd", Namespace: "efgh", Stack: lokiv1.LokiStackSpec{ Template: &lokiv1.LokiTemplateSpec{ QueryFrontend: &lokiv1.LokiComponentSpec{ Replicas: 1, }, }, }, }) l := ss.Spec.Template.GetObjectMeta().GetLabels() for key, value := range ss.Spec.Selector.MatchLabels { require.Contains(t, l, key) require.Equal(t, l[key], value) } } func TestNewQueryFrontendDeployment_HasTemplateConfigHashAnnotation(t *testing.T) { ss := NewQueryFrontendDeployment(Options{ Name: "abcd", Namespace: "efgh", ConfigSHA1: "deadbeef", Stack: lokiv1.LokiStackSpec{ Template: &lokiv1.LokiTemplateSpec{ QueryFrontend: &lokiv1.LokiComponentSpec{ Replicas: 1, }, }, }, }) expected := "loki.grafana.com/config-hash" annotations := ss.Spec.Template.Annotations require.Contains(t, annotations, expected) require.Equal(t, annotations[expected], "deadbeef") } func TestConfigureQueryFrontendHTTPServicePKI(t *testing.T) { opts := Options{ Name: "abcd", Namespace: "efgh", Stack: lokiv1.LokiStackSpec{ Template: &lokiv1.LokiTemplateSpec{ QueryFrontend: &lokiv1.LokiComponentSpec{ Replicas: 1, }, }, }, TLSProfile: TLSProfileSpec{ MinTLSVersion: "TLSVersion1.2", Ciphers: []string{"TLS_RSA_WITH_AES_128_CBC_SHA"}, }, } d := appsv1.Deployment{ TypeMeta: metav1.TypeMeta{ Kind: "Deployment", APIVersion: appsv1.SchemeGroupVersion.String(), }, Spec: appsv1.DeploymentSpec{ Template: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{ { Name: lokiFrontendContainerName, Args: []string{ "-target=query-frontend", }, VolumeMounts: []corev1.VolumeMount{ { Name: configVolumeName, ReadOnly: false, MountPath: config.LokiConfigMountDir, }, }, }, }, Volumes: []corev1.Volume{ { Name: configVolumeName, VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ DefaultMode: &defaultConfigMapMode, LocalObjectReference: corev1.LocalObjectReference{ Name: lokiConfigMapName(opts.Name), }, }, }, }, }, }, }, }, } caBundleVolumeName := signingCABundleName(opts.Name) serviceName := serviceNameQueryFrontendHTTP(opts.Name) expected := appsv1.Deployment{ TypeMeta: metav1.TypeMeta{ Kind: "Deployment", APIVersion: appsv1.SchemeGroupVersion.String(), }, Spec: appsv1.DeploymentSpec{ Template: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ Containers: []corev1.Container{ { Name: lokiFrontendContainerName, Args: []string{ "-target=query-frontend", "-frontend.tail-tls-config.tls-cipher-suites=TLS_RSA_WITH_AES_128_CBC_SHA", "-frontend.tail-tls-config.tls-min-version=TLSVersion1.2", fmt.Sprintf("-frontend.tail-tls-config.tls-ca-path=%s/%s", caBundleDir, caFile), fmt.Sprintf("-server.http-tls-cert-path=%s", path.Join(httpTLSDir, tlsCertFile)), fmt.Sprintf("-server.http-tls-key-path=%s", path.Join(httpTLSDir, tlsKeyFile)), }, VolumeMounts: []corev1.VolumeMount{ { Name: configVolumeName, ReadOnly: false, MountPath: config.LokiConfigMountDir, }, { Name: caBundleVolumeName, ReadOnly: true, MountPath: caBundleDir, }, { Name: serviceName, ReadOnly: false, MountPath: httpTLSDir, }, }, ReadinessProbe: &corev1.Probe{ ProbeHandler: corev1.ProbeHandler{ HTTPGet: &corev1.HTTPGetAction{ Scheme: corev1.URISchemeHTTPS, }, }, }, LivenessProbe: &corev1.Probe{ ProbeHandler: corev1.ProbeHandler{ HTTPGet: &corev1.HTTPGetAction{ Scheme: corev1.URISchemeHTTPS, }, }, }, }, }, Volumes: []corev1.Volume{ { Name: configVolumeName, VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ DefaultMode: &defaultConfigMapMode, LocalObjectReference: corev1.LocalObjectReference{ Name: lokiConfigMapName(opts.Name), }, }, }, }, { Name: caBundleVolumeName, VolumeSource: corev1.VolumeSource{ ConfigMap: &corev1.ConfigMapVolumeSource{ DefaultMode: &defaultConfigMapMode, LocalObjectReference: corev1.LocalObjectReference{ Name: caBundleVolumeName, }, }, }, }, { Name: serviceName, VolumeSource: corev1.VolumeSource{ Secret: &corev1.SecretVolumeSource{ SecretName: serviceName, }, }, }, }, }, }, }, } err := configureQueryFrontendHTTPServicePKI(&d, opts) require.Nil(t, err) require.Equal(t, expected, d) }