// makeImageStreamTagAdmissionUsageFunc returns a function that computes a resource usage for given image // stream tag during admission. func makeImageStreamTagAdmissionUsageFunc(isNamespacer osclient.ImageStreamsNamespacer) generic.UsageFunc { return func(object runtime.Object) kapi.ResourceList { ist, ok := object.(*imageapi.ImageStreamTag) if !ok { return kapi.ResourceList{} } res := map[kapi.ResourceName]resource.Quantity{ imageapi.ResourceImageStreams: *resource.NewQuantity(0, resource.BinarySI), } isName, _, err := imageapi.ParseImageStreamTagName(ist.Name) if err != nil { utilruntime.HandleError(err) return kapi.ResourceList{} } is, err := isNamespacer.ImageStreams(ist.Namespace).Get(isName) if err != nil { if !kerrors.IsNotFound(err) { utilruntime.HandleError(fmt.Errorf("failed to get image stream %s/%s: %v", ist.Namespace, isName, err)) } } if is == nil { res[imageapi.ResourceImageStreams] = *resource.NewQuantity(1, resource.BinarySI) } return res } }
// nameAndTag splits a string into its name component and tag component, and returns an error // if the string is not in the right form. func nameAndTag(id string) (name string, tag string, err error) { name, tag, err = api.ParseImageStreamTagName(id) if err != nil { err = kapierrors.NewBadRequest("ImageStreamTags must be retrieved with <name>:<tag>") } return }
// GetImageReferenceForObjectReference returns corresponding image reference for the given object // reference representing either an image stream image or image stream tag or docker image. func GetImageReferenceForObjectReference(namespace string, objRef *kapi.ObjectReference) (string, error) { switch objRef.Kind { case "ImageStreamImage", "DockerImage": res, err := imageapi.ParseDockerImageReference(objRef.Name) if err != nil { return "", err } if objRef.Kind == "ImageStreamImage" { if res.Namespace == "" { res.Namespace = objRef.Namespace } if res.Namespace == "" { res.Namespace = namespace } if len(res.ID) == 0 { return "", fmt.Errorf("missing id in ImageStreamImage reference %q", objRef.Name) } } else { // objRef.Kind == "DockerImage" res = res.DockerClientDefaults() } // docker image reference return res.DaemonMinimal().Exact(), nil case "ImageStreamTag": isName, tag, err := imageapi.ParseImageStreamTagName(objRef.Name) if err != nil { return "", err } ns := namespace if len(objRef.Namespace) > 0 { ns = objRef.Namespace } // <namespace>/<isname>:<tag> return cache.MetaNamespaceKeyFunc(&kapi.ObjectMeta{ Namespace: ns, Name: imageapi.JoinImageStreamTag(isName, tag), }) } return "", fmt.Errorf("unsupported object reference kind %s", objRef.Kind) }
// NewImageStreamTagEvaluator computes resource usage of ImageStreamsTags. Its sole purpose is to handle // UPDATE admission operations on imageStreamTags resource. func NewImageStreamTagEvaluator(istNamespacer osclient.ImageStreamTagsNamespacer, isNamespacer osclient.ImageStreamsNamespacer) kquota.Evaluator { computeResources := []kapi.ResourceName{ imageapi.ResourceImageStreams, } matchesScopeFunc := func(kapi.ResourceQuotaScope, runtime.Object) bool { return true } getFuncByNamespace := func(namespace, id string) (runtime.Object, error) { isName, tag, err := imageapi.ParseImageStreamTagName(id) if err != nil { return nil, err } obj, err := istNamespacer.ImageStreamTags(namespace).Get(isName, tag) if err != nil { if !kerrors.IsNotFound(err) { return nil, err } obj = &imageapi.ImageStreamTag{ ObjectMeta: kapi.ObjectMeta{ Namespace: namespace, Name: id, }, } } return obj, nil } return &generic.GenericEvaluator{ Name: imageStreamTagEvaluatorName, InternalGroupKind: imageapi.Kind("ImageStreamTag"), InternalOperationResources: map[admission.Operation][]kapi.ResourceName{ admission.Update: computeResources, admission.Create: computeResources, }, MatchedResourceNames: computeResources, MatchesScopeFunc: matchesScopeFunc, UsageFunc: makeImageStreamTagAdmissionUsageFunc(isNamespacer), GetFuncByNamespace: getFuncByNamespace, ListFuncByNamespace: func(namespace string, options kapi.ListOptions) (runtime.Object, error) { return &imageapi.ImageStreamTagList{}, nil }, ConstraintsFunc: imageStreamTagConstraintsFunc, } }