diff --git a/api/v1alpha1/flowcollector_webhook.go b/api/v1alpha1/flowcollector_webhook.go
index 0d6a9dc63..e993f5ef8 100644
--- a/api/v1alpha1/flowcollector_webhook.go
+++ b/api/v1alpha1/flowcollector_webhook.go
@@ -57,6 +57,8 @@ func (r *FlowCollector) ConvertTo(dstRaw conversion.Hub) error {
dst.Spec.Processor.Metrics.DisableAlerts = restored.Spec.Processor.Metrics.DisableAlerts
}
+ dst.Spec.Loki.StatusTLS = restored.Spec.Loki.StatusTLS
+
return nil
}
@@ -100,3 +102,10 @@ func Convert_v1beta1_FlowCollectorFLP_To_v1alpha1_FlowCollectorFLP(in *v1beta1.F
func Convert_v1beta1_FLPMetrics_To_v1alpha1_FLPMetrics(in *v1beta1.FLPMetrics, out *FLPMetrics, s apiconversion.Scope) error {
return autoConvert_v1beta1_FLPMetrics_To_v1alpha1_FLPMetrics(in, out, s)
}
+
+// This function need to be manually created because conversion-gen not able to create it intentionally because
+// we have new defined fields in v1beta1 not in v1alpha1
+// nolint:golint,stylecheck,revive
+func Convert_v1beta1_FlowCollectorLoki_To_v1alpha1_FlowCollectorLoki(in *v1beta1.FlowCollectorLoki, out *FlowCollectorLoki, s apiconversion.Scope) error {
+ return autoConvert_v1beta1_FlowCollectorLoki_To_v1alpha1_FlowCollectorLoki(in, out, s)
+}
diff --git a/api/v1alpha1/zz_generated.conversion.go b/api/v1alpha1/zz_generated.conversion.go
index fbf944af9..f6d827c6e 100644
--- a/api/v1alpha1/zz_generated.conversion.go
+++ b/api/v1alpha1/zz_generated.conversion.go
@@ -193,11 +193,6 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
- if err := s.AddGeneratedConversionFunc((*v1beta1.FlowCollectorLoki)(nil), (*FlowCollectorLoki)(nil), func(a, b interface{}, scope conversion.Scope) error {
- return Convert_v1beta1_FlowCollectorLoki_To_v1alpha1_FlowCollectorLoki(a.(*v1beta1.FlowCollectorLoki), b.(*FlowCollectorLoki), scope)
- }); err != nil {
- return err
- }
if err := s.AddGeneratedConversionFunc((*FlowCollectorSpec)(nil), (*v1beta1.FlowCollectorSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha1_FlowCollectorSpec_To_v1beta1_FlowCollectorSpec(a.(*FlowCollectorSpec), b.(*v1beta1.FlowCollectorSpec), scope)
}); err != nil {
@@ -268,6 +263,11 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
+ if err := s.AddConversionFunc((*v1beta1.FlowCollectorLoki)(nil), (*FlowCollectorLoki)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_v1beta1_FlowCollectorLoki_To_v1alpha1_FlowCollectorLoki(a.(*v1beta1.FlowCollectorLoki), b.(*FlowCollectorLoki), scope)
+ }); err != nil {
+ return err
+ }
return nil
}
@@ -823,14 +823,10 @@ func autoConvert_v1beta1_FlowCollectorLoki_To_v1alpha1_FlowCollectorLoki(in *v1b
if err := Convert_v1beta1_ClientTLS_To_v1alpha1_ClientTLS(&in.TLS, &out.TLS, s); err != nil {
return err
}
+ // WARNING: in.StatusTLS requires manual conversion: does not exist in peer-type
return nil
}
-// Convert_v1beta1_FlowCollectorLoki_To_v1alpha1_FlowCollectorLoki is an autogenerated conversion function.
-func Convert_v1beta1_FlowCollectorLoki_To_v1alpha1_FlowCollectorLoki(in *v1beta1.FlowCollectorLoki, out *FlowCollectorLoki, s conversion.Scope) error {
- return autoConvert_v1beta1_FlowCollectorLoki_To_v1alpha1_FlowCollectorLoki(in, out, s)
-}
-
func autoConvert_v1alpha1_FlowCollectorSpec_To_v1beta1_FlowCollectorSpec(in *FlowCollectorSpec, out *v1beta1.FlowCollectorSpec, s conversion.Scope) error {
out.Namespace = in.Namespace
if err := Convert_v1alpha1_FlowCollectorAgent_To_v1beta1_FlowCollectorAgent(&in.Agent, &out.Agent, s); err != nil {
diff --git a/api/v1beta1/flowcollector_types.go b/api/v1beta1/flowcollector_types.go
index 819edde96..8ff0024b3 100644
--- a/api/v1beta1/flowcollector_types.go
+++ b/api/v1beta1/flowcollector_types.go
@@ -462,6 +462,7 @@ type FlowCollectorLoki struct {
// This is useful to show error messages and some context in the frontend.
// When using the Loki Operator, set it to the Loki HTTP query frontend service, for example
// https://loki-query-frontend-http.netobserv.svc:3100/.
+ // statusTLS configuration will be used when statusUrl is set.
StatusURL string `json:"statusUrl,omitempty"`
//+kubebuilder:default:="netobserv"
@@ -509,9 +510,13 @@ type FlowCollectorLoki struct {
// staticLabels is a map of common labels to set on each flow.
StaticLabels map[string]string `json:"staticLabels,omitempty"`
- // tls client configuration.
+ // tls client configuration for loki URL.
// +optional
TLS ClientTLS `json:"tls"`
+
+ // tls client configuration for loki status URL.
+ // +optional
+ StatusTLS ClientTLS `json:"statusTls"`
}
// FlowCollectorConsolePlugin defines the desired ConsolePlugin state of FlowCollector
diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go
index 0bb0e8956..ad2bcc39f 100644
--- a/api/v1beta1/zz_generated.deepcopy.go
+++ b/api/v1beta1/zz_generated.deepcopy.go
@@ -402,6 +402,7 @@ func (in *FlowCollectorLoki) DeepCopyInto(out *FlowCollectorLoki) {
}
}
out.TLS = in.TLS
+ out.StatusTLS = in.StatusTLS
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlowCollectorLoki.
diff --git a/bundle/manifests/flows.netobserv.io_flowcollectors.yaml b/bundle/manifests/flows.netobserv.io_flowcollectors.yaml
index 13fdd65b4..ef3a18802 100644
--- a/bundle/manifests/flows.netobserv.io_flowcollectors.yaml
+++ b/bundle/manifests/flows.netobserv.io_flowcollectors.yaml
@@ -3363,6 +3363,71 @@ spec:
description: staticLabels is a map of common labels to set on
each flow.
type: object
+ statusTls:
+ description: tls client configuration for loki status URL.
+ properties:
+ caCert:
+ description: caCert defines the reference of the certificate
+ for the Certificate Authority
+ properties:
+ certFile:
+ description: certFile defines the path to the certificate
+ file name within the config map or secret
+ type: string
+ certKey:
+ description: certKey defines the path to the certificate
+ private key file name within the config map or secret.
+ Omit when the key is not necessary.
+ type: string
+ name:
+ description: name of the config map or secret containing
+ certificates
+ type: string
+ type:
+ description: 'type for the certificate reference: "configmap"
+ or "secret"'
+ enum:
+ - configmap
+ - secret
+ type: string
+ type: object
+ enable:
+ default: false
+ description: enable TLS
+ type: boolean
+ insecureSkipVerify:
+ default: false
+ description: insecureSkipVerify allows skipping client-side
+ verification of the server certificate If set to true, CACert
+ field will be ignored
+ type: boolean
+ userCert:
+ description: userCert defines the user certificate reference,
+ used for mTLS (you can ignore it when using regular, one-way
+ TLS)
+ properties:
+ certFile:
+ description: certFile defines the path to the certificate
+ file name within the config map or secret
+ type: string
+ certKey:
+ description: certKey defines the path to the certificate
+ private key file name within the config map or secret.
+ Omit when the key is not necessary.
+ type: string
+ name:
+ description: name of the config map or secret containing
+ certificates
+ type: string
+ type:
+ description: 'type for the certificate reference: "configmap"
+ or "secret"'
+ enum:
+ - configmap
+ - secret
+ type: string
+ type: object
+ type: object
statusUrl:
description: statusURL specifies the address of the Loki /ready
/metrics /config endpoints, in case it is different from the
@@ -3370,6 +3435,7 @@ spec:
This is useful to show error messages and some context in the
frontend. When using the Loki Operator, set it to the Loki HTTP
query frontend service, for example https://loki-query-frontend-http.netobserv.svc:3100/.
+ statusTLS configuration will be used when statusUrl is set.
type: string
tenantID:
default: netobserv
@@ -3383,7 +3449,7 @@ spec:
limit. A Timeout of zero means no timeout.
type: string
tls:
- description: tls client configuration.
+ description: tls client configuration for loki URL.
properties:
caCert:
description: caCert defines the reference of the certificate
diff --git a/bundle/manifests/netobserv-operator.clusterserviceversion.yaml b/bundle/manifests/netobserv-operator.clusterserviceversion.yaml
index d9f8a3b5e..59e8339b4 100644
--- a/bundle/manifests/netobserv-operator.clusterserviceversion.yaml
+++ b/bundle/manifests/netobserv-operator.clusterserviceversion.yaml
@@ -282,6 +282,21 @@ metadata:
"maxBackoff": "5s",
"maxRetries": 2,
"minBackoff": "1s",
+ "statusTls": {
+ "caCert": {
+ "certFile": "service-ca.crt",
+ "name": "loki-ca-bundle",
+ "type": "configmap"
+ },
+ "enable": false,
+ "insecureSkipVerify": false,
+ "userCert": {
+ "certFile": "tls.crt",
+ "certKey": "tls.key",
+ "name": "loki-query-frontend-http",
+ "type": "secret"
+ }
+ },
"tls": {
"caCert": {
"certFile": "service-ca.crt",
diff --git a/config/crd/bases/flows.netobserv.io_flowcollectors.yaml b/config/crd/bases/flows.netobserv.io_flowcollectors.yaml
index 99c201e0d..9e1009774 100644
--- a/config/crd/bases/flows.netobserv.io_flowcollectors.yaml
+++ b/config/crd/bases/flows.netobserv.io_flowcollectors.yaml
@@ -3350,6 +3350,71 @@ spec:
description: staticLabels is a map of common labels to set on
each flow.
type: object
+ statusTls:
+ description: tls client configuration for loki status URL.
+ properties:
+ caCert:
+ description: caCert defines the reference of the certificate
+ for the Certificate Authority
+ properties:
+ certFile:
+ description: certFile defines the path to the certificate
+ file name within the config map or secret
+ type: string
+ certKey:
+ description: certKey defines the path to the certificate
+ private key file name within the config map or secret.
+ Omit when the key is not necessary.
+ type: string
+ name:
+ description: name of the config map or secret containing
+ certificates
+ type: string
+ type:
+ description: 'type for the certificate reference: "configmap"
+ or "secret"'
+ enum:
+ - configmap
+ - secret
+ type: string
+ type: object
+ enable:
+ default: false
+ description: enable TLS
+ type: boolean
+ insecureSkipVerify:
+ default: false
+ description: insecureSkipVerify allows skipping client-side
+ verification of the server certificate If set to true, CACert
+ field will be ignored
+ type: boolean
+ userCert:
+ description: userCert defines the user certificate reference,
+ used for mTLS (you can ignore it when using regular, one-way
+ TLS)
+ properties:
+ certFile:
+ description: certFile defines the path to the certificate
+ file name within the config map or secret
+ type: string
+ certKey:
+ description: certKey defines the path to the certificate
+ private key file name within the config map or secret.
+ Omit when the key is not necessary.
+ type: string
+ name:
+ description: name of the config map or secret containing
+ certificates
+ type: string
+ type:
+ description: 'type for the certificate reference: "configmap"
+ or "secret"'
+ enum:
+ - configmap
+ - secret
+ type: string
+ type: object
+ type: object
statusUrl:
description: statusURL specifies the address of the Loki /ready
/metrics /config endpoints, in case it is different from the
@@ -3357,6 +3422,7 @@ spec:
This is useful to show error messages and some context in the
frontend. When using the Loki Operator, set it to the Loki HTTP
query frontend service, for example https://loki-query-frontend-http.netobserv.svc:3100/.
+ statusTLS configuration will be used when statusUrl is set.
type: string
tenantID:
default: netobserv
@@ -3370,7 +3436,7 @@ spec:
limit. A Timeout of zero means no timeout.
type: string
tls:
- description: tls client configuration.
+ description: tls client configuration for loki URL.
properties:
caCert:
description: caCert defines the reference of the certificate
diff --git a/config/samples/flows_v1alpha1_flowcollector.yaml b/config/samples/flows_v1alpha1_flowcollector.yaml
index 340bef399..4cf751bad 100644
--- a/config/samples/flows_v1alpha1_flowcollector.yaml
+++ b/config/samples/flows_v1alpha1_flowcollector.yaml
@@ -62,6 +62,7 @@ spec:
loki:
url: 'http://loki.netobserv.svc:3100/'
# Uncomment lines below for typical installation with loki-operator (5.6+ needed)
+ # and ensure tls is enabled
# url: 'https://loki-gateway-http.netobserv.svc:8080/api/logs/v1/network/'
# statusUrl: 'https://loki-query-frontend-http.netobserv.svc:3100/'
# authToken: HOST
diff --git a/config/samples/flows_v1beta1_flowcollector.yaml b/config/samples/flows_v1beta1_flowcollector.yaml
index 098c6cda9..5930fb606 100644
--- a/config/samples/flows_v1beta1_flowcollector.yaml
+++ b/config/samples/flows_v1beta1_flowcollector.yaml
@@ -66,9 +66,10 @@ spec:
loki:
url: 'http://loki.netobserv.svc:3100/'
# Uncomment lines below for typical installation with loki-operator (5.6+ needed)
+ # and ensure tls and statusTls are enabled
# url: 'https://loki-gateway-http.netobserv.svc:8080/api/logs/v1/network/'
# statusUrl: 'https://loki-query-frontend-http.netobserv.svc:3100/'
- # authToken: HOST
+ # authToken: FORWARD
tls:
enable: false
caCert:
@@ -76,6 +77,18 @@ spec:
name: loki-gateway-ca-bundle
certFile: service-ca.crt
insecureSkipVerify: false
+ statusTls:
+ enable: false
+ caCert:
+ certFile: service-ca.crt
+ name: loki-ca-bundle
+ type: configmap
+ insecureSkipVerify: false
+ userCert:
+ certFile: tls.crt
+ certKey: tls.key
+ name: loki-query-frontend-http
+ type: secret
batchWait: 1s
batchSize: 10485760
minBackoff: 1s
diff --git a/controllers/consoleplugin/consoleplugin_objects.go b/controllers/consoleplugin/consoleplugin_objects.go
index 57a4dce84..23d01b3da 100644
--- a/controllers/consoleplugin/consoleplugin_objects.go
+++ b/controllers/consoleplugin/consoleplugin_objects.go
@@ -30,6 +30,7 @@ const configFile = "config.yaml"
const configVolume = "config-volume"
const configPath = "/opt/app-root/"
const lokiCerts = "loki-certs"
+const lokiStatusCerts = "loki-status-certs"
const tokensPath = "/var/run/secrets/tokens/"
type builder struct {
@@ -181,9 +182,21 @@ func buildArgs(desired *flowslatest.FlowCollectorSpec) []string {
if desired.Loki.TLS.InsecureSkipVerify {
args = append(args, "-loki-skip-tls")
} else {
- args = append(args, "--loki-ca-path", helper.GetCACertPath(&desired.Loki.TLS, lokiCerts))
+ args = append(args, "-loki-ca-path", helper.GetCACertPath(&desired.Loki.TLS, lokiCerts))
}
}
+
+ statusTLS := helper.GetLokiStatusTLS(&desired.Loki)
+ if statusTLS.Enable {
+ if statusTLS.InsecureSkipVerify {
+ args = append(args, "-loki-status-skip-tls")
+ } else {
+ args = append(args, "-loki-status-ca-path", helper.GetCACertPath(&statusTLS, lokiStatusCerts))
+ args = append(args, "-loki-status-user-cert-path", helper.GetUserCertPath(&statusTLS, lokiStatusCerts))
+ args = append(args, "-loki-status-user-key-path", helper.GetUserKeyPath(&statusTLS, lokiStatusCerts))
+ }
+ }
+
if helper.LokiUseHostToken(&desired.Loki) {
args = append(args, "-loki-token-path", tokenPath(&desired.Loki))
}
@@ -226,6 +239,11 @@ func (b *builder) podTemplate(cmDigest string) *corev1.PodTemplateSpec {
volumes, volumeMounts = helper.AppendCertVolumes(volumes, volumeMounts, &b.desired.Loki.TLS, lokiCerts, b.cWatcher)
}
+ statusTLS := helper.GetLokiStatusTLS(&b.desired.Loki)
+ if b.desired != nil && statusTLS.Enable && !statusTLS.InsecureSkipVerify {
+ volumes, volumeMounts = helper.AppendCertVolumes(volumes, volumeMounts, &statusTLS, lokiStatusCerts, b.cWatcher)
+ }
+
if helper.LokiUseHostToken(&b.desired.Loki) {
volumes, volumeMounts = helper.AppendTokenVolume(volumes, volumeMounts, constants.PluginName, constants.PluginName)
}
diff --git a/controllers/consoleplugin/consoleplugin_reconciler.go b/controllers/consoleplugin/consoleplugin_reconciler.go
index 6cad122c5..8cde07b81 100644
--- a/controllers/consoleplugin/consoleplugin_reconciler.go
+++ b/controllers/consoleplugin/consoleplugin_reconciler.go
@@ -197,7 +197,7 @@ func (r *CPReconciler) reconcileDeployment(ctx context.Context, builder builder,
newDepl := builder.deployment(cmDigest)
// Annotate pod with certificate reference so that it is reloaded if modified
- if err := r.CertWatcher.AnnotatePod(ctx, r.Client, &newDepl.Spec.Template, lokiCerts); err != nil {
+ if err := r.CertWatcher.AnnotatePod(ctx, r.Client, &newDepl.Spec.Template, lokiCerts, lokiStatusCerts); err != nil {
return err
}
if !r.nobjMngr.Exists(r.owned.deployment) {
diff --git a/controllers/consoleplugin/consoleplugin_test.go b/controllers/consoleplugin/consoleplugin_test.go
index 6ceb76363..e66793285 100644
--- a/controllers/consoleplugin/consoleplugin_test.go
+++ b/controllers/consoleplugin/consoleplugin_test.go
@@ -188,6 +188,49 @@ func TestContainerUpdateCheck(t *testing.T) {
report = helper.NewChangeReport("")
assert.False(helper.PodChanged(&old.Spec.Template, &new.Spec.Template, constants.PluginName, &report))
assert.Contains(report.String(), "no change")
+ old = new
+
+ //set status url and enable default tls
+ loki.StatusURL = "http://loki.status:3100/"
+ loki.StatusTLS.Enable = true
+
+ spec = flowslatest.FlowCollectorSpec{ConsolePlugin: plugin, Loki: loki}
+ builder = newBuilder(testNamespace, testImage, &spec, &certWatcher)
+ new = builder.deployment("digest")
+ report = helper.NewChangeReport("")
+ assert.True(helper.PodChanged(&old.Spec.Template, &new.Spec.Template, constants.PluginName, &report))
+ assert.Contains(report.String(), "Container changed")
+ old = new
+
+ //update status ca cert
+ loki.StatusTLS.CACert = flowslatest.CertificateReference{
+ Type: "configmap",
+ Name: "status-cm-name",
+ CertFile: "status-ca.crt",
+ }
+
+ spec = flowslatest.FlowCollectorSpec{ConsolePlugin: plugin, Loki: loki}
+ builder = newBuilder(testNamespace, testImage, &spec, &certWatcher)
+ new = builder.deployment("digest")
+ report = helper.NewChangeReport("")
+ assert.True(helper.PodChanged(&old.Spec.Template, &new.Spec.Template, constants.PluginName, &report))
+ assert.Contains(report.String(), "Volumes changed")
+ old = new
+
+ //update status user cert
+ loki.StatusTLS.UserCert = flowslatest.CertificateReference{
+ Type: "secret",
+ Name: "sec-name",
+ CertFile: "tls.crt",
+ CertKey: "tls.key",
+ }
+
+ spec = flowslatest.FlowCollectorSpec{ConsolePlugin: plugin, Loki: loki}
+ builder = newBuilder(testNamespace, testImage, &spec, &certWatcher)
+ new = builder.deployment("digest")
+ report = helper.NewChangeReport("")
+ assert.True(helper.PodChanged(&old.Spec.Template, &new.Spec.Template, constants.PluginName, &report))
+ assert.Contains(report.String(), "Volumes changed")
}
func TestServiceUpdateCheck(t *testing.T) {
diff --git a/docs/FlowCollector.md b/docs/FlowCollector.md
index 7b61c18a2..bc09165c5 100644
--- a/docs/FlowCollector.md
+++ b/docs/FlowCollector.md
@@ -5952,11 +5952,18 @@ loki, the flow store, client settings.
Default: map[app:netobserv-flowcollector]
Name | +Type | +Description | +Required | +
---|---|---|---|
caCert | +object | +
+ caCert defines the reference of the certificate for the Certificate Authority + |
+ false | +
enable | +boolean | +
+ enable TLS + + Default: false + |
+ false | +
insecureSkipVerify | +boolean | +
+ insecureSkipVerify allows skipping client-side verification of the server certificate If set to true, CACert field will be ignored + + Default: false + |
+ false | +
userCert | +object | +
+ userCert defines the user certificate reference, used for mTLS (you can ignore it when using regular, one-way TLS) + |
+ false | +
Name | +Type | +Description | +Required | +
---|---|---|---|
certFile | +string | +
+ certFile defines the path to the certificate file name within the config map or secret + |
+ false | +
certKey | +string | +
+ certKey defines the path to the certificate private key file name within the config map or secret. Omit when the key is not necessary. + |
+ false | +
name | +string | +
+ name of the config map or secret containing certificates + |
+ false | +
type | +enum | +
+ type for the certificate reference: "configmap" or "secret" + + Enum: configmap, secret + |
+ false | +
Name | +Type | +Description | +Required | +
---|---|---|---|
certFile | +string | +
+ certFile defines the path to the certificate file name within the config map or secret + |
+ false | +
certKey | +string | +
+ certKey defines the path to the certificate private key file name within the config map or secret. Omit when the key is not necessary. + |
+ false | +
name | +string | +
+ name of the config map or secret containing certificates + |
+ false | +
type | +enum | +
+ type for the certificate reference: "configmap" or "secret" + + Enum: configmap, secret + |
+ false | +