Provide a more meaningful error message when not admitted Storage/Ingress Classes are used (#141)

* Providing further details on non allowed Storage Classes

* Providing further details on non allowed Ingress Classes
This commit is contained in:
Dario Tranchitella
2020-11-17 23:44:08 +01:00
committed by GitHub
parent 6541f19b67
commit d3bc9f4870
4 changed files with 77 additions and 32 deletions
+31 -10
View File
@@ -18,26 +18,47 @@ package ingress
import (
"fmt"
"strings"
"github.com/clastix/capsule/api/v1alpha1"
)
type ingressClassForbidden struct {
ingressClass string
className string
spec v1alpha1.IngressClassesSpec
}
func NewIngressClassForbidden(ingressClass string) error {
return &ingressClassForbidden{ingressClass: ingressClass}
func NewIngressClassForbidden(className string, spec v1alpha1.IngressClassesSpec) error {
return &ingressClassForbidden{
className: className,
spec: spec,
}
}
func (i ingressClassForbidden) Error() string {
return fmt.Sprintf("Ingress Class %s is forbidden for the current Tenant", i.ingressClass)
return fmt.Sprintf("Ingress Class %s is forbidden for the current Tenant%s", i.className, appendError(i.spec))
}
type ingressClassNotValid struct{}
func NewIngressClassNotValid() error {
return &ingressClassNotValid{}
func appendError(spec v1alpha1.IngressClassesSpec) (append string) {
if len(spec.Allowed) > 0 {
append += fmt.Sprintf(", one of the following (%s)", strings.Join(spec.Allowed, ", "))
}
if len(spec.AllowedRegex) > 0 {
append += fmt.Sprintf(", or matching the regex %s", spec.AllowedRegex)
}
return
}
func (ingressClassNotValid) Error() string {
return "A valid Ingress Class must be used"
type ingressClassNotValid struct {
spec v1alpha1.IngressClassesSpec
}
func NewIngressClassNotValid(spec v1alpha1.IngressClassesSpec) error {
return &ingressClassNotValid{
spec: spec,
}
}
func (i ingressClassNotValid) Error() string {
return "A valid Ingress Class must be used" + appendError(i.spec)
}
+8 -6
View File
@@ -132,21 +132,23 @@ func (r *handler) validateIngress(ctx context.Context, c client.Client, object I
return admission.Allowed("")
}
tnt := tl.Items[0]
ingressClass := object.IngressClass()
if ingressClass == nil {
return admission.Errored(http.StatusBadRequest, NewIngressClassNotValid())
return admission.Errored(http.StatusBadRequest, NewIngressClassNotValid(tnt.Spec.IngressClasses))
}
if len(tl.Items[0].Spec.IngressClasses.Allowed) > 0 {
valid = tl.Items[0].Spec.IngressClasses.Allowed.IsStringInList(*ingressClass)
if len(tnt.Spec.IngressClasses.Allowed) > 0 {
valid = tnt.Spec.IngressClasses.Allowed.IsStringInList(*ingressClass)
}
if len(tl.Items[0].Spec.IngressClasses.AllowedRegex) > 0 {
matched, _ = regexp.MatchString(tl.Items[0].Spec.IngressClasses.AllowedRegex, *ingressClass)
if len(tnt.Spec.IngressClasses.AllowedRegex) > 0 {
matched, _ = regexp.MatchString(tnt.Spec.IngressClasses.AllowedRegex, *ingressClass)
}
if !valid && !matched {
return admission.Errored(http.StatusBadRequest, NewIngressClassForbidden(*ingressClass))
return admission.Errored(http.StatusBadRequest, NewIngressClassForbidden(*ingressClass, tnt.Spec.IngressClasses))
}
return admission.Allowed("")
+31 -10
View File
@@ -18,26 +18,47 @@ package pvc
import (
"fmt"
"strings"
"github.com/clastix/capsule/api/v1alpha1"
)
type storageClassNotValid struct{}
func NewStorageClassNotValid() error {
return &storageClassNotValid{}
type storageClassNotValid struct {
spec v1alpha1.StorageClassesSpec
}
func (storageClassNotValid) Error() string {
return "A valid Storage Class must be used"
func NewStorageClassNotValid(storageClasses v1alpha1.StorageClassesSpec) error {
return &storageClassNotValid{
spec: storageClasses,
}
}
func appendError(spec v1alpha1.StorageClassesSpec) (append string) {
if len(spec.Allowed) > 0 {
append += fmt.Sprintf(", one of the following (%s)", strings.Join(spec.Allowed, ", "))
}
if len(spec.AllowedRegex) > 0 {
append += fmt.Sprintf(", or matching the regex %s", spec.AllowedRegex)
}
return
}
func (s storageClassNotValid) Error() (err string) {
return "A valid Storage Class must be used" + appendError(s.spec)
}
type storageClassForbidden struct {
storageClassName string
className string
spec v1alpha1.StorageClassesSpec
}
func NewStorageClassForbidden(storageClassName string) error {
return &storageClassForbidden{storageClassName: storageClassName}
func NewStorageClassForbidden(className string, storageClasses v1alpha1.StorageClassesSpec) error {
return &storageClassForbidden{
className: className,
spec: storageClasses,
}
}
func (f storageClassForbidden) Error() string {
return fmt.Sprintf("Storage Class %s is forbidden for the current Tenant", f.storageClassName)
return fmt.Sprintf("Storage Class %s is forbidden for the current Tenant%s", f.className, appendError(f.spec))
}
+7 -6
View File
@@ -80,21 +80,22 @@ func (h *handler) OnCreate(c client.Client, decoder *admission.Decoder) capsulew
}
if pvc.Spec.StorageClassName == nil {
return admission.Errored(http.StatusBadRequest, NewStorageClassNotValid())
return admission.Errored(http.StatusBadRequest, NewStorageClassNotValid(tl.Items[0].Spec.StorageClasses))
}
tnt := tl.Items[0]
sc := *pvc.Spec.StorageClassName
if len(tl.Items[0].Spec.StorageClasses.Allowed) > 0 {
valid = tl.Items[0].Spec.StorageClasses.Allowed.IsStringInList(sc)
if len(tnt.Spec.StorageClasses.Allowed) > 0 {
valid = tnt.Spec.StorageClasses.Allowed.IsStringInList(sc)
}
if len(tl.Items[0].Spec.StorageClasses.AllowedRegex) > 0 {
matched, _ = regexp.MatchString(tl.Items[0].Spec.StorageClasses.AllowedRegex, sc)
if len(tnt.Spec.StorageClasses.AllowedRegex) > 0 {
matched, _ = regexp.MatchString(tnt.Spec.StorageClasses.AllowedRegex, sc)
}
if !valid && !matched {
return admission.Errored(http.StatusBadRequest, NewStorageClassForbidden(*pvc.Spec.StorageClassName))
return admission.Errored(http.StatusBadRequest, NewStorageClassForbidden(*pvc.Spec.StorageClassName, tnt.Spec.StorageClasses))
}
return admission.Allowed("")