-
Notifications
You must be signed in to change notification settings - Fork 1
/
lookups.go
144 lines (121 loc) · 3.67 KB
/
lookups.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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package duty
import (
"fmt"
"github.com/flanksource/commons/logger"
"github.com/flanksource/gomplate/v3"
"github.com/google/uuid"
"github.com/flanksource/duty/context"
"github.com/flanksource/duty/query"
"github.com/flanksource/duty/types"
)
// Lookup specifies the type of lookup to perform.
type Lookup struct {
// Expr is a cel-expression.
Expr string `json:"expr,omitempty" yaml:"expr,omitempty"`
// Value is the static value to use.
Value string `json:"value,omitempty" yaml:"value,omitempty"`
// Label specifies the key to lookup on the label.
Label string `json:"label,omitempty" yaml:"label,omitempty"`
}
func (t *Lookup) Empty() bool {
return t.Expr == "" && t.Value == "" && t.Label == ""
}
func (t *Lookup) Eval(labels map[string]string, envVar map[string]any) (string, error) {
if t.Empty() {
return "", nil
}
if t.Value != "" {
return t.Value, nil
}
if t.Label != "" {
return labels[t.Label], nil
}
if t.Expr != "" {
res, err := gomplate.RunTemplate(envVar, gomplate.Template{Expression: t.Expr})
if err != nil {
return "", err
}
return res, nil
}
return "", nil
}
// LookupSpec defines a tuple of fields to lookup.
type LookupSpec struct {
Name Lookup `json:"name,omitempty" yaml:"name,omitempty"`
Namespace Lookup `json:"namespace,omitempty" yaml:"namespace,omitempty"`
Type Lookup `json:"type,omitempty" yaml:"type,omitempty"`
}
// LookupEvalResult is the result of evaluation of a LookupSpec.
type LookupEvalResult struct {
Name string
Namespace string
Type string
}
// Eval evaluates all the fields in the lookup spec based on labels and environment variables.
// Returns nil if any non-empty lookup evaluates to an empty value.
func (t *LookupSpec) Eval(labels map[string]string, envVar map[string]any) (*LookupEvalResult, error) {
var result LookupEvalResult
if !t.Name.Empty() {
name, err := t.Name.Eval(labels, envVar)
if err != nil {
return nil, err
}
if name == "" {
return nil, nil
}
result.Name = name
}
if !t.Namespace.Empty() {
namespace, err := t.Namespace.Eval(labels, envVar)
if err != nil {
return nil, err
}
if namespace == "" {
return nil, nil
}
result.Namespace = namespace
}
if !t.Type.Empty() {
typ, err := t.Type.Eval(labels, envVar)
if err != nil {
return nil, err
}
if typ == "" {
return nil, nil
}
result.Type = typ
}
return &result, nil
}
func LookupComponents(ctx context.Context, lookup LookupSpec, labels map[string]string, env map[string]any) ([]uuid.UUID, error) {
lookupResult, err := lookup.Eval(labels, env)
if err != nil {
return nil, fmt.Errorf("error evaluating lookup spec: %w", err)
} else if lookupResult == nil {
return nil, nil
}
if ctx.IsTrace() {
logger.Tracef("Finding all components (namespace=%s) (name=%s) (type=%s)", lookupResult.Namespace, lookupResult.Name, lookupResult.Type)
}
return query.FindComponentIDs(ctx, types.ResourceSelector{
Namespace: lookupResult.Namespace,
Name: lookupResult.Name,
Types: []string{lookupResult.Type},
})
}
func LookupConfigs(ctx context.Context, lookup LookupSpec, labels map[string]string, env map[string]any) ([]uuid.UUID, error) {
lookupResult, err := lookup.Eval(labels, env)
if err != nil {
return nil, fmt.Errorf("error evaluating lookup spec: %w", err)
} else if lookupResult == nil {
return nil, nil
}
if ctx.IsTrace() {
logger.Tracef("Finding all config items (namespace=%s) (name=%s) (type=%s)", lookupResult.Namespace, lookupResult.Name, lookupResult.Type)
}
return query.FindConfigIDsByResourceSelector(ctx, types.ResourceSelector{
Namespace: lookupResult.Namespace,
Name: lookupResult.Name,
Types: []string{lookupResult.Type},
})
}