mirror of
https://github.com/projectcapsule/capsule.git
synced 2026-02-14 18:09:58 +00:00
refactor: grouping Ingress options into defined struct
This commit is contained in:
@@ -171,13 +171,19 @@ func (t *Tenant) ConvertTo(dstRaw conversion.Hub) error {
|
||||
}
|
||||
}
|
||||
if t.Spec.IngressClasses != nil {
|
||||
dst.Spec.IngressClasses = &capsulev1beta1.AllowedListSpec{
|
||||
if dst.Spec.IngressOptions == nil {
|
||||
dst.Spec.IngressOptions = &capsulev1beta1.IngressOptions{}
|
||||
}
|
||||
dst.Spec.IngressOptions.IngressClasses = &capsulev1beta1.AllowedListSpec{
|
||||
Exact: t.Spec.IngressClasses.Exact,
|
||||
Regex: t.Spec.IngressClasses.Regex,
|
||||
}
|
||||
}
|
||||
if t.Spec.IngressHostnames != nil {
|
||||
dst.Spec.IngressHostnames = &capsulev1beta1.AllowedListSpec{
|
||||
if dst.Spec.IngressOptions == nil {
|
||||
dst.Spec.IngressOptions = &capsulev1beta1.IngressOptions{}
|
||||
}
|
||||
dst.Spec.IngressOptions.IngressHostnames = &capsulev1beta1.AllowedListSpec{
|
||||
Exact: t.Spec.IngressHostnames.Exact,
|
||||
Regex: t.Spec.IngressHostnames.Regex,
|
||||
}
|
||||
@@ -453,16 +459,16 @@ func (t *Tenant) ConvertFrom(srcRaw conversion.Hub) error {
|
||||
Regex: src.Spec.StorageClasses.Regex,
|
||||
}
|
||||
}
|
||||
if src.Spec.IngressClasses != nil {
|
||||
if src.Spec.IngressOptions != nil && src.Spec.IngressOptions.IngressClasses != nil {
|
||||
t.Spec.IngressClasses = &AllowedListSpec{
|
||||
Exact: src.Spec.IngressClasses.Exact,
|
||||
Regex: src.Spec.IngressClasses.Regex,
|
||||
Exact: src.Spec.IngressOptions.IngressClasses.Exact,
|
||||
Regex: src.Spec.IngressOptions.IngressClasses.Regex,
|
||||
}
|
||||
}
|
||||
if src.Spec.IngressHostnames != nil {
|
||||
if src.Spec.IngressOptions != nil && src.Spec.IngressOptions.IngressHostnames != nil {
|
||||
t.Spec.IngressHostnames = &AllowedListSpec{
|
||||
Exact: src.Spec.IngressHostnames.Exact,
|
||||
Regex: src.Spec.IngressHostnames.Regex,
|
||||
Exact: src.Spec.IngressOptions.IngressHostnames.Exact,
|
||||
Regex: src.Spec.IngressOptions.IngressHostnames.Regex,
|
||||
}
|
||||
}
|
||||
if src.Spec.ContainerRegistries != nil {
|
||||
|
||||
@@ -229,11 +229,13 @@ func generateTenantsSpecs() (Tenant, capsulev1beta1.Tenant) {
|
||||
},
|
||||
},
|
||||
},
|
||||
NamespaceOptions: v1beta1NamespaceOptions,
|
||||
ServiceOptions: v1beta1ServiceOptions,
|
||||
StorageClasses: v1beta1AllowedListSpec,
|
||||
IngressClasses: v1beta1AllowedListSpec,
|
||||
IngressHostnames: v1beta1AllowedListSpec,
|
||||
NamespaceOptions: v1beta1NamespaceOptions,
|
||||
ServiceOptions: v1beta1ServiceOptions,
|
||||
StorageClasses: v1beta1AllowedListSpec,
|
||||
IngressOptions: &capsulev1beta1.IngressOptions{
|
||||
IngressClasses: v1beta1AllowedListSpec,
|
||||
IngressHostnames: v1beta1AllowedListSpec,
|
||||
},
|
||||
ContainerRegistries: v1beta1AllowedListSpec,
|
||||
NodeSelector: nodeSelector,
|
||||
NetworkPolicies: &capsulev1beta1.NetworkPolicySpec{
|
||||
|
||||
11
api/v1beta1/ingress_options.go
Normal file
11
api/v1beta1/ingress_options.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// Copyright 2020-2021 Clastix Labs
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package v1beta1
|
||||
|
||||
type IngressOptions struct {
|
||||
// Specifies the allowed IngressClasses assigned to the Tenant. Capsule assures that all Ingress resources created in the Tenant can use only one of the allowed IngressClasses. Optional.
|
||||
IngressClasses *AllowedListSpec `json:"ingressClasses,omitempty"`
|
||||
// Specifies the allowed hostnames in Ingresses for the given Tenant. Capsule assures that all Ingress resources created in the Tenant can use only one of the allowed hostnames. Optional.
|
||||
IngressHostnames *AllowedListSpec `json:"ingressHostnames,omitempty"`
|
||||
}
|
||||
@@ -17,10 +17,8 @@ type TenantSpec struct {
|
||||
ServiceOptions *ServiceOptions `json:"serviceOptions,omitempty"`
|
||||
// Specifies the allowed StorageClasses assigned to the Tenant. Capsule assures that all PersistentVolumeClaim resources created in the Tenant can use only one of the allowed StorageClasses. Optional.
|
||||
StorageClasses *AllowedListSpec `json:"storageClasses,omitempty"`
|
||||
// Specifies the allowed IngressClasses assigned to the Tenant. Capsule assures that all Ingress resources created in the Tenant can use only one of the allowed IngressClasses. Optional.
|
||||
IngressClasses *AllowedListSpec `json:"ingressClasses,omitempty"`
|
||||
// Specifies the allowed hostnames in Ingresses for the given Tenant. Capsule assures that all Ingress resources created in the Tenant can use only one of the allowed hostnames. Optional.
|
||||
IngressHostnames *AllowedListSpec `json:"ingressHostnames,omitempty"`
|
||||
// Specifies options for the Ingress resources, such as allowed hostnames and IngressClass. Optional.
|
||||
IngressOptions *IngressOptions `json:"ingressOptions,omitempty"`
|
||||
// Specifies the trusted Image Registries assigned to the Tenant. Capsule assures that all Pods resources created in the Tenant can use only one of the allowed trusted registries. Optional.
|
||||
ContainerRegistries *AllowedListSpec `json:"containerRegistries,omitempty"`
|
||||
// Specifies the label to control the placement of pods on a given pool of worker nodes. All namesapces created within the Tenant will have the node selector annotation. This annotation tells the Kubernetes scheduler to place pods on the nodes having the selector label. Optional.
|
||||
|
||||
@@ -149,6 +149,31 @@ func (in *ExternalServiceIPsSpec) DeepCopy() *ExternalServiceIPsSpec {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *IngressOptions) DeepCopyInto(out *IngressOptions) {
|
||||
*out = *in
|
||||
if in.IngressClasses != nil {
|
||||
in, out := &in.IngressClasses, &out.IngressClasses
|
||||
*out = new(AllowedListSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.IngressHostnames != nil {
|
||||
in, out := &in.IngressHostnames, &out.IngressHostnames
|
||||
*out = new(AllowedListSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressOptions.
|
||||
func (in *IngressOptions) DeepCopy() *IngressOptions {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(IngressOptions)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LimitRangesSpec) DeepCopyInto(out *LimitRangesSpec) {
|
||||
*out = *in
|
||||
@@ -417,14 +442,9 @@ func (in *TenantSpec) DeepCopyInto(out *TenantSpec) {
|
||||
*out = new(AllowedListSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.IngressClasses != nil {
|
||||
in, out := &in.IngressClasses, &out.IngressClasses
|
||||
*out = new(AllowedListSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.IngressHostnames != nil {
|
||||
in, out := &in.IngressHostnames, &out.IngressHostnames
|
||||
*out = new(AllowedListSpec)
|
||||
if in.IngressOptions != nil {
|
||||
in, out := &in.IngressOptions, &out.IngressOptions
|
||||
*out = new(IngressOptions)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.ContainerRegistries != nil {
|
||||
|
||||
@@ -64,12 +64,12 @@ func (r *Manager) syncNamespaceMetadata(namespace string, tnt *capsulev1beta1.Te
|
||||
annotations["scheduler.alpha.kubernetes.io/node-selector"] = strings.Join(selector, ",")
|
||||
}
|
||||
|
||||
if tnt.Spec.IngressClasses != nil {
|
||||
if len(tnt.Spec.IngressClasses.Exact) > 0 {
|
||||
annotations[capsulev1beta1.AvailableIngressClassesAnnotation] = strings.Join(tnt.Spec.IngressClasses.Exact, ",")
|
||||
if tnt.Spec.IngressOptions != nil && tnt.Spec.IngressOptions.IngressClasses != nil {
|
||||
if len(tnt.Spec.IngressOptions.IngressClasses.Exact) > 0 {
|
||||
annotations[capsulev1beta1.AvailableIngressClassesAnnotation] = strings.Join(tnt.Spec.IngressOptions.IngressClasses.Exact, ",")
|
||||
}
|
||||
if len(tnt.Spec.IngressClasses.Regex) > 0 {
|
||||
annotations[capsulev1beta1.AvailableIngressClassesRegexpAnnotation] = tnt.Spec.IngressClasses.Regex
|
||||
if len(tnt.Spec.IngressOptions.IngressClasses.Regex) > 0 {
|
||||
annotations[capsulev1beta1.AvailableIngressClassesRegexpAnnotation] = tnt.Spec.IngressOptions.IngressClasses.Regex
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@ func (IngressHostnames) Field() string {
|
||||
func (IngressHostnames) Func() client.IndexerFunc {
|
||||
return func(object client.Object) (out []string) {
|
||||
tenant := object.(*capsulev1beta1.Tenant)
|
||||
if tenant.Spec.IngressHostnames != nil {
|
||||
out = append(out, tenant.Spec.IngressHostnames.Exact...)
|
||||
if tenant.Spec.IngressOptions != nil && tenant.Spec.IngressOptions.IngressHostnames != nil {
|
||||
out = append(out, tenant.Spec.IngressOptions.IngressHostnames.Exact...)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -111,23 +111,23 @@ func (r *class) OnDelete(client.Client, *admission.Decoder, record.EventRecorder
|
||||
}
|
||||
|
||||
func (r *class) validateClass(tenant capsulev1beta1.Tenant, ingressClass *string) error {
|
||||
if tenant.Spec.IngressClasses == nil {
|
||||
if tenant.Spec.IngressOptions.IngressClasses == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if ingressClass == nil {
|
||||
return NewIngressClassNotValid(*tenant.Spec.IngressClasses)
|
||||
return NewIngressClassNotValid(*tenant.Spec.IngressOptions.IngressClasses)
|
||||
}
|
||||
|
||||
var valid, matched bool
|
||||
|
||||
if len(tenant.Spec.IngressClasses.Exact) > 0 {
|
||||
valid = tenant.Spec.IngressClasses.ExactMatch(*ingressClass)
|
||||
if len(tenant.Spec.IngressOptions.IngressClasses.Exact) > 0 {
|
||||
valid = tenant.Spec.IngressOptions.IngressClasses.ExactMatch(*ingressClass)
|
||||
}
|
||||
matched = tenant.Spec.IngressClasses.RegexMatch(*ingressClass)
|
||||
matched = tenant.Spec.IngressOptions.IngressClasses.RegexMatch(*ingressClass)
|
||||
|
||||
if !valid && !matched {
|
||||
return NewIngressClassForbidden(*ingressClass, *tenant.Spec.IngressClasses)
|
||||
return NewIngressClassForbidden(*ingressClass, *tenant.Spec.IngressOptions.IngressClasses)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
capsulev1beta1 "github.com/clastix/capsule/api/v1beta1"
|
||||
|
||||
"github.com/clastix/capsule/pkg/configuration"
|
||||
capsulewebhook "github.com/clastix/capsule/pkg/webhook"
|
||||
"github.com/clastix/capsule/pkg/webhook/utils"
|
||||
@@ -105,7 +104,7 @@ func (r *hostnames) OnDelete(client.Client, *admission.Decoder, record.EventReco
|
||||
}
|
||||
|
||||
func (r *hostnames) validateHostnames(tenant capsulev1beta1.Tenant, hostnames []string) error {
|
||||
if tenant.Spec.IngressHostnames == nil {
|
||||
if tenant.Spec.IngressOptions == nil || tenant.Spec.IngressOptions.IngressHostnames == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -114,7 +113,7 @@ func (r *hostnames) validateHostnames(tenant capsulev1beta1.Tenant, hostnames []
|
||||
var invalidHostnames []string
|
||||
if len(hostnames) > 0 {
|
||||
for _, currentHostname := range hostnames {
|
||||
isPresent := HostnamesList(tenant.Spec.IngressHostnames.Exact).IsStringInList(currentHostname)
|
||||
isPresent := HostnamesList(tenant.Spec.IngressOptions.IngressHostnames.Exact).IsStringInList(currentHostname)
|
||||
if !isPresent {
|
||||
invalidHostnames = append(invalidHostnames, currentHostname)
|
||||
}
|
||||
@@ -125,10 +124,10 @@ func (r *hostnames) validateHostnames(tenant capsulev1beta1.Tenant, hostnames []
|
||||
}
|
||||
|
||||
var notMatchingHostnames []string
|
||||
allowedRegex := tenant.Spec.IngressHostnames.Regex
|
||||
allowedRegex := tenant.Spec.IngressOptions.IngressHostnames.Regex
|
||||
if len(allowedRegex) > 0 {
|
||||
for _, currentHostname := range hostnames {
|
||||
matched, _ = regexp.MatchString(tenant.Spec.IngressHostnames.Regex, currentHostname)
|
||||
matched, _ = regexp.MatchString(allowedRegex, currentHostname)
|
||||
if !matched {
|
||||
notMatchingHostnames = append(notMatchingHostnames, currentHostname)
|
||||
}
|
||||
@@ -139,7 +138,7 @@ func (r *hostnames) validateHostnames(tenant capsulev1beta1.Tenant, hostnames []
|
||||
}
|
||||
|
||||
if !valid && !matched {
|
||||
return NewIngressHostnamesNotValid(invalidHostnames, notMatchingHostnames, *tenant.Spec.IngressHostnames)
|
||||
return NewIngressHostnamesNotValid(invalidHostnames, notMatchingHostnames, *tenant.Spec.IngressOptions.IngressHostnames)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -30,8 +30,8 @@ func (h *hostnameRegexHandler) validate(decoder *admission.Decoder, req admissio
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
if tenant.Spec.IngressHostnames != nil && len(tenant.Spec.IngressHostnames.Regex) > 0 {
|
||||
if _, err := regexp.Compile(tenant.Spec.IngressHostnames.Regex); err != nil {
|
||||
if tenant.Spec.IngressOptions.IngressHostnames != nil && len(tenant.Spec.IngressOptions.IngressHostnames.Regex) > 0 {
|
||||
if _, err := regexp.Compile(tenant.Spec.IngressOptions.IngressHostnames.Regex); err != nil {
|
||||
response := admission.Denied("unable to compile allowedHostnames allowedRegex")
|
||||
|
||||
return &response
|
||||
|
||||
@@ -33,8 +33,8 @@ func (h *hostnamesCollisionHandler) validateTenant(ctx context.Context, req admi
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
if !h.configuration.AllowTenantIngressHostnamesCollision() && tenant.Spec.IngressHostnames != nil && len(tenant.Spec.IngressHostnames.Exact) > 0 {
|
||||
for _, h := range tenant.Spec.IngressHostnames.Exact {
|
||||
if !h.configuration.AllowTenantIngressHostnamesCollision() && tenant.Spec.IngressOptions != nil && tenant.Spec.IngressOptions.IngressHostnames != nil && len(tenant.Spec.IngressOptions.IngressHostnames.Exact) > 0 {
|
||||
for _, h := range tenant.Spec.IngressOptions.IngressHostnames.Exact {
|
||||
tntList := &capsulev1beta1.TenantList{}
|
||||
if err := clt.List(ctx, tntList, client.MatchingFieldsSelector{
|
||||
Selector: fields.OneTermEqualSelector(".spec.ingressHostnames", h),
|
||||
|
||||
@@ -30,8 +30,8 @@ func (h *ingressClassRegexHandler) validate(decoder *admission.Decoder, req admi
|
||||
return utils.ErroredResponse(err)
|
||||
}
|
||||
|
||||
if tenant.Spec.IngressClasses != nil && len(tenant.Spec.IngressClasses.Regex) > 0 {
|
||||
if _, err := regexp.Compile(tenant.Spec.IngressClasses.Regex); err != nil {
|
||||
if tenant.Spec.IngressOptions != nil && tenant.Spec.IngressOptions.IngressClasses != nil && len(tenant.Spec.IngressOptions.IngressClasses.Regex) > 0 {
|
||||
if _, err := regexp.Compile(tenant.Spec.IngressOptions.IngressClasses.Regex); err != nil {
|
||||
response := admission.Denied("unable to compile ingressClasses allowedRegex")
|
||||
|
||||
return &response
|
||||
|
||||
Reference in New Issue
Block a user