Skip to content

Commit

Permalink
Use limitador pdb type
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-cattermole committed Aug 16, 2023
1 parent b9a7371 commit 8a4a0c9
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 144 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ local-redeploy: ## re-deploy operator in local kind cluster
$(MAKE) docker-build
@echo "Deploying Limitador control plane"
$(KIND) load docker-image ${IMG} --name ${KIND_CLUSTER_NAME}
make deploy-develmode
$(MAKE) deploy-develmode
kubectl rollout restart deployment -n limitador-operator-system limitador-operator-controller-manager
@echo "Wait for all deployments to be up"
kubectl -n limitador-operator-system wait --timeout=300s --for=condition=Available deployments --all
Expand Down
19 changes: 17 additions & 2 deletions api/v1alpha1/limitador_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import (
"github.com/go-logr/logr"
"github.com/google/go-cmp/cmp"
corev1 "k8s.io/api/core/v1"
policyv1 "k8s.io/api/policy/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"

"github.com/kuadrant/limitador-operator/pkg/helpers"
)
Expand Down Expand Up @@ -64,7 +64,7 @@ type LimitadorSpec struct {
Limits []RateLimit `json:"limits,omitempty"`

// +optional
PodDisruptionBudget *policyv1.PodDisruptionBudgetSpec `json:"pdb,omitempty"`
PodDisruptionBudget *PodDisruptionBudgetType `json:"pdb,omitempty"`
}

//+kubebuilder:object:root=true
Expand Down Expand Up @@ -292,3 +292,18 @@ func (s *LimitadorStatus) Equals(other *LimitadorStatus, logger logr.Logger) boo
func init() {
SchemeBuilder.Register(&Limitador{}, &LimitadorList{})
}

type PodDisruptionBudgetType struct {
// An eviction is allowed if at most "maxUnavailable" pods selected by
// "selector" are unavailable after the eviction, i.e. even in absence of
// the evicted pod. For example, one can prevent all voluntary evictions
// by specifying 0. This is a mutually exclusive setting with "minAvailable".
// +optional
MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"`
// An eviction is allowed if at least "minAvailable" pods selected by
// "selector" will still be available after the eviction, i.e. even in the
// absence of the evicted pod. So for example you can prevent all voluntary
// evictions by specifying "100%".
// +optional
MinAvailable *intstr.IntOrString `json:"minAvailable,omitempty"`
}
35 changes: 30 additions & 5 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 0 additions & 49 deletions bundle/manifests/limitador.kuadrant.io_limitadors.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ spec:
type: object
type: object
pdb:
description: PodDisruptionBudgetSpec is a description of a PodDisruptionBudget.
properties:
maxUnavailable:
anyOf:
Expand All @@ -98,54 +97,6 @@ spec:
example you can prevent all voluntary evictions by specifying
"100%".
x-kubernetes-int-or-string: true
selector:
description: Label query over pods whose evictions are managed
by the disruption budget. A null selector will match no pods,
while an empty ({}) selector will select all pods within the
namespace.
properties:
matchExpressions:
description: matchExpressions is a list of label selector
requirements. The requirements are ANDed.
items:
description: A label selector requirement is a selector
that contains values, a key, and an operator that relates
the key and values.
properties:
key:
description: key is the label key that the selector
applies to.
type: string
operator:
description: operator represents a key's relationship
to a set of values. Valid operators are In, NotIn,
Exists and DoesNotExist.
type: string
values:
description: values is an array of string values. If
the operator is In or NotIn, the values array must
be non-empty. If the operator is Exists or DoesNotExist,
the values array must be empty. This array is replaced
during a strategic merge patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: array
matchLabels:
additionalProperties:
type: string
description: matchLabels is a map of {key,value} pairs. A
single {key,value} in the matchLabels map is equivalent
to an element of matchExpressions, whose key field is "key",
the operator is "In", and the values array contains only
"value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
type: object
rateLimitHeaders:
description: RateLimitHeadersType defines the valid options for the
Expand Down
49 changes: 0 additions & 49 deletions config/crd/bases/limitador.kuadrant.io_limitadors.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ spec:
type: object
type: object
pdb:
description: PodDisruptionBudgetSpec is a description of a PodDisruptionBudget.
properties:
maxUnavailable:
anyOf:
Expand All @@ -99,54 +98,6 @@ spec:
example you can prevent all voluntary evictions by specifying
"100%".
x-kubernetes-int-or-string: true
selector:
description: Label query over pods whose evictions are managed
by the disruption budget. A null selector will match no pods,
while an empty ({}) selector will select all pods within the
namespace.
properties:
matchExpressions:
description: matchExpressions is a list of label selector
requirements. The requirements are ANDed.
items:
description: A label selector requirement is a selector
that contains values, a key, and an operator that relates
the key and values.
properties:
key:
description: key is the label key that the selector
applies to.
type: string
operator:
description: operator represents a key's relationship
to a set of values. Valid operators are In, NotIn,
Exists and DoesNotExist.
type: string
values:
description: values is an array of string values. If
the operator is In or NotIn, the values array must
be non-empty. If the operator is Exists or DoesNotExist,
the values array must be empty. This array is replaced
during a strategic merge patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: array
matchLabels:
additionalProperties:
type: string
description: matchLabels is a map of {key,value} pairs. A
single {key,value} in the matchLabels map is equivalent
to an element of matchExpressions, whose key field is "key",
the operator is "In", and the values array contains only
"value". The requirements are ANDed.
type: object
type: object
x-kubernetes-map-type: atomic
type: object
rateLimitHeaders:
description: RateLimitHeadersType defines the valid options for the
Expand Down
17 changes: 2 additions & 15 deletions controllers/limitador_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
v1 "k8s.io/api/core/v1"
policyv1 "k8s.io/api/policy/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -135,23 +134,11 @@ func (r *LimitadorReconciler) reconcilePdb(ctx context.Context, limitadorObj *li
return nil
}

