operator: Add rules labels filters for openshift application tenant (#9600)

Co-authored-by: Mohamed-Amine Bouqsimi <bouqsimiamine@gmail.com>
pull/9751/head
Periklis Tsirakidis 2 years ago committed by GitHub
parent 24e9efb907
commit 89a094c5fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      operator/CHANGELOG.md
  2. 1
      operator/internal/manifests/build.go
  3. 7
      operator/internal/manifests/gateway.go
  4. 11
      operator/internal/manifests/gateway_tenants.go
  5. 1
      operator/internal/manifests/gateway_test.go
  6. 27
      operator/internal/manifests/openshift/alertingrule.go
  7. 195
      operator/internal/manifests/openshift/alertingrule_test.go
  8. 24
      operator/internal/manifests/openshift/configure.go
  9. 18
      operator/internal/manifests/rules_config.go

@ -1,5 +1,6 @@
## Main ## Main
- [9600](https://github.com/grafana/loki/pull/9600) **periklis**: Add rules labels filters for openshift-logging application tenant
- [9735](https://github.com/grafana/loki/pull/9735) **JoaoBraveCoding** Adjust 1x.extra-small resources according to findings - [9735](https://github.com/grafana/loki/pull/9735) **JoaoBraveCoding** Adjust 1x.extra-small resources according to findings
- [9689](https://github.com/grafana/loki/pull/9689) **xperimental**: Fix availability of demo LokiStack size - [9689](https://github.com/grafana/loki/pull/9689) **xperimental**: Fix availability of demo LokiStack size
- [9630](https://github.com/grafana/loki/pull/9630) **jpinsonneau**: Expose per_stream_rate_limit & burst - [9630](https://github.com/grafana/loki/pull/9630) **jpinsonneau**: Expose per_stream_rate_limit & burst

@ -61,7 +61,6 @@ func BuildAll(opts Options) ([]client.Object, error) {
res = append(res, BuildLokiGossipRingService(opts.Name)) res = append(res, BuildLokiGossipRingService(opts.Name))
if opts.Stack.Rules != nil && opts.Stack.Rules.Enabled { if opts.Stack.Rules != nil && opts.Stack.Rules.Enabled {
rulesCMShards, err := RulesConfigMapShards(&opts) rulesCMShards, err := RulesConfigMapShards(&opts)
if err != nil { if err != nil {
return nil, err return nil, err

@ -56,6 +56,13 @@ func BuildGateway(opts Options) ([]client.Object, error) {
if err := configureGatewayRulesAPI(&dpl.Spec.Template.Spec, opts.Name, opts.Namespace); err != nil { if err := configureGatewayRulesAPI(&dpl.Spec.Template.Spec, opts.Name, opts.Namespace); err != nil {
return nil, err return nil, err
} }
if opts.Stack.Tenants != nil {
mode := opts.Stack.Tenants.Mode
if err := configureGatewayDeploymentRulesAPIForMode(dpl, mode); err != nil {
return nil, err
}
}
} }
if opts.Gates.HTTPEncryption { if opts.Gates.HTTPEncryption {

@ -74,6 +74,17 @@ func configureGatewayDeploymentForMode(d *appsv1.Deployment, mode lokiv1.ModeTyp
return nil return nil
} }
func configureGatewayDeploymentRulesAPIForMode(d *appsv1.Deployment, mode lokiv1.ModeType) error {
switch mode {
case lokiv1.Static, lokiv1.Dynamic, lokiv1.OpenshiftNetwork:
return nil // nothing to configure
case lokiv1.OpenshiftLogging:
return openshift.ConfigureGatewayDeploymentRulesAPI(d, gatewayContainerName)
}
return nil
}
func configureGatewayServiceForMode(s *corev1.ServiceSpec, mode lokiv1.ModeType) error { func configureGatewayServiceForMode(s *corev1.ServiceSpec, mode lokiv1.ModeType) error {
switch mode { switch mode {
case lokiv1.Static, lokiv1.Dynamic: case lokiv1.Static, lokiv1.Dynamic:

@ -690,6 +690,7 @@ func TestBuildGateway_WithRulesEnabled(t *testing.T) {
wantArgs: []string{ wantArgs: []string{
"--logs.rules.endpoint=https://abcd-ruler-http.efgh.svc.cluster.local:3100", "--logs.rules.endpoint=https://abcd-ruler-http.efgh.svc.cluster.local:3100",
"--logs.rules.read-only=true", "--logs.rules.read-only=true",
"--logs.rules.label-filters=application:kubernetes_namespace_name",
}, },
}, },
{ {

@ -0,0 +1,27 @@
package openshift
import lokiv1 "github.com/grafana/loki/operator/apis/loki/v1"
func AlertingRuleTenantLabels(ar *lokiv1.AlertingRule) {
switch ar.Spec.TenantID {
case tenantApplication:
for groupIdx, group := range ar.Spec.Groups {
group := group
for ruleIdx, rule := range group.Rules {
rule := rule
if rule.Labels == nil {
rule.Labels = map[string]string{}
}
rule.Labels[opaDefaultLabelMatcher] = ar.Namespace
group.Rules[ruleIdx] = rule
}
ar.Spec.Groups[groupIdx] = group
}
case tenantInfrastructure, tenantAudit:
// Do nothing
case tenantNetwork:
// Do nothing
default:
// Do nothing
}
}

@ -0,0 +1,195 @@
package openshift
import (
"testing"
lokiv1 "github.com/grafana/loki/operator/apis/loki/v1"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func TestAlertingRuleTenantLabels(t *testing.T) {
tt := []struct {
rule *lokiv1.AlertingRule
want *lokiv1.AlertingRule
}{
{
rule: &lokiv1.AlertingRule{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test-ns",
},
Spec: lokiv1.AlertingRuleSpec{
TenantID: tenantApplication,
Groups: []*lokiv1.AlertingRuleGroup{
{
Name: "test-group",
Rules: []*lokiv1.AlertingRuleGroupSpec{
{
Alert: "alert",
},
},
},
},
},
},
want: &lokiv1.AlertingRule{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test-ns",
},
Spec: lokiv1.AlertingRuleSpec{
TenantID: tenantApplication,
Groups: []*lokiv1.AlertingRuleGroup{
{
Name: "test-group",
Rules: []*lokiv1.AlertingRuleGroupSpec{
{
Alert: "alert",
Labels: map[string]string{
opaDefaultLabelMatcher: "test-ns",
},
},
},
},
},
},
},
},
{
rule: &lokiv1.AlertingRule{
Spec: lokiv1.AlertingRuleSpec{
TenantID: tenantInfrastructure,
Groups: []*lokiv1.AlertingRuleGroup{
{
Name: "test-group",
Rules: []*lokiv1.AlertingRuleGroupSpec{
{
Alert: "alert",
},
},
},
},
},
},
want: &lokiv1.AlertingRule{
Spec: lokiv1.AlertingRuleSpec{
TenantID: tenantInfrastructure,
Groups: []*lokiv1.AlertingRuleGroup{
{
Name: "test-group",
Rules: []*lokiv1.AlertingRuleGroupSpec{
{
Alert: "alert",
},
},
},
},
},
},
},
{
rule: &lokiv1.AlertingRule{
Spec: lokiv1.AlertingRuleSpec{
TenantID: tenantAudit,
Groups: []*lokiv1.AlertingRuleGroup{
{
Name: "test-group",
Rules: []*lokiv1.AlertingRuleGroupSpec{
{
Alert: "alert",
},
},
},
},
},
},
want: &lokiv1.AlertingRule{
Spec: lokiv1.AlertingRuleSpec{
TenantID: tenantAudit,
Groups: []*lokiv1.AlertingRuleGroup{
{
Name: "test-group",
Rules: []*lokiv1.AlertingRuleGroupSpec{
{
Alert: "alert",
},
},
},
},
},
},
},
{
rule: &lokiv1.AlertingRule{
Spec: lokiv1.AlertingRuleSpec{
TenantID: tenantNetwork,
Groups: []*lokiv1.AlertingRuleGroup{
{
Name: "test-group",
Rules: []*lokiv1.AlertingRuleGroupSpec{
{
Alert: "alert",
},
},
},
},
},
},
want: &lokiv1.AlertingRule{
Spec: lokiv1.AlertingRuleSpec{
TenantID: tenantNetwork,
Groups: []*lokiv1.AlertingRuleGroup{
{
Name: "test-group",
Rules: []*lokiv1.AlertingRuleGroupSpec{
{
Alert: "alert",
},
},
},
},
},
},
},
{
rule: &lokiv1.AlertingRule{
Spec: lokiv1.AlertingRuleSpec{
TenantID: "unknown",
Groups: []*lokiv1.AlertingRuleGroup{
{
Name: "test-group",
Rules: []*lokiv1.AlertingRuleGroupSpec{
{
Alert: "alert",
},
},
},
},
},
},
want: &lokiv1.AlertingRule{
Spec: lokiv1.AlertingRuleSpec{
TenantID: "unknown",
Groups: []*lokiv1.AlertingRuleGroup{
{
Name: "test-group",
Rules: []*lokiv1.AlertingRuleGroupSpec{
{
Alert: "alert",
},
},
},
},
},
},
},
}
for _, tc := range tt {
tc := tc
t.Run(tc.rule.Spec.TenantID, func(t *testing.T) {
t.Parallel()
AlertingRuleTenantLabels(tc.rule)
require.Equal(t, tc.want, tc.rule)
})
}
}

@ -76,6 +76,30 @@ func ConfigureGatewayDeployment(
return nil return nil
} }
// ConfigureGatewayDeploymentRulesAPI merges CLI argument to the gateway container
// that allow only Rules API access with a valid namespace input for the tenant application.
func ConfigureGatewayDeploymentRulesAPI(d *appsv1.Deployment, containerName string) error {
var gwIndex int
for i, c := range d.Spec.Template.Spec.Containers {
if c.Name == containerName {
gwIndex = i
break
}
}
container := corev1.Container{
Args: []string{
fmt.Sprintf("--logs.rules.label-filters=%s:%s", tenantApplication, opaDefaultLabelMatcher),
},
}
if err := mergo.Merge(&d.Spec.Template.Spec.Containers[gwIndex], container, mergo.WithAppendSlice); err != nil {
return kverrors.Wrap(err, "failed to merge container")
}
return nil
}
// ConfigureGatewayService merges the OpenPolicyAgent sidecar metrics port into // ConfigureGatewayService merges the OpenPolicyAgent sidecar metrics port into
// the service spec. With this the metrics are exposed through the same service. // the service spec. With this the metrics are exposed through the same service.
func ConfigureGatewayService(s *corev1.ServiceSpec) error { func ConfigureGatewayService(s *corev1.ServiceSpec) error {

@ -3,7 +3,9 @@ package manifests
import ( import (
"fmt" "fmt"
lokiv1 "github.com/grafana/loki/operator/apis/loki/v1"
"github.com/grafana/loki/operator/internal/manifests/internal/rules" "github.com/grafana/loki/operator/internal/manifests/internal/rules"
"github.com/grafana/loki/operator/internal/manifests/openshift"
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"
) )
@ -26,6 +28,11 @@ func RulesConfigMapShards(opts *Options) ([]*corev1.ConfigMap, error) {
shardedCM := NewShardedConfigMap(template, RulesConfigMapName(opts.Name)) shardedCM := NewShardedConfigMap(template, RulesConfigMapName(opts.Name))
for _, r := range opts.AlertingRules { for _, r := range opts.AlertingRules {
r := r
if opts.Stack.Tenants != nil {
configureAlertingRuleForMode(&r, opts.Stack.Tenants.Mode)
}
c, err := rules.MarshalAlertingRule(r) c, err := rules.MarshalAlertingRule(r)
if err != nil { if err != nil {
return nil, err return nil, err
@ -73,3 +80,14 @@ func newConfigMapTemplate(opts *Options, l map[string]string) *corev1.ConfigMap
func (rn RuleName) toString() string { func (rn RuleName) toString() string {
return fmt.Sprintf("%s%s%s.yaml", rn.tenantID, rulePartsSeparator, rn.filename) return fmt.Sprintf("%s%s%s.yaml", rn.tenantID, rulePartsSeparator, rn.filename)
} }
func configureAlertingRuleForMode(ar *lokiv1.AlertingRule, mode lokiv1.ModeType) {
switch mode {
case lokiv1.Static, lokiv1.Dynamic:
// Do nothing
case lokiv1.OpenshiftLogging:
openshift.AlertingRuleTenantLabels(ar)
case lokiv1.OpenshiftNetwork:
// Do nothing
}
}

Loading…
Cancel
Save