Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- (Bugfix) Fix and document action timeouts
- (Feature) Propagate sidecars' ports to a member's service
- (Debug Package) Initial commit
- (Feature) Detach PVC from deployment in Ordered indexing method

## [1.2.16](https://github.com/arangodb/kube-arangodb/tree/1.2.16) (2022-09-14)
- (Feature) Add ArangoDeployment ServerGroupStatus
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/deployment/v1/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

"github.com/arangodb/kube-arangodb/pkg/apis/deployment"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/tools"
)

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand All @@ -49,6 +50,10 @@ type ArangoDeployment struct {
Status DeploymentStatus `json:"status,omitempty"`
}

func (d *ArangoDeployment) OwnerOf(in meta.Object) bool {
return tools.IsOwner(d.AsOwner(), in)
}

type ServerGroupFunc func(ServerGroup, ServerGroupSpec, *MemberStatusList) error

// AsOwner creates an OwnerReference for the given deployment
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/deployment/v2alpha1/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

"github.com/arangodb/kube-arangodb/pkg/apis/deployment"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/tools"
)

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand All @@ -49,6 +50,10 @@ type ArangoDeployment struct {
Status DeploymentStatus `json:"status,omitempty"`
}

func (d *ArangoDeployment) OwnerOf(in meta.Object) bool {
return tools.IsOwner(d.AsOwner(), in)
}

type ServerGroupFunc func(ServerGroup, ServerGroupSpec, *MemberStatusList) error

// AsOwner creates an OwnerReference for the given deployment
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/replication/v1/replication.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
meta "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/arangodb/kube-arangodb/pkg/apis/replication"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/tools"
)

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand All @@ -49,6 +50,10 @@ type ArangoDeploymentReplication struct {
Status DeploymentReplicationStatus `json:"status"`
}

func (d *ArangoDeploymentReplication) OwnerOf(in meta.Object) bool {
return tools.IsOwner(d.AsOwner(), in)
}

// AsOwner creates an OwnerReference for the given replication
func (d *ArangoDeploymentReplication) AsOwner() meta.OwnerReference {
trueVar := true
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/replication/v2alpha1/replication.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
meta "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/arangodb/kube-arangodb/pkg/apis/replication"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/tools"
)

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand All @@ -49,6 +50,10 @@ type ArangoDeploymentReplication struct {
Status DeploymentReplicationStatus `json:"status"`
}

func (d *ArangoDeploymentReplication) OwnerOf(in meta.Object) bool {
return tools.IsOwner(d.AsOwner(), in)
}

