-
Notifications
You must be signed in to change notification settings - Fork 24
/
validator.go
116 lines (102 loc) · 3.7 KB
/
validator.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
package controlplane
import (
"context"
"errors"
"go.uber.org/fx"
policylangv1 "github.com/fluxninja/aperture/api/v2/gen/proto/go/aperture/policy/language/v1"
policysyncv1 "github.com/fluxninja/aperture/api/v2/gen/proto/go/aperture/policy/sync/v1"
"github.com/fluxninja/aperture/v2/pkg/alerts"
"github.com/fluxninja/aperture/v2/pkg/config"
"github.com/fluxninja/aperture/v2/pkg/log"
"github.com/fluxninja/aperture/v2/pkg/policies/controlplane/circuitfactory"
"github.com/fluxninja/aperture/v2/pkg/policies/controlplane/crwatcher"
"github.com/fluxninja/aperture/v2/pkg/policies/flowcontrol/resources/classifier/compiler"
"github.com/fluxninja/aperture/v2/pkg/status"
"github.com/fluxninja/aperture/v2/pkg/webhooks/policyvalidator"
)
// FxOut is the output of the controlplane module.
type FxOut struct {
fx.Out
Validator policyvalidator.PolicySpecValidator `group:"policy-validators"`
}
// FxIn is the input for the AddAgentInfoAttribute function.
type FxIn struct {
fx.In
Unmarshaller config.Unmarshaller
}
// ProvidePolicyValidator provides classification Policy Custom Resource validator
//
// Note: This validator must be registered to be accessible.
func ProvidePolicyValidator(in FxIn) (FxOut, error) {
var config crwatcher.CRWatcherConfig
err := in.Unmarshaller.UnmarshalKey(crwatcher.ConfigKey, &config)
if err != nil {
log.Error().Err(err).Msg("Failed to unmarshal Kubernetes watcher config")
return FxOut{}, nil
}
if !config.Enabled {
log.Info().Msg("Kubernetes watcher is disabled")
return FxOut{}, nil
}
return FxOut{
Validator: &PolicySpecValidator{},
}, nil
}
// PolicySpecValidator Policy implementation of PolicySpecValidator interface.
type PolicySpecValidator struct{}
// ValidateSpec checks the validity of a Policy spec
//
// returns:
// * true, "", nil when Policy is valid
// * false, message, nil when Policy is invalid
// and
// * false, "", err on other errors.
//
// ValidateSpec checks the syntax, validity of extractors, and validity of
// rego modules (by attempting to compile them).
func (v *PolicySpecValidator) ValidateSpec(ctx context.Context, name string, yamlSrc []byte) (bool, string, error) {
_, _, err := ValidateAndCompileYAML(ctx, name, yamlSrc)
if err != nil {
// there is no need to handle validator errors. just return validation result.
return false, err.Error(), nil
}
return true, "", nil
}
// ValidateAndCompileYAML checks the validity of a single Policy and compiles it.
func ValidateAndCompileYAML(ctx context.Context, name string, yamlSrc []byte) (*circuitfactory.Circuit, *policylangv1.Policy, error) {
if len(yamlSrc) == 0 {
return nil, nil, errors.New("empty policy")
}
policy := &policylangv1.Policy{}
err := config.UnmarshalYAML(yamlSrc, policy)
if err != nil {
return nil, nil, err
}
return ValidateAndCompileProto(ctx, name, policy)
}
// ValidateAndCompileProto checks the validity of a single Policy and compiles it.
func ValidateAndCompileProto(ctx context.Context, name string, policy *policylangv1.Policy) (*circuitfactory.Circuit, *policylangv1.Policy, error) {
alerter := alerts.NewSimpleAlerter(100)
registry := status.NewRegistry(log.GetGlobalLogger(), alerter)
circuit, err := CompilePolicy(policy, name, registry)
if err != nil {
return nil, nil, err
}
if policy.GetResources() != nil {
classifiers := policy.GetResources().GetFlowControl().GetClassifiers()
for _, c := range classifiers {
_, err = compiler.CompileRuleset(ctx, name, &policysyncv1.ClassifierWrapper{
Classifier: c,
ClassifierAttributes: &policysyncv1.ClassifierAttributes{
PolicyName: "dummy",
PolicyHash: "dummy",
ClassifierIndex: 0,
},
})
if err != nil {
return nil, nil, err
}
}
}
return circuit, policy, nil
}