/
utils.go
95 lines (77 loc) · 2.67 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package rlptools
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"unicode"
limitadorv1alpha1 "github.com/kuadrant/limitador-operator/api/v1alpha1"
kuadrantv1beta2 "github.com/kuadrant/kuadrant-operator/api/v1beta2"
"github.com/kuadrant/kuadrant-operator/pkg/common"
)
const (
LimitadorRateLimitIdentifierPrefix = "limit."
)
func LimitNameToLimitadorIdentifier(uniqueLimitName string) string {
identifier := LimitadorRateLimitIdentifierPrefix
// sanitize chars that are not allowed in limitador identifiers
for _, c := range uniqueLimitName {
if unicode.IsLetter(c) || unicode.IsDigit(c) || c == '_' {
identifier += string(c)
} else {
identifier += "_"
}
}
// to avoid breaking the uniqueness of the limit name after sanitization, we add a hash of the original name
hash := sha256.Sum256([]byte(uniqueLimitName))
identifier += "__" + hex.EncodeToString(hash[:4])
return identifier
}
// LimitadorRateLimitsFromRLP converts rate limits from a Kuadrant RateLimitPolicy into a list of Limitador rate limit
// objects
func LimitadorRateLimitsFromRLP(rlp *kuadrantv1beta2.RateLimitPolicy) []limitadorv1alpha1.RateLimit {
limitsNamespace := LimitsNamespaceFromRLP(rlp)
rateLimits := make([]limitadorv1alpha1.RateLimit, 0)
for limitKey, limit := range rlp.Spec.Limits {
limitIdentifier := LimitNameToLimitadorIdentifier(limitKey)
for _, rate := range limit.Rates {
maxValue, seconds := rateToSeconds(rate)
rateLimits = append(rateLimits, limitadorv1alpha1.RateLimit{
Namespace: limitsNamespace,
MaxValue: maxValue,
Seconds: seconds,
Conditions: []string{fmt.Sprintf("%s == \"1\"", limitIdentifier)},
Variables: common.GetEmptySliceIfNil(limit.CountersAsStringList()),
Name: LimitsNameFromRLP(rlp),
})
}
}
return rateLimits
}
func LimitsNamespaceFromRLP(rlp *kuadrantv1beta2.RateLimitPolicy) string {
return fmt.Sprintf("%s/%s", rlp.GetNamespace(), rlp.GetName())
}
func LimitsNameFromRLP(rlp *kuadrantv1beta2.RateLimitPolicy) string {
return LimitsNamespaceFromRLP(rlp)
}
var timeUnitMap = map[kuadrantv1beta2.TimeUnit]int{
kuadrantv1beta2.TimeUnit("second"): 1,
kuadrantv1beta2.TimeUnit("minute"): 60,
kuadrantv1beta2.TimeUnit("hour"): 60 * 60,
kuadrantv1beta2.TimeUnit("day"): 60 * 60 * 24,
}
// rateToSeconds converts from RLP Rate API (limit, duration and unit)
// to Limitador's Limit format (maxValue, Seconds)
func rateToSeconds(rate kuadrantv1beta2.Rate) (maxValue int, seconds int) {
maxValue = rate.Limit
seconds = 0
if tmpSecs, ok := timeUnitMap[rate.Unit]; ok && rate.Duration > 0 {
seconds = tmpSecs * rate.Duration
}
if rate.Duration < 0 {
seconds = 0
}
if rate.Limit < 0 {
maxValue = 0
}
return
}