/
strategy.go
121 lines (101 loc) · 3.67 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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package route
import (
"fmt"
kapi "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/runtime"
utilruntime "k8s.io/kubernetes/pkg/util/runtime"
"k8s.io/kubernetes/pkg/util/validation/field"
"github.com/openshift/origin/pkg/route"
"github.com/openshift/origin/pkg/route/api"
"github.com/openshift/origin/pkg/route/api/validation"
)
// HostGeneratedAnnotationKey is the key for an annotation set to "true" if the route's host was generated
const HostGeneratedAnnotationKey = "openshift.io/host.generated"
type routeStrategy struct {
runtime.ObjectTyper
kapi.NameGenerator
route.RouteAllocator
}
// NewStrategy initializes the default logic that applies when creating and updating
// Route objects via the REST API.
func NewStrategy(allocator route.RouteAllocator) routeStrategy {
return routeStrategy{
kapi.Scheme,
kapi.SimpleNameGenerator,
allocator,
}
}
func (routeStrategy) NamespaceScoped() bool {
return true
}
func (s routeStrategy) PrepareForCreate(obj runtime.Object) {
route := obj.(*api.Route)
route.Status = api.RouteStatus{}
// Limit to kind/name
// TODO: convert to LocalObjectReference
route.Spec.To = kapi.ObjectReference{Kind: route.Spec.To.Kind, Name: route.Spec.To.Name}
if len(route.Spec.Host) == 0 && s.RouteAllocator != nil {
// TODO: this does not belong here, and should be removed
shard, err := s.RouteAllocator.AllocateRouterShard(route)
if err != nil {
// TODO: this will be changed when moved to a controller
utilruntime.HandleError(errors.NewInternalError(fmt.Errorf("allocation error: %v for route: %#v", err, obj)))
return
}
route.Spec.Host = s.RouteAllocator.GenerateHostname(route, shard)
if route.Annotations == nil {
route.Annotations = map[string]string{}
}
route.Annotations[HostGeneratedAnnotationKey] = "true"
}
}
func (routeStrategy) PrepareForUpdate(obj, old runtime.Object) {
route := obj.(*api.Route)
oldRoute := old.(*api.Route)
route.Status = oldRoute.Status
// Limit to kind/name
// TODO: convert to LocalObjectReference
route.Spec.To = kapi.ObjectReference{Kind: route.Spec.To.Kind, Name: route.Spec.To.Name}
}
func (routeStrategy) Validate(ctx kapi.Context, obj runtime.Object) field.ErrorList {
route := obj.(*api.Route)
return validation.ValidateRoute(route)
}
func (routeStrategy) AllowCreateOnUpdate() bool {
return false
}
// Canonicalize normalizes the object after validation.
func (routeStrategy) Canonicalize(obj runtime.Object) {
}
func (routeStrategy) ValidateUpdate(ctx kapi.Context, obj, old runtime.Object) field.ErrorList {
oldRoute := old.(*api.Route)
objRoute := obj.(*api.Route)
return validation.ValidateRouteUpdate(objRoute, oldRoute)
}
func (routeStrategy) AllowUnconditionalUpdate() bool {
return true
}
type routeStatusStrategy struct {
routeStrategy
}
var StatusStrategy = routeStatusStrategy{NewStrategy(nil)}
func (routeStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
newRoute := obj.(*api.Route)
oldRoute := old.(*api.Route)
newRoute.Spec = oldRoute.Spec
}
func (routeStatusStrategy) ValidateUpdate(ctx kapi.Context, obj, old runtime.Object) field.ErrorList {
return validation.ValidateRouteStatusUpdate(obj.(*api.Route), old.(*api.Route))
}
// Matcher returns a matcher for a route
func Matcher(label labels.Selector, field fields.Selector) generic.Matcher {
return &generic.SelectionPredicate{Label: label, Field: field, GetAttrs: getAttrs}
}
func getAttrs(obj runtime.Object) (objLabels labels.Set, objFields fields.Set, err error) {
route := obj.(*api.Route)
return labels.Set(route.Labels), api.RouteToSelectableFields(route), nil
}