Skip to content

Commit

Permalink
operator: Add support for blocking queries per tenant (#11094)
Browse files Browse the repository at this point in the history
Co-authored-by: Robert Jacob <[email protected]>
  • Loading branch information
periklis and xperimental authored Nov 28, 2023
1 parent 10210b8 commit 21a7f96
Show file tree
Hide file tree
Showing 22 changed files with 840 additions and 72 deletions.
3 changes: 2 additions & 1 deletion operator/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
## Main

- [11094](https://github.com/grafana/loki/pull/11094) **periklis**: Add support for blocking queries per tenant
- [11288](https://github.com/grafana/loki/pull/11288) **periklis**: Fix custom CA for object-store in ruler component
- [11091](https://github.com/grafana/loki/pull/11091) **periklis**: Add automatic stream sharding support
- [11022](https://github.com/grafana/loki/pull/11022) **JoaoBraveCoding**: Remove outdated BoltDB dashboards
- [10932](https://github.com/grafana/loki/pull/10932) **JoaoBraveCoding**: Adds new value v13 to schema
- [11232](https://github.com/grafana/loki/pull/11232) **periklis**: Update dependencies and dev tools
- [11129](https://github.com/grafana/loki/pull/11129) **periklis**: Update deps to secure webhooks for CVE-2023-44487
-

## 0.5.0 (2023-10-24)

- [10924](https://github.com/grafana/loki/pull/10924) **periklis**: Update Loki operand to v2.9.2
Expand Down
93 changes: 92 additions & 1 deletion operator/apis/loki/v1/lokistack_types.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package v1

import (
"strings"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
Expand Down Expand Up @@ -633,6 +635,65 @@ type QueryLimitSpec struct {
CardinalityLimit int32 `json:"cardinalityLimit,omitempty"`
}

// BlockedQueryType defines which type of query a blocked query should apply to.
//
// +kubebuilder:validation:Enum=filter;limited;metric
type BlockedQueryType string

const (
// BlockedQueryFilter is used, when the blocked query should apply to queries using a log filter.
BlockedQueryFilter BlockedQueryType = "filter"
// BlockedQueryLimited is used, when the blocked query should apply to queries without a filter or a metric aggregation.
BlockedQueryLimited BlockedQueryType = "limited"
// BlockedQueryMetric is used, when the blocked query should apply to queries with an aggregation.
BlockedQueryMetric BlockedQueryType = "metric"
)

// BlockedQueryTypes defines a slice of BlockedQueryType values to be used for a blocked query.
type BlockedQueryTypes []BlockedQueryType

// BlockedQuerySpec defines the rule spec for queries to be blocked.
//
// +kubebuilder:validation:MinProperties:=1
type BlockedQuerySpec struct {
// Hash is a 32-bit FNV-1 hash of the query string.
//
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors="urn:alm:descriptor:com.tectonic.ui:number",displayName="Query Hash"
Hash int32 `json:"hash,omitempty"`
// Pattern defines the pattern matching the queries to be blocked.
//
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Query Pattern"
Pattern string `json:"pattern,omitempty"`
// Regex defines if the pattern is a regular expression. If false the pattern will be used only for exact matches.
//
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors="urn:alm:descriptor:com.tectonic.ui:booleanSwitch",displayName="Regex"
Regex bool `json:"regex,omitempty"`
// Types defines the list of query types that should be considered for blocking.
//
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Query Types"
Types BlockedQueryTypes `json:"types,omitempty"`
}

// PerTenantQueryLimitSpec defines the limits applied to per tenant query path.
type PerTenantQueryLimitSpec struct {
QueryLimitSpec `json:",omitempty"`

// Blocked defines the list of rules to block matching queries.
//
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Blocked"
Blocked []BlockedQuerySpec `json:"blocked,omitempty"`
}

// IngestionLimitSpec defines the limits applied at the ingestion path.
type IngestionLimitSpec struct {
// IngestionRate defines the sample size per second. Units MB.
Expand Down Expand Up @@ -773,6 +834,27 @@ type LimitsTemplateSpec struct {
Retention *RetentionLimitSpec `json:"retention,omitempty"`
}

// LimitsTemplateSpec defines the limits applied at ingestion or query path.
type PerTenantLimitsTemplateSpec struct {
// IngestionLimits defines the limits applied on ingested log streams.
//
// +optional
// +kubebuilder:validation:Optional
IngestionLimits *IngestionLimitSpec `json:"ingestion,omitempty"`

// QueryLimits defines the limit applied on querying log streams.
//
// +optional
// +kubebuilder:validation:Optional
QueryLimits *PerTenantQueryLimitSpec `json:"queries,omitempty"`

// Retention defines how long logs are kept in storage.
//
// +optional
// +kubebuilder:validation:Optional
Retention *RetentionLimitSpec `json:"retention,omitempty"`
}

// LimitsSpec defines the spec for limits applied at ingestion or query
// path across the cluster or per tenant.
type LimitsSpec struct {
Expand All @@ -788,7 +870,7 @@ type LimitsSpec struct {
// +optional
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Limits per Tenant"
Tenants map[string]LimitsTemplateSpec `json:"tenants,omitempty"`
Tenants map[string]PerTenantLimitsTemplateSpec `json:"tenants,omitempty"`
}

// RulesSpec defines the spec for the ruler component.
Expand Down Expand Up @@ -1148,3 +1230,12 @@ func init() {

// Hub declares the v1.LokiStack as the hub CRD version.
func (*LokiStack) Hub() {}

func (t BlockedQueryTypes) String() string {
res := make([]string, 0, len(t))
for _, t := range t {
res = append(res, string(t))
}

return strings.Join(res, ",")
}
94 changes: 93 additions & 1 deletion operator/apis/loki/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 8 additions & 6 deletions operator/apis/loki/v1beta1/lokistack_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -933,11 +933,11 @@ func (src *LokiStack) ConvertTo(dstRaw conversion.Hub) error {
}

if len(src.Spec.Limits.Tenants) > 0 {
dst.Spec.Limits.Tenants = make(map[string]v1.LimitsTemplateSpec)
dst.Spec.Limits.Tenants = make(map[string]v1.PerTenantLimitsTemplateSpec)
}

for tenant, srcSpec := range src.Spec.Limits.Tenants {
dstSpec := v1.LimitsTemplateSpec{}
dstSpec := v1.PerTenantLimitsTemplateSpec{}

if srcSpec.IngestionLimits != nil {
dstSpec.IngestionLimits = &v1.IngestionLimitSpec{
Expand All @@ -952,10 +952,12 @@ func (src *LokiStack) ConvertTo(dstRaw conversion.Hub) error {
}

if srcSpec.QueryLimits != nil {
dstSpec.QueryLimits = &v1.QueryLimitSpec{
MaxEntriesLimitPerQuery: srcSpec.QueryLimits.MaxEntriesLimitPerQuery,
MaxChunksPerQuery: srcSpec.QueryLimits.MaxChunksPerQuery,
MaxQuerySeries: srcSpec.QueryLimits.MaxQuerySeries,
dstSpec.QueryLimits = &v1.PerTenantQueryLimitSpec{
QueryLimitSpec: v1.QueryLimitSpec{
MaxEntriesLimitPerQuery: srcSpec.QueryLimits.MaxEntriesLimitPerQuery,
MaxChunksPerQuery: srcSpec.QueryLimits.MaxChunksPerQuery,
MaxQuerySeries: srcSpec.QueryLimits.MaxQuerySeries,
},
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ metadata:
categories: OpenShift Optional, Logging & Tracing
certified: "false"
containerImage: docker.io/grafana/loki-operator:0.5.0
createdAt: "2023-11-23T11:25:33Z"
createdAt: "2023-11-03T11:44:16Z"
description: The Community Loki Operator provides Kubernetes native deployment
and management of Loki and related logging components.
operators.operatorframework.io/builder: operator-sdk-unknown
Expand Down Expand Up @@ -444,6 +444,27 @@ spec:
path: limits.tenants.ingestion.perStreamRateLimitBurst
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:number
- description: Blocked defines the list of rules to block matching queries.
displayName: Blocked
path: limits.tenants.queries.blocked
- description: Hash is a 32-bit FNV-1 hash of the query string.
displayName: Query Hash
path: limits.tenants.queries.blocked[0].hash
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:number
- description: Pattern defines the pattern matching the queries to be blocked.
displayName: Query Pattern
path: limits.tenants.queries.blocked[0].pattern
- description: Regex defines if the pattern is a regular expression. If false
the pattern will be used only for exact matches.
displayName: Regex
path: limits.tenants.queries.blocked[0].regex
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
- description: Types defines the list of query types that should be considered
for blocking.
displayName: Query Types
path: limits.tenants.queries.blocked[0].types
- description: CardinalityLimit defines the cardinality limit for index queries.
displayName: Cardinality Limit
path: limits.tenants.queries.cardinalityLimit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,43 @@ spec:
description: QueryLimits defines the limit applied on querying
log streams.
properties:
blocked:
description: Blocked defines the list of rules to block
matching queries.
items:
description: BlockedQuerySpec defines the rule spec
for queries to be blocked.
minProperties: 1
properties:
hash:
description: Hash is a 32-bit FNV-1 hash of the
query string.
format: int32
type: integer
pattern:
description: Pattern defines the pattern matching
the queries to be blocked.
type: string
regex:
description: Regex defines if the pattern is a
regular expression. If false the pattern will
be used only for exact matches.
type: boolean
types:
description: Types defines the list of query types
that should be considered for blocking.
items:
description: BlockedQueryType defines which
type of query a blocked query should apply
to.
enum:
- filter
- limited
- metric
type: string
type: array
type: object
type: array
cardinalityLimit:
description: CardinalityLimit defines the cardinality
limit for index queries.
Expand Down
Loading

0 comments on commit 21a7f96

Please sign in to comment.