forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
imagestream_evaluator.go
137 lines (118 loc) · 4.74 KB
/
imagestream_evaluator.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
package image
import (
"fmt"
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/admission"
kapi "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource"
kquota "k8s.io/kubernetes/pkg/quota"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/sets"
osclient "github.com/openshift/origin/pkg/client"
imageapi "github.com/openshift/origin/pkg/image/api"
quotautil "github.com/openshift/origin/pkg/quota/util"
)
const (
imageStreamEvaluatorName = "Evaluator.ImageStream.Controller"
imageStreamAdmissionEvaluatorName = "Evaluator.ImageStream.Admission"
)
// NewImageStreamEvaluator computes resource usage of ImageStreams. Instantiating this is necessary for
// resource quota admission controller to properly work on image stream related objects.
func NewImageStreamEvaluator(osClient osclient.Interface) kquota.Evaluator {
computeResources := []kapi.ResourceName{
imageapi.ResourceImages,
}
matchesScopeFunc := func(kapi.ResourceQuotaScope, runtime.Object) bool { return true }
getFuncByNamespace := func(namespace, name string) (runtime.Object, error) {
return osClient.ImageStreams(namespace).Get(name)
}
listFuncByNamespace := func(namespace string, options kapi.ListOptions) (runtime.Object, error) {
return osClient.ImageStreams(namespace).List(options)
}
return quotautil.NewSharedContextEvaluator(
imageStreamEvaluatorName,
kapi.Kind("ImageStream"),
nil,
computeResources,
matchesScopeFunc,
getFuncByNamespace,
listFuncByNamespace,
imageStreamConstraintsFunc,
makeImageStreamUsageComputerFactory(osClient))
}
// NewImageStreamAdmissionEvaluator computes resource usage of ImageStreams in the context of admission
// plugin.
func NewImageStreamAdmissionEvaluator(osClient osclient.Interface) kquota.Evaluator {
evaluator := NewImageStreamEvaluator(osClient)
isEval := evaluator.(*quotautil.SharedContextEvaluator)
isEval.Name = imageStreamAdmissionEvaluatorName
isEval.InternalOperationResources = map[admission.Operation][]kapi.ResourceName{
admission.Create: isEval.MatchedResourceNames,
admission.Update: isEval.MatchedResourceNames,
}
isEval.UsageComputerFactory = makeImageStreamUsageComputerForAdmissionFactory(osClient)
// admission plugin should not attempt to list us
isEval.ListFuncByNamespace = nil
return isEval
}
// imageStreamConstraintsFunc checks that given object is an image stream
func imageStreamConstraintsFunc(required []kapi.ResourceName, object runtime.Object) error {
if _, ok := object.(*imageapi.ImageStream); !ok {
return fmt.Errorf("Unexpected input object %v", object)
}
return nil
}
// makeImageStreamUsageComputerFactory returns an object used during computation of image quota across all
// repositories in a namespace.
func makeImageStreamUsageComputerFactory(osClient osclient.Interface) quotautil.UsageComputerFactory {
return func() quotautil.UsageComputer {
return &imageStreamUsageComputer{
GenericImageStreamUsageComputer: *NewGenericImageStreamUsageComputer(osClient, false, true),
processedImages: sets.NewString(),
}
}
}
// imageStreamUsageComputer is a context object for use in SharedContextEvaluator.
type imageStreamUsageComputer struct {
GenericImageStreamUsageComputer
processedImages sets.String
}
// Usage returns a usage for an image stream.
func (c *imageStreamUsageComputer) Usage(object runtime.Object) kapi.ResourceList {
is, ok := object.(*imageapi.ImageStream)
if !ok {
return kapi.ResourceList{}
}
images := c.GetImageStreamUsage(is, c.processedImages)
return kapi.ResourceList{
imageapi.ResourceImages: *images,
}
}
// makeImageStreamUsageComputerForAdmissionFactory returns an object used during computation of image quota
// across all repositories in a namespace in a context of admission plugin.
func makeImageStreamUsageComputerForAdmissionFactory(osClient osclient.Interface) quotautil.UsageComputerFactory {
return func() quotautil.UsageComputer {
return &imageStreamUsageComputerForAdmission{
GenericImageStreamUsageComputer: *NewGenericImageStreamUsageComputer(osClient, true, false),
}
}
}
// imageStreamUsageComputerForAdmission is a context object for use in SharedContextEvaluator
type imageStreamUsageComputerForAdmission struct {
GenericImageStreamUsageComputer
}
// Usage returns a usage for an image stream.
func (c *imageStreamUsageComputerForAdmission) Usage(object runtime.Object) kapi.ResourceList {
is, ok := object.(*imageapi.ImageStream)
if !ok {
return kapi.ResourceList{}
}
_, imagesIncrement, err := c.GetProjectImagesUsageIncrement(is.Namespace, is, nil)
if err != nil {
glog.Errorf("Failed to compute project images size increment in namespace %q: %v", is.Namespace, err)
return kapi.ResourceList{}
}
return map[kapi.ResourceName]resource.Quantity{
imageapi.ResourceImages: *imagesIncrement,
}
}