// AsOwner creates an OwnerReference for the given replication
func (d *ArangoDeploymentReplication) AsOwner() meta.OwnerReference {
trueVar := true
Expand Down
6 changes: 6 additions & 0 deletions pkg/apis/storage/v1alpha/local_storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ package v1alpha

import (
meta "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/tools"
)

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
Expand All @@ -48,6 +50,10 @@ type ArangoLocalStorage struct {
Status LocalStorageStatus `json:"status"`
}

func (d *ArangoLocalStorage) OwnerOf(in meta.Object) bool {
return tools.IsOwner(d.AsOwner(), in)
}

// AsOwner creates an OwnerReference for the given storage
func (d *ArangoLocalStorage) AsOwner() meta.OwnerReference {
return meta.OwnerReference{
Expand Down
3 changes: 2 additions & 1 deletion pkg/deployment/reconcile/plan_builder_tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import (
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
memberTls "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/tls"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/tools"
)

const CertificateRenewalMargin = 7 * 24 * time.Hour
Expand Down Expand Up @@ -207,7 +208,7 @@ func (r *Reconciler) createCARenewalPlan(ctx context.Context, apiObject k8sutil.
return nil
}

if !k8sutil.IsOwner(apiObject.AsOwner(), caSecret) {
if !tools.IsOwner(apiObject.AsOwner(), caSecret) {
r.planLogger.Str("secret", spec.TLS.GetCASecretName()).Debug("CA Secret is not owned by Operator, we wont do anything")
return nil
}
Expand Down
19 changes: 10 additions & 9 deletions pkg/deployment/resources/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
"github.com/arangodb/kube-arangodb/pkg/util/globals"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/tools"
)

type PatchFunc func(name string, d []byte) error
Expand Down Expand Up @@ -180,7 +181,7 @@ func (r *Resources) ensureSecretsAnnotations(patch PatchFunc, cachedStatus inspe
r.ensureAnnotationsMap(secret.Kind, secret, spec, patch)
return nil
}, func(secret *core.Secret) bool {
return k8sutil.IsChildResource(kind, name, namespace, secret)
return tools.IsChildResource(kind, name, namespace, secret)
}); err != nil {
return err
}
Expand All @@ -193,7 +194,7 @@ func (r *Resources) ensureServiceAccountsAnnotations(patch PatchFunc, cachedStat
r.ensureAnnotationsMap(serviceAccount.Kind, serviceAccount, spec, patch)
return nil
}, func(serviceAccount *core.ServiceAccount) bool {
return k8sutil.IsChildResource(kind, name, namespace, serviceAccount)
return tools.IsChildResource(kind, name, namespace, serviceAccount)
}); err != nil {
return err
}
Expand All @@ -206,7 +207,7 @@ func (r *Resources) ensureServicesAnnotations(patch PatchFunc, cachedStatus insp
r.ensureAnnotationsMap(service.Kind, service, spec, patch)
return nil
}, func(service *core.Service) bool {
return k8sutil.IsChildResource(kind, name, namespace, service)
return tools.IsChildResource(kind, name, namespace, service)
}); err != nil {
return err
}
Expand All @@ -221,7 +222,7 @@ func (r *Resources) ensurePdbsAnnotations(patch PatchFunc, cachedStatus inspecto
r.ensureAnnotationsMap(podDisruptionBudget.Kind, podDisruptionBudget, spec, patch)
return nil
}, func(podDisruptionBudget *policyv1.PodDisruptionBudget) bool {
return k8sutil.IsChildResource(kind, name, namespace, podDisruptionBudget)
return tools.IsChildResource(kind, name, namespace, podDisruptionBudget)
}); err != nil {
return err
}
Expand All @@ -237,7 +238,7 @@ func (r *Resources) ensurePdbsAnnotations(patch PatchFunc, cachedStatus inspecto
r.ensureAnnotationsMap(podDisruptionBudget.Kind, podDisruptionBudget, spec, patch)
return nil
}, func(podDisruptionBudget *policyv1beta1.PodDisruptionBudget) bool {
return k8sutil.IsChildResource(kind, name, namespace, podDisruptionBudget)
return tools.IsChildResource(kind, name, namespace, podDisruptionBudget)
}); err != nil {
return err
}
Expand All @@ -250,7 +251,7 @@ func (r *Resources) ensurePvcsAnnotations(patch PatchFunc, cachedStatus inspecto
r.ensureGroupAnnotationsMap(persistentVolumeClaim.Kind, persistentVolumeClaim, spec, patch)
return nil
}, func(persistentVolumeClaim *core.PersistentVolumeClaim) bool {
return k8sutil.IsChildResource(kind, name, namespace, persistentVolumeClaim)
return tools.IsChildResource(kind, name, namespace, persistentVolumeClaim)
}); err != nil {
return err
}
Expand All @@ -270,7 +271,7 @@ func (r *Resources) ensureServiceMonitorsAnnotations(patch PatchFunc, cachedStat
r.ensureAnnotationsMap(serviceMonitor.Kind, serviceMonitor, spec, patch)
return nil
}, func(serviceMonitor *monitoring.ServiceMonitor) bool {
return k8sutil.IsChildResource(kind, name, namespace, serviceMonitor)
return tools.IsChildResource(kind, name, namespace, serviceMonitor)
}); err != nil {
return err
}
Expand Down Expand Up @@ -298,7 +299,7 @@ func (r *Resources) ensurePodsAnnotations(patch PatchFunc, cachedStatus inspecto
r.ensureGroupAnnotationsMap(pod.Kind, pod, spec, patch)
return nil
}, func(pod *core.Pod) bool {
return k8sutil.IsChildResource(kind, name, namespace, pod)
return tools.IsChildResource(kind, name, namespace, pod)
}); err != nil {
return err
}
Expand All @@ -307,7 +308,7 @@ func (r *Resources) ensurePodsAnnotations(patch PatchFunc, cachedStatus inspecto
}

func (r *Resources) isChildResource(obj meta.Object) bool {
return k8sutil.IsChildResource(deployment.ArangoDeploymentResourceKind,
return tools.IsChildResource(deployment.ArangoDeploymentResourceKind,
r.context.GetAPIObject().GetName(),
r.context.GetAPIObject().GetNamespace(),
obj)
Expand Down
51 changes: 49 additions & 2 deletions pkg/deployment/resources/pvc_inspector.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"

api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/deployment/patch"
"github.com/arangodb/kube-arangodb/pkg/metrics"
"github.com/arangodb/kube-arangodb/pkg/util"
Expand Down Expand Up @@ -66,6 +67,12 @@ func (r *Resources) InspectPVCs(ctx context.Context, cachedStatus inspectorInter
memberStatus, group, found := status.Members.MemberStatusByPVCName(pvc.GetName())
if !found {
log.Str("pvc", pvc.GetName()).Debug("no memberstatus found for PVC")

if !r.context.GetAPIObject().OwnerOf(pvc) {
log.Str("pvc", pvc.GetName()).Debug("PVC is not owned by us")
return nil
}

if k8sutil.IsPersistentVolumeClaimMarkedForDeletion(pvc) && len(pvc.GetFinalizers()) > 0 {
// Strange, pvc belongs to us, but we have no member for it.
// Remove all finalizers, so it can be removed.
Expand All @@ -79,9 +86,23 @@ func (r *Resources) InspectPVCs(ctx context.Context, cachedStatus inspectorInter
return nil
}

groupSpec := r.context.GetSpec().GetServerGroupSpec(group)

owner := r.context.GetAPIObject().AsOwner()
if k8sutil.UpdateOwnerRefToObjectIfNeeded(pvc.GetObjectMeta(), &owner) {
q := patch.NewPatch(patch.ItemReplace(patch.NewPath("metadata", "ownerReferences"), pvc.ObjectMeta.OwnerReferences))

ownerUpdate := k8sutil.UpdateOwnerRefToObjectIfNeeded
if groupSpec.IndexMethod.Get() == api.ServerGroupIndexMethodOrdered {
ownerUpdate = k8sutil.RemoveOwnerRefToObjectIfNeeded
}

if ownerUpdate(pvc.GetObjectMeta(), &owner) {
q := patch.NewPatch()
if f := pvc.ObjectMeta.OwnerReferences; len(f) == 0 {
q.Add(patch.ItemRemove(patch.NewPath("metadata", "ownerReferences")))
} else {
q.Add(patch.ItemReplace(patch.NewPath("metadata", "ownerReferences"), pvc.ObjectMeta.OwnerReferences))
}

d, err := q.Marshal()
if err != nil {
log.Err(err).Debug("Failed to prepare PVC patch (ownerReferences)")
Expand All @@ -107,6 +128,32 @@ func (r *Resources) InspectPVCs(ctx context.Context, cachedStatus inspectorInter
} else {
nextInterval = nextInterval.ReduceTo(x)
}
} else {
// Ensure finalizers
if r.ensurePVCFinalizers(pvc) {
q := patch.NewPatch()
if f := pvc.Finalizers; len(f) == 0 {
q.Add(patch.ItemRemove(patch.NewPath("metadata", "finalizers")))
} else {
q.Add(patch.ItemReplace(patch.NewPath("metadata", "finalizers"), f))
}

d, err := q.Marshal()
if err != nil {
log.Err(err).Debug("Failed to prepare PVC patch (finalizers)")
return errors.WithStack(err)
}

err = globals.GetGlobalTimeouts().Kubernetes().RunWithTimeout(ctx, func(ctxChild context.Context) error {
_, err := cachedStatus.PersistentVolumeClaimsModInterface().V1().Patch(ctxChild, pvc.GetName(), types.JSONPatchType, d, meta.PatchOptions{})
return err
})

if err != nil {
log.Err(err).Debug("Failed to update PVC (ownerReferences)")
return errors.WithStack(err)
}
}
}

return nil
Expand Down
10 changes: 8 additions & 2 deletions pkg/deployment/resources/pvcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ package resources
import (
"context"

meta "k8s.io/apimachinery/pkg/apis/meta/v1"

api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/util/constants"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
Expand All @@ -32,10 +34,14 @@ import (
)

// createPVCFinalizers creates a list of finalizers for a PVC created for the given group.
func (r *Resources) createPVCFinalizers(group api.ServerGroup) []string {
func (r *Resources) createPVCFinalizers() []string {
return []string{constants.FinalizerPVCMemberExists}
}

func (r *Resources) ensurePVCFinalizers(in meta.Object) bool {
return k8sutil.EnsureFinalizers(in, r.createPVCFinalizers(), nil)
}

// EnsurePVCs creates all PVC's listed in member status
func (r *Resources) EnsurePVCs(ctx context.Context, cachedStatus inspectorInterface.Inspector) error {
apiObject := r.context.GetAPIObject()
Expand All @@ -59,7 +65,7 @@ func (r *Resources) EnsurePVCs(ctx context.Context, cachedStatus inspectorInterf
role := group.AsRole()
resources := spec.Resources
vct := spec.VolumeClaimTemplate
finalizers := r.createPVCFinalizers(group)
finalizers := r.createPVCFinalizers()
err := globals.GetGlobalTimeouts().Kubernetes().RunWithTimeout(ctx, func(ctxChild context.Context) error {
return k8sutil.CreatePersistentVolumeClaim(ctxChild, cachedStatus.PersistentVolumeClaimsModInterface().V1(),
m.PersistentVolumeClaimName, deploymentName, storageClassName, role, enforceAntiAffinity,
Expand Down
2 changes: 2 additions & 0 deletions pkg/util/k8sutil/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ type APIObject interface {
meta.Object
// AsOwner creates an OwnerReference for the given deployment
AsOwner() meta.OwnerReference

OwnerOf(in meta.Object) bool
}

// NewMemberAddEvent creates an event indicating that a member was added.
Expand Down
40 changes: 40 additions & 0 deletions pkg/util/k8sutil/finalizers.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package k8sutil

import (
"context"
"sort"

core "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -158,3 +159,42 @@ func RemoveFinalizers(finalizers []string, getFunc func() (meta.Object, error),
}
}
}

func EnsureFinalizers(in meta.Object, exists []string, missing []string) bool {
present := make(map[string]bool, len(in.GetFinalizers()))

for _, k := range in.GetFinalizers() {
present[k] = true
}

changed := false

for _, k := range exists {
if _, ok := present[k]; !ok {
present[k] = true
changed = true
}
}

for _, k := range missing {
if _, ok := present[k]; ok {
delete(present, k)
changed = true
}
}

if !changed {
return false
}

q := make([]string, 0, len(present))

for k := range present {
q = append(q, k)
}

sort.Strings(q)

in.SetFinalizers(q)
return true
}
Loading