This repository has been archived by the owner on Mar 16, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 101
/
strategy.go
102 lines (83 loc) · 3.2 KB
/
strategy.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
package devsessions
import (
"context"
"fmt"
"github.com/acorn-io/baaah/pkg/router"
apiv1 "github.com/acorn-io/runtime/pkg/apis/api.acorn.io/v1"
"github.com/acorn-io/runtime/pkg/config"
"github.com/acorn-io/runtime/pkg/profiles"
"github.com/acorn-io/runtime/pkg/server/registry/apigroups/acorn/apps"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
kclient "sigs.k8s.io/controller-runtime/pkg/client"
)
const ErrMsgDevSessionBlockedByIAR = "ImageAllowRules active - DevSessions are being blocked"
type Validator struct {
client kclient.Client
appValidator *apps.Validator
}
func NewValidator(c kclient.Client, appValidator *apps.Validator) *Validator {
return &Validator{
client: c,
appValidator: appValidator,
}
}
func (v *Validator) Validate(ctx context.Context, obj runtime.Object) (result field.ErrorList) {
devSession := obj.(*apiv1.DevSession)
app := &apiv1.App{}
if err := v.client.Get(ctx, router.Key(devSession.Namespace, devSession.Name), app); err != nil {
result = append(result, field.Invalid(field.NewPath("metadata", "name"), devSession.Name, err.Error()))
return
}
iarEnabled, err := config.GetFeature(ctx, v.client, profiles.FeatureImageAllowRules)
if err != nil {
result = append(result, field.Invalid(field.NewPath("metadata", "name"), devSession.Name, err.Error()))
return
}
if iarEnabled {
result = append(result, field.Forbidden(field.NewPath("metadata", "name"), ErrMsgDevSessionBlockedByIAR))
return
}
if devSession.Spec.Region != app.GetRegion() {
if devSession.Spec.Region != "" {
result = append(result, field.Invalid(field.NewPath("spec", "region"), devSession.Spec.Region,
fmt.Sprintf("Region on devSession [%s] and app [%s] must match", devSession.Spec.Region, app.GetRegion())))
return
}
// If the dev session's region is blank, then set it to the app's region.
devSession.Spec.Region = app.GetRegion()
}
if devSession.Spec.SpecOverride == nil {
return nil
}
app.Spec = *devSession.Spec.SpecOverride
app.Status.DevSession = nil
errs := v.appValidator.Validate(ctx, app)
// Super important that we set the image perms from validation
devSession.Spec.SpecOverride.ImageGrantedPermissions = app.Spec.ImageGrantedPermissions
return errs
}
func (v *Validator) ValidateUpdate(ctx context.Context, obj, old runtime.Object) (result field.ErrorList) {
oldObj := old.(*apiv1.DevSession)
newObj := obj.(*apiv1.DevSession)
if oldObj.Spec.SpecOverride == nil {
return v.Validate(ctx, obj)
} else if newObj.Spec.SpecOverride == nil {
return nil
}
app := &apiv1.App{}
if err := v.client.Get(ctx, router.Key(newObj.Namespace, newObj.Name), app); err != nil {
result = append(result, field.Invalid(field.NewPath("metadata", "name"), newObj.Name, err.Error()))
return
}
oldApp := app.DeepCopy()
oldApp.Spec = *oldObj.Spec.SpecOverride
oldApp.Status.DevSession = nil
newApp := app.DeepCopy()
newApp.Spec = *newObj.Spec.SpecOverride
newApp.Status.DevSession = nil
errs := v.appValidator.AllowNestedUpdate().ValidateUpdate(ctx, newApp, oldApp)
// Super important that we set the image perms from validation
newObj.Spec.SpecOverride.ImageGrantedPermissions = newApp.Spec.ImageGrantedPermissions
return errs
}