astefanutti commented on a change in pull request #1787: URL: https://github.com/apache/camel-k/pull/1787#discussion_r512063252
########## File path: pkg/trait/pdb.go ########## @@ -0,0 +1,103 @@ +package trait + +import ( + v1 "github.com/apache/camel-k/pkg/apis/camel/v1" + "github.com/google/go-cmp/cmp" + "k8s.io/api/policy/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) + +type pdbTrait struct { + BaseTrait `property:",squash"` + MaxUnavailable string `property:"max-unavailable" json:"maxUnavailable,omitempty"` + MinAvailable string `property:"min-available" json:"minAvailable,omitempty"` +} + +func newPdbTrait() Trait { + return &pdbTrait{ + BaseTrait: NewBaseTrait("pdb", 900), + } +} + +func (t *pdbTrait) Configure(e *Environment) (bool, error) { + return e.IntegrationInPhase( Review comment: The `Configure` method should be truthy when the integration is in phases `Deploying` and `Running`, and if the trait is explicitly enabled. ########## File path: pkg/trait/pdb.go ########## @@ -0,0 +1,103 @@ +package trait + +import ( + v1 "github.com/apache/camel-k/pkg/apis/camel/v1" + "github.com/google/go-cmp/cmp" + "k8s.io/api/policy/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) + +type pdbTrait struct { + BaseTrait `property:",squash"` + MaxUnavailable string `property:"max-unavailable" json:"maxUnavailable,omitempty"` + MinAvailable string `property:"min-available" json:"minAvailable,omitempty"` +} + +func newPdbTrait() Trait { + return &pdbTrait{ + BaseTrait: NewBaseTrait("pdb", 900), + } +} + +func (t *pdbTrait) Configure(e *Environment) (bool, error) { + return e.IntegrationInPhase( + v1.IntegrationPhaseRunning, + ), nil +} + +func (t *pdbTrait) Apply(e *Environment) error { + pdbName := "pdb-" + e.Integration.Name + "-it" + var pdb *v1beta1.PodDisruptionBudget + var err error + + if pdb, err = t.Client.PolicyV1beta1().PodDisruptionBudgets(e.DetermineNamespace()).Get(pdbName, metav1.GetOptions{}); err == nil { + if a := t.havePdbConfChanged(pdb); a { + err = t.Client.PolicyV1beta1().PodDisruptionBudgets(e.DetermineNamespace()).Delete(pdbName, &metav1.DeleteOptions{}) + updated := t.generatePodDisruptionBudget(pdbName, e.Integration) + if _, err = t.Client.PolicyV1beta1().PodDisruptionBudgets(e.DetermineNamespace()).Create(updated); err == nil { + t.L.Info("PodDisruptionBudget updated: ", pdb.Spec) + } + } + + } else { + t.L.Info("PodDisruptionBudget for the integration", e.Integration.Name, "not found") + pdb = t.generatePodDisruptionBudget(pdbName, e.Integration) + if _, err = t.Client.PolicyV1beta1().PodDisruptionBudgets(e.DetermineNamespace()).Create(pdb); err == nil { + t.L.Error(err, "error during creating pdb", err) + } + } + return err +} + +// check if configuration for pdb has changed, if yes update values in pdbtrait +func (t *pdbTrait) havePdbConfChanged(pdb *v1beta1.PodDisruptionBudget) bool { + return !cmp.Equal(t.MaxUnavailable, pdb.Spec.MaxUnavailable) || !cmp.Equal(t.MinAvailable, pdb.Spec.MinAvailable) +} +func (t *pdbTrait) generatePodDisruptionBudget(pdbName string, integration *v1.Integration) *v1beta1.PodDisruptionBudget { + controller := true + blockOwnerDeletion := true + spec := v1beta1.PodDisruptionBudgetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "camel.apache.org/integration": integration.Name, + }, + }, + } + var min, max intstr.IntOrString + + if t.MinAvailable == "" && t.MaxUnavailable == "" { + //set the default + max = intstr.Parse("1") + spec.MaxUnavailable = &max + } else if t.MinAvailable != "" { + // sets to maxUnavailable to nil because only one parameter is allowed to be set + min = intstr.Parse(t.MinAvailable) + spec.MinAvailable = &min + spec.MaxUnavailable = nil + t.MaxUnavailable = "" + } else { + //set maxAvailable + max = intstr.Parse(t.MaxUnavailable) + spec.MaxUnavailable = &max + } + + return &v1beta1.PodDisruptionBudget{ + ObjectMeta: metav1.ObjectMeta{ + Name: pdbName, + Namespace: integration.Namespace, + Labels: integration.Labels, + OwnerReferences: []metav1.OwnerReference{ Review comment: This can be removed once the PDB is added to `environment.Resources` as the _owner_ trait is responsible to set ownership for the environment resources. ########## File path: pkg/trait/pdb.go ########## @@ -0,0 +1,103 @@ +package trait + +import ( + v1 "github.com/apache/camel-k/pkg/apis/camel/v1" + "github.com/google/go-cmp/cmp" + "k8s.io/api/policy/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) + +type pdbTrait struct { + BaseTrait `property:",squash"` + MaxUnavailable string `property:"max-unavailable" json:"maxUnavailable,omitempty"` + MinAvailable string `property:"min-available" json:"minAvailable,omitempty"` +} + +func newPdbTrait() Trait { + return &pdbTrait{ + BaseTrait: NewBaseTrait("pdb", 900), + } +} + +func (t *pdbTrait) Configure(e *Environment) (bool, error) { + return e.IntegrationInPhase( + v1.IntegrationPhaseRunning, + ), nil +} + +func (t *pdbTrait) Apply(e *Environment) error { + pdbName := "pdb-" + e.Integration.Name + "-it" + var pdb *v1beta1.PodDisruptionBudget + var err error + + if pdb, err = t.Client.PolicyV1beta1().PodDisruptionBudgets(e.DetermineNamespace()).Get(pdbName, metav1.GetOptions{}); err == nil { Review comment: In order to avoid each trait to implement that get / create / update logic, the idea is that each trait only adds their resources into the `environment.Resources` list. Then the _deployer_ trait does that get / create / update logic generically: https://github.com/apache/camel-k/blob/530164176b6d8354a781d1dcbe1fb21c1d92386b/pkg/trait/deployer.go#L62-L116. ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org