limitadorPdb := limitadorObj.Spec.PodDisruptionBudget
if err := limitador.ValidatePDB(limitadorPdb); err != nil {
pdb := limitador.PodDisruptionBudget(limitadorObj)
if err := limitador.ValidatePDB(pdb); err != nil {
return err
}

limitadorPdb.Selector = &metav1.LabelSelector{
MatchLabels: map[string]string{"app": "limitador"},
}

pdb := &policyv1.PodDisruptionBudget{
ObjectMeta: metav1.ObjectMeta{
Name: limitador.PodDisruptionBudgetName(limitadorObj),
Namespace: limitadorObj.ObjectMeta.Namespace,
},
Spec: *limitadorPdb,
}

// controller reference
if err := r.SetOwnerReference(limitadorObj, pdb); err != nil {
return err
Expand Down
4 changes: 2 additions & 2 deletions controllers/limitador_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ var _ = Describe("Limitador controller", func() {
GRPC: grpcPort,
},
Limits: limits,
PodDisruptionBudget: &policyv1.PodDisruptionBudgetSpec{
PodDisruptionBudget: &limitadorv1alpha1.PodDisruptionBudgetType{
MaxUnavailable: maxUnavailable,
},
},
Expand Down Expand Up @@ -259,7 +259,7 @@ var _ = Describe("Limitador controller", func() {
return err == nil
}, timeout, interval).Should(BeTrue())
Expect(createdPdb.Spec.MaxUnavailable).To(Equal(maxUnavailable))
Expect(createdPdb.Spec.Selector.MatchLabels).To(Equal(map[string]string{"app": "limitador"}))
Expect(createdPdb.Spec.Selector.MatchLabels).To(Equal(limitador.Labels()))
})
})

Expand Down
35 changes: 26 additions & 9 deletions pkg/limitador/k8s_objects.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func Service(limitador *limitadorv1alpha1.Limitador) *v1.Service {
ObjectMeta: metav1.ObjectMeta{
Name: ServiceName(limitador),
Namespace: limitador.ObjectMeta.Namespace, // TODO: revisit later. For now assume same.
Labels: labels(),
Labels: Labels(),
},
Spec: v1.ServiceSpec{
Ports: []v1.ServicePort{
Expand All @@ -48,7 +48,7 @@ func Service(limitador *limitadorv1alpha1.Limitador) *v1.Service {
TargetPort: intstr.FromString("grpc"),
},
},
Selector: labels(),
Selector: Labels(),
ClusterIP: v1.ClusterIPNone,
Type: v1.ServiceTypeClusterIP,
},
Expand All @@ -74,16 +74,16 @@ func Deployment(limitador *limitadorv1alpha1.Limitador, storageConfigSecret *v1.
ObjectMeta: metav1.ObjectMeta{
Name: limitador.ObjectMeta.Name, // TODO: revisit later. For now assume same.
Namespace: limitador.ObjectMeta.Namespace, // TODO: revisit later. For now assume same.
Labels: labels(),
Labels: Labels(),
},
Spec: appsv1.DeploymentSpec{
Replicas: &replicas,
Selector: &metav1.LabelSelector{
MatchLabels: labels(),
MatchLabels: Labels(),
},
Template: v1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: labels(),
Labels: Labels(),
},
Spec: v1.PodSpec{
Containers: []v1.Container{
Expand Down Expand Up @@ -171,7 +171,7 @@ func LimitsConfigMap(limitador *limitadorv1alpha1.Limitador) (*v1.ConfigMap, err
ObjectMeta: metav1.ObjectMeta{
Name: LimitsCMNamePrefix + limitador.Name,
Namespace: limitador.Namespace,
Labels: map[string]string{"app": "limitador"},
Labels: Labels(),
},
}, nil
}
Expand All @@ -180,18 +180,35 @@ func ServiceName(limitadorObj *limitadorv1alpha1.Limitador) string {
return fmt.Sprintf("limitador-%s", limitadorObj.Name)
}

func PodDisruptionBudget(limitadorObj *limitadorv1alpha1.Limitador) *policyv1.PodDisruptionBudget {
return &policyv1.PodDisruptionBudget{
ObjectMeta: metav1.ObjectMeta{
Name: PodDisruptionBudgetName(limitadorObj),
Namespace: limitadorObj.ObjectMeta.Namespace,
Labels: Labels(),
},
Spec: policyv1.PodDisruptionBudgetSpec{
MaxUnavailable: limitadorObj.Spec.PodDisruptionBudget.MaxUnavailable,
MinAvailable: limitadorObj.Spec.PodDisruptionBudget.MinAvailable,
Selector: &metav1.LabelSelector{
MatchLabels: Labels(),
},
},
}
}

func PodDisruptionBudgetName(limitadorObj *limitadorv1alpha1.Limitador) string {
return fmt.Sprintf("limitador-%s", limitadorObj.Name)
}

func ValidatePDB(pdb *policyv1.PodDisruptionBudgetSpec) error {
if pdb.MaxUnavailable != nil && pdb.MinAvailable != nil {
func ValidatePDB(pdb *policyv1.PodDisruptionBudget) error {
if pdb.Spec.MaxUnavailable != nil && pdb.Spec.MinAvailable != nil {
return fmt.Errorf("pdb spec invalid, maxunavailable and minavailable are mutually exclusive")
}
return nil
}

func labels() map[string]string {
func Labels() map[string]string {
return map[string]string{"app": "limitador"}
}

Expand Down
Loading

0 comments on commit 8a4a0c9

Please sign in to comment.