mirror of
https://github.com/arangodb/kube-arangodb.git
synced 2024-12-14 11:57:37 +00:00
[Feature] Use inspector for ArangoMember (#1176)
This commit is contained in:
parent
2f94237256
commit
7420e13b5c
15 changed files with 185 additions and 282 deletions
|
@ -15,6 +15,7 @@
|
|||
- (Bugfix) Unlock broken inspectors
|
||||
- (Debug) Allow to send package to stdout
|
||||
- (Improvement) ArangoDB image validation (=>3.10) for ARM64 architecture
|
||||
- (Improvement) Use inspector for ArangoMember
|
||||
|
||||
## [1.2.20](https://github.com/arangodb/kube-arangodb/tree/1.2.20) (2022-10-25)
|
||||
- (Feature) Add action progress
|
||||
|
|
|
@ -46,7 +46,6 @@ import (
|
|||
memberState "github.com/arangodb/kube-arangodb/pkg/deployment/member"
|
||||
"github.com/arangodb/kube-arangodb/pkg/deployment/patch"
|
||||
"github.com/arangodb/kube-arangodb/pkg/deployment/reconcile"
|
||||
"github.com/arangodb/kube-arangodb/pkg/deployment/reconciler"
|
||||
"github.com/arangodb/kube-arangodb/pkg/deployment/resilience"
|
||||
"github.com/arangodb/kube-arangodb/pkg/deployment/resources"
|
||||
"github.com/arangodb/kube-arangodb/pkg/deployment/resources/inspector"
|
||||
|
@ -59,7 +58,6 @@ import (
|
|||
"github.com/arangodb/kube-arangodb/pkg/util/errors"
|
||||
"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/kerrors"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/trigger"
|
||||
|
@ -139,14 +137,6 @@ type Deployment struct {
|
|||
metrics Metrics
|
||||
}
|
||||
|
||||
func (d *Deployment) WithArangoMember(cache inspectorInterface.Inspector, timeout time.Duration, name string) reconciler.ArangoMemberModContext {
|
||||
return reconciler.NewArangoMemberModContext(cache, timeout, name)
|
||||
}
|
||||
|
||||
func (d *Deployment) WithCurrentArangoMember(name string) reconciler.ArangoMemberModContext {
|
||||
return d.WithArangoMember(d.acs.CurrentClusterCache(), globals.GetGlobals().Timeouts().Kubernetes().Get(), name)
|
||||
}
|
||||
|
||||
func (d *Deployment) GetMembersState() memberState.StateInspector {
|
||||
return d.memberState
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ import (
|
|||
"github.com/arangodb/kube-arangodb/pkg/util"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/errors"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
|
||||
)
|
||||
|
||||
func runTestCases(t *testing.T, testCases ...testCaseStruct) {
|
||||
|
@ -149,9 +150,7 @@ func runTestCase(t *testing.T, testCase testCaseStruct) {
|
|||
},
|
||||
}
|
||||
|
||||
c := d.WithCurrentArangoMember(m.ArangoMemberName(d.GetName(), group))
|
||||
|
||||
if loopErr = c.Create(context.Background(), &member); loopErr != nil {
|
||||
if _, loopErr = d.acs.CurrentClusterCache().ArangoMemberModInterface().V1().Create(context.Background(), &member, meta.CreateOptions{}); loopErr != nil {
|
||||
break
|
||||
}
|
||||
|
||||
|
@ -188,16 +187,16 @@ func runTestCase(t *testing.T, testCase testCaseStruct) {
|
|||
member.Status.Template = podTemplate
|
||||
member.Spec.Template = podTemplate
|
||||
|
||||
if loopErr = c.Update(context.Background(), func(obj *api.ArangoMember) bool {
|
||||
obj.Spec.Template = podTemplate
|
||||
return true
|
||||
if loopErr = inspector.WithArangoMemberUpdate(context.Background(), d.acs.CurrentClusterCache(), member.GetName(), func(in *api.ArangoMember) (bool, error) {
|
||||
in.Spec.Template = podTemplate
|
||||
return true, nil
|
||||
}); loopErr != nil {
|
||||
break
|
||||
}
|
||||
|
||||
if loopErr = c.UpdateStatus(context.Background(), func(obj *api.ArangoMember, s *api.ArangoMemberStatus) bool {
|
||||
s.Template = podTemplate
|
||||
return true
|
||||
if loopErr = inspector.WithArangoMemberStatusUpdate(context.Background(), d.acs.CurrentClusterCache(), member.GetName(), func(in *api.ArangoMember) (bool, error) {
|
||||
in.Status.Template = podTemplate
|
||||
return true, nil
|
||||
}); loopErr != nil {
|
||||
break
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import (
|
|||
"github.com/arangodb/kube-arangodb/pkg/deployment/resources"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/errors"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
|
||||
)
|
||||
|
||||
// newArangoMemberUpdatePodSpecAction creates a new Action that implements the given
|
||||
|
@ -61,7 +62,11 @@ func (a *actionArangoMemberUpdatePodSpec) Start(ctx context.Context) (bool, erro
|
|||
return true, nil
|
||||
}
|
||||
|
||||
member, ok := a.actionCtx.ACS().CurrentClusterCache().ArangoMember().V1().GetSimple(m.ArangoMemberName(a.actionCtx.GetName(), a.action.Group))
|
||||
name := m.ArangoMemberName(a.actionCtx.GetName(), a.action.Group)
|
||||
|
||||
cache := a.actionCtx.ACS().CurrentClusterCache()
|
||||
|
||||
_, ok := cache.ArangoMember().V1().GetSimple(name)
|
||||
if !ok {
|
||||
err := errors.Newf("ArangoMember not found")
|
||||
a.log.Err(err).Error("ArangoMember not found")
|
||||
|
@ -118,26 +123,24 @@ func (a *actionArangoMemberUpdatePodSpec) Start(ctx context.Context) (bool, erro
|
|||
template.Endpoint = &q
|
||||
}
|
||||
|
||||
c := a.actionCtx.WithCurrentArangoMember(member.GetName())
|
||||
|
||||
if err := c.Update(ctx, func(member *api.ArangoMember) bool {
|
||||
if err := inspector.WithArangoMemberUpdate(ctx, cache, name, func(member *api.ArangoMember) (bool, error) {
|
||||
if !member.Spec.Template.Equals(template) {
|
||||
member.Spec.Template = template.DeepCopy()
|
||||
return true
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false
|
||||
return false, nil
|
||||
}); err != nil {
|
||||
a.log.Err(err).Error("Error while updating member")
|
||||
return false, err
|
||||
}
|
||||
|
||||
if err := c.UpdateStatus(ctx, func(member *api.ArangoMember, status *api.ArangoMemberStatus) bool {
|
||||
if (status.Template == nil || status.Template.PodSpec == nil) && (m.Pod == nil || m.Pod.SpecVersion == "" || m.Pod.SpecVersion == template.PodSpecChecksum) {
|
||||
status.Template = template.DeepCopy()
|
||||
if err := inspector.WithArangoMemberStatusUpdate(ctx, cache, name, func(member *api.ArangoMember) (bool, error) {
|
||||
if (member.Status.Template == nil || member.Status.Template.PodSpec == nil) && (m.Pod == nil || m.Pod.SpecVersion == "" || m.Pod.SpecVersion == template.PodSpecChecksum) {
|
||||
member.Status.Template = template.DeepCopy()
|
||||
}
|
||||
|
||||
return true
|
||||
return true, nil
|
||||
}); err != nil {
|
||||
a.log.Err(err).Error("Error while updating member status")
|
||||
return false, err
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/errors"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -60,7 +61,10 @@ func (a *actionArangoMemberUpdatePodStatus) Start(ctx context.Context) (bool, er
|
|||
return true, nil
|
||||
}
|
||||
|
||||
member, ok := a.actionCtx.ACS().CurrentClusterCache().ArangoMember().V1().GetSimple(m.ArangoMemberName(a.actionCtx.GetName(), a.action.Group))
|
||||
name := m.ArangoMemberName(a.actionCtx.GetName(), a.action.Group)
|
||||
cache := a.actionCtx.ACS().CurrentClusterCache()
|
||||
|
||||
member, ok := cache.ArangoMember().V1().GetSimple(name)
|
||||
if !ok {
|
||||
err := errors.Newf("ArangoMember not found")
|
||||
a.log.Err(err).Error("ArangoMember not found")
|
||||
|
@ -79,12 +83,12 @@ func (a *actionArangoMemberUpdatePodStatus) Start(ctx context.Context) (bool, er
|
|||
}
|
||||
|
||||
if member.Status.Template == nil || !member.Status.Template.Equals(member.Spec.Template) {
|
||||
if err := a.actionCtx.WithCurrentArangoMember(member.GetName()).UpdateStatus(ctx, func(obj *api.ArangoMember, status *api.ArangoMemberStatus) bool {
|
||||
if status.Template == nil || !status.Template.Equals(member.Spec.Template) {
|
||||
status.Template = member.Spec.Template.DeepCopy()
|
||||
return true
|
||||
if err := inspector.WithArangoMemberStatusUpdate(ctx, cache, name, func(in *api.ArangoMember) (bool, error) {
|
||||
if in.Status.Template == nil || !in.Status.Template.Equals(member.Spec.Template) {
|
||||
in.Status.Template = member.Spec.Template.DeepCopy()
|
||||
return true, nil
|
||||
}
|
||||
return false
|
||||
return false, nil
|
||||
}); err != nil {
|
||||
a.log.Err(err).Error("Error while updating member")
|
||||
return false, err
|
||||
|
|
|
@ -46,7 +46,6 @@ import (
|
|||
type ActionContext interface {
|
||||
reconciler.DeploymentStatusUpdate
|
||||
reconciler.DeploymentAgencyMaintenance
|
||||
reconciler.ArangoMemberContext
|
||||
reconciler.DeploymentPodRenderer
|
||||
reconciler.ArangoAgencyGet
|
||||
reconciler.DeploymentInfoGetter
|
||||
|
@ -220,14 +219,6 @@ func (ac *actionContext) Add(key api.PlanLocalKey, value string, override bool)
|
|||
return ac.locals.Add(key, value, override)
|
||||
}
|
||||
|
||||
func (ac *actionContext) WithArangoMember(cache inspectorInterface.Inspector, timeout time.Duration, name string) reconciler.ArangoMemberModContext {
|
||||
return ac.context.WithArangoMember(cache, timeout, name)
|
||||
}
|
||||
|
||||
func (ac *actionContext) WithCurrentArangoMember(name string) reconciler.ArangoMemberModContext {
|
||||
return ac.context.WithCurrentArangoMember(name)
|
||||
}
|
||||
|
||||
func (ac *actionContext) GetMembersState() member.StateInspector {
|
||||
return ac.context.GetMembersState()
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import (
|
|||
"github.com/arangodb/kube-arangodb/pkg/deployment/rotation"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/globals"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/definitions"
|
||||
)
|
||||
|
||||
|
@ -64,7 +65,7 @@ func (a actionRuntimeContainerArgsLogLevelUpdate) Post(ctx context.Context) erro
|
|||
}
|
||||
|
||||
memberName := m.ArangoMemberName(a.actionCtx.GetName(), a.action.Group)
|
||||
member, ok := cache.ArangoMember().V1().GetSimple(memberName)
|
||||
_, ok = cache.ArangoMember().V1().GetSimple(memberName)
|
||||
if !ok {
|
||||
return errors.Errorf("ArangoMember %s not found", memberName)
|
||||
}
|
||||
|
@ -76,37 +77,37 @@ func (a actionRuntimeContainerArgsLogLevelUpdate) Post(ctx context.Context) erro
|
|||
}
|
||||
|
||||
log := a.log.Str("containerName", containerName)
|
||||
updateMemberStatusArgs := func(obj *api.ArangoMember, s *api.ArangoMemberStatus) bool {
|
||||
if obj.Spec.Template == nil || s.Template == nil ||
|
||||
obj.Spec.Template.PodSpec == nil || s.Template.PodSpec == nil {
|
||||
updateMemberStatusArgs := func(in *api.ArangoMember) (bool, error) {
|
||||
if in.Spec.Template == nil || in.Status.Template == nil ||
|
||||
in.Spec.Template.PodSpec == nil || in.Status.Template.PodSpec == nil {
|
||||
log.Info("Nil Member definition")
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if len(obj.Spec.Template.PodSpec.Spec.Containers) != len(s.Template.PodSpec.Spec.Containers) {
|
||||
if len(in.Spec.Template.PodSpec.Spec.Containers) != len(in.Status.Template.PodSpec.Spec.Containers) {
|
||||
log.Info("Invalid size of containers")
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
|
||||
for id := range obj.Spec.Template.PodSpec.Spec.Containers {
|
||||
if obj.Spec.Template.PodSpec.Spec.Containers[id].Name == containerName {
|
||||
if s.Template.PodSpec.Spec.Containers[id].Name != containerName {
|
||||
for id := range in.Spec.Template.PodSpec.Spec.Containers {
|
||||
if in.Spec.Template.PodSpec.Spec.Containers[id].Name == containerName {
|
||||
if in.Status.Template.PodSpec.Spec.Containers[id].Name != containerName {
|
||||
log.Info("Invalid order of containers")
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
|
||||
s.Template.PodSpec.Spec.Containers[id].Command = obj.Spec.Template.PodSpec.Spec.Containers[id].Command
|
||||
in.Status.Template.PodSpec.Spec.Containers[id].Command = in.Spec.Template.PodSpec.Spec.Containers[id].Command
|
||||
log.Info("Updating container args")
|
||||
return true
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
log.Info("can not find the container")
|
||||
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
|
||||
err := a.actionCtx.WithCurrentArangoMember(member.GetName()).UpdateStatus(ctx, updateMemberStatusArgs)
|
||||
err := inspector.WithArangoMemberStatusUpdate(ctx, cache, memberName, updateMemberStatusArgs)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "Error while updating member status")
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import (
|
|||
"github.com/arangodb/kube-arangodb/pkg/deployment/rotation"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/errors"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
|
||||
)
|
||||
|
||||
func newRuntimeContainerImageUpdateAction(action api.Action, actionCtx ActionContext) Action {
|
||||
|
@ -56,51 +57,54 @@ func (a actionRuntimeContainerImageUpdate) Post(ctx context.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
name, image, ok := a.getContainerDetails()
|
||||
cname, image, ok := a.getContainerDetails()
|
||||
if !ok {
|
||||
a.log.Info("Unable to find container details")
|
||||
return nil
|
||||
}
|
||||
|
||||
member, ok := a.actionCtx.ACS().CurrentClusterCache().ArangoMember().V1().GetSimple(m.ArangoMemberName(a.actionCtx.GetName(), a.action.Group))
|
||||
cache := a.actionCtx.ACS().CurrentClusterCache()
|
||||
name := m.ArangoMemberName(a.actionCtx.GetName(), a.action.Group)
|
||||
|
||||
_, ok = cache.ArangoMember().V1().GetSimple(name)
|
||||
if !ok {
|
||||
err := errors.Newf("ArangoMember not found")
|
||||
a.log.Err(err).Error("ArangoMember not found")
|
||||
return err
|
||||
}
|
||||
|
||||
return a.actionCtx.WithCurrentArangoMember(member.GetName()).UpdateStatus(ctx, func(obj *api.ArangoMember, s *api.ArangoMemberStatus) bool {
|
||||
if obj.Spec.Template == nil || s.Template == nil ||
|
||||
obj.Spec.Template.PodSpec == nil || s.Template.PodSpec == nil {
|
||||
return inspector.WithArangoMemberUpdate(ctx, cache, name, func(in *api.ArangoMember) (bool, error) {
|
||||
if in.Spec.Template == nil || in.Status.Template == nil ||
|
||||
in.Spec.Template.PodSpec == nil || in.Status.Template.PodSpec == nil {
|
||||
a.log.Info("Nil Member definition")
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if len(obj.Spec.Template.PodSpec.Spec.Containers) != len(s.Template.PodSpec.Spec.Containers) {
|
||||
if len(in.Spec.Template.PodSpec.Spec.Containers) != len(in.Status.Template.PodSpec.Spec.Containers) {
|
||||
a.log.Info("Invalid size of containers")
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
|
||||
for id := range obj.Spec.Template.PodSpec.Spec.Containers {
|
||||
if obj.Spec.Template.PodSpec.Spec.Containers[id].Name == name {
|
||||
if s.Template.PodSpec.Spec.Containers[id].Name != name {
|
||||
for id := range in.Spec.Template.PodSpec.Spec.Containers {
|
||||
if in.Spec.Template.PodSpec.Spec.Containers[id].Name == cname {
|
||||
if in.Status.Template.PodSpec.Spec.Containers[id].Name != cname {
|
||||
a.log.Info("Invalid order of containers")
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if obj.Spec.Template.PodSpec.Spec.Containers[id].Image != image {
|
||||
a.log.Str("got", obj.Spec.Template.PodSpec.Spec.Containers[id].Image).Str("expected", image).Info("Invalid spec image of container")
|
||||
return false
|
||||
if in.Spec.Template.PodSpec.Spec.Containers[id].Image != image {
|
||||
a.log.Str("got", in.Spec.Template.PodSpec.Spec.Containers[id].Image).Str("expected", image).Info("Invalid spec image of container")
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if s.Template.PodSpec.Spec.Containers[id].Image != image {
|
||||
s.Template.PodSpec.Spec.Containers[id].Image = image
|
||||
return true
|
||||
if in.Status.Template.PodSpec.Spec.Containers[id].Image != image {
|
||||
in.Status.Template.PodSpec.Spec.Containers[id].Image = image
|
||||
return true, nil
|
||||
}
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return false
|
||||
return false, nil
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ type CreateMemberMod func(s *api.DeploymentStatus, g api.ServerGroup, m *api.Mem
|
|||
type Context interface {
|
||||
reconciler.DeploymentStatusUpdate
|
||||
reconciler.DeploymentAgencyMaintenance
|
||||
reconciler.ArangoMemberContext
|
||||
reconciler.DeploymentPodRenderer
|
||||
reconciler.DeploymentImageManager
|
||||
reconciler.ArangoAgencyGet
|
||||
|
|
|
@ -36,7 +36,6 @@ type PlanBuilderContext interface {
|
|||
|
||||
reconciler.DeploymentInfoGetter
|
||||
reconciler.DeploymentAgencyMaintenance
|
||||
reconciler.ArangoMemberContext
|
||||
reconciler.DeploymentPodRenderer
|
||||
reconciler.DeploymentImageManager
|
||||
reconciler.ArangoAgencyGet
|
||||
|
|
|
@ -25,7 +25,6 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
monitoringClient "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/typed/monitoring/v1"
|
||||
"github.com/rs/zerolog"
|
||||
|
@ -124,14 +123,6 @@ func (c *testContext) GetDatabaseAsyncClient(ctx context.Context) (driver.Client
|
|||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *testContext) WithArangoMember(cache inspectorInterface.Inspector, timeout time.Duration, name string) reconciler.ArangoMemberModContext {
|
||||
return reconciler.NewArangoMemberModContext(cache, timeout, name)
|
||||
}
|
||||
|
||||
func (c *testContext) WithCurrentArangoMember(name string) reconciler.ArangoMemberModContext {
|
||||
return c.WithArangoMember(c.Inspector, 0, name)
|
||||
}
|
||||
|
||||
func (c *testContext) GetMembersState() member.StateInspector {
|
||||
return c.state
|
||||
}
|
||||
|
@ -220,14 +211,6 @@ func (c *testContext) SelectImageForMember(spec api.DeploymentSpec, status api.D
|
|||
return c.SelectImage(spec, status)
|
||||
}
|
||||
|
||||
func (c *testContext) WithArangoMemberUpdate(ctx context.Context, namespace, name string, action reconciler.ArangoMemberUpdateFunc) error {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *testContext) WithArangoMemberStatusUpdate(ctx context.Context, namespace, name string, action reconciler.ArangoMemberStatusUpdateFunc) error {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (c *testContext) GetAgencyMaintenanceMode(ctx context.Context) (bool, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
|
|
@ -1,173 +0,0 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package reconciler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
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/errors"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
|
||||
)
|
||||
|
||||
type ArangoMemberCreateFunc func(obj *api.ArangoMember)
|
||||
type ArangoMemberUpdateFunc func(obj *api.ArangoMember) bool
|
||||
type ArangoMemberStatusUpdateFunc func(obj *api.ArangoMember, s *api.ArangoMemberStatus) bool
|
||||
|
||||
type ArangoMemberContext interface {
|
||||
// WithArangoMember start ArangoMember scope. Used in ACS
|
||||
WithArangoMember(cache inspector.Inspector, timeout time.Duration, name string) ArangoMemberModContext
|
||||
|
||||
// WithCurrentArangoMember start ArangoMember scope within current deployment scope
|
||||
WithCurrentArangoMember(name string) ArangoMemberModContext
|
||||
}
|
||||
|
||||
func NewArangoMemberModContext(cache inspector.Inspector, timeout time.Duration, name string) ArangoMemberModContext {
|
||||
return arangoMemberModContext{
|
||||
cache: cache,
|
||||
name: name,
|
||||
timeout: timeout,
|
||||
}
|
||||
}
|
||||
|
||||
type ArangoMemberModContext interface {
|
||||
// Exists returns true if object exists
|
||||
Exists(ctx context.Context) bool
|
||||
// Create creates ArangoMember
|
||||
Create(ctx context.Context, obj *api.ArangoMember) error
|
||||
// Update run action with update of ArangoMember
|
||||
Update(ctx context.Context, action ArangoMemberUpdateFunc) error
|
||||
// UpdateStatus run action with update of ArangoMember Status
|
||||
UpdateStatus(ctx context.Context, action ArangoMemberStatusUpdateFunc) error
|
||||
// Delete deletes object
|
||||
Delete(ctx context.Context) error
|
||||
}
|
||||
|
||||
type arangoMemberModContext struct {
|
||||
cache inspector.Inspector
|
||||
name string
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
func (a arangoMemberModContext) withTimeout(ctx context.Context) (context.Context, func()) {
|
||||
if a.timeout != 0 {
|
||||
return context.WithTimeout(ctx, a.timeout)
|
||||
}
|
||||
|
||||
return ctx, func() {}
|
||||
}
|
||||
|
||||
func (a arangoMemberModContext) Delete(ctx context.Context) error {
|
||||
ctx, c := a.withTimeout(ctx)
|
||||
defer c()
|
||||
|
||||
if err := a.cache.Client().Arango().DatabaseV1().ArangoMembers(a.cache.Namespace()).Delete(ctx, a.name, meta.DeleteOptions{}); err != nil {
|
||||
if api.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a arangoMemberModContext) Exists(ctx context.Context) bool {
|
||||
_, ok := a.cache.ArangoMember().V1().GetSimple(a.name)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (a arangoMemberModContext) Create(ctx context.Context, obj *api.ArangoMember) error {
|
||||
ctx, c := a.withTimeout(ctx)
|
||||
defer c()
|
||||
|
||||
if obj.GetName() == "" {
|
||||
obj.Name = a.name
|
||||
} else if obj.GetName() != a.name {
|
||||
return errors.Newf("Name is invalid")
|
||||
}
|
||||
|
||||
if obj.GetNamespace() == "" {
|
||||
obj.Namespace = a.cache.Namespace()
|
||||
} else if obj.GetNamespace() != a.cache.Namespace() {
|
||||
return errors.Newf("Namespace is invalid")
|
||||
}
|
||||
|
||||
if _, err := a.cache.Client().Arango().DatabaseV1().ArangoMembers(obj.GetNamespace()).Create(ctx, obj, meta.CreateOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := a.cache.ArangoMember().Refresh(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a arangoMemberModContext) Update(ctx context.Context, action ArangoMemberUpdateFunc) error {
|
||||
ctx, c := a.withTimeout(ctx)
|
||||
defer c()
|
||||
|
||||
o, err := a.cache.ArangoMember().V1().Read().Get(ctx, a.name, meta.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if action(o) {
|
||||
if _, err := a.cache.Client().Arango().DatabaseV1().ArangoMembers(a.cache.Namespace()).Update(ctx, o, meta.UpdateOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := a.cache.ArangoMember().Refresh(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a arangoMemberModContext) UpdateStatus(ctx context.Context, action ArangoMemberStatusUpdateFunc) error {
|
||||
ctx, c := a.withTimeout(ctx)
|
||||
defer c()
|
||||
|
||||
o, err := a.cache.ArangoMember().V1().Read().Get(ctx, a.name, meta.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
status := o.Status.DeepCopy()
|
||||
|
||||
if action(o, status) {
|
||||
o.Status = *status
|
||||
if _, err := a.cache.Client().Arango().DatabaseV1().ArangoMembers(a.cache.Namespace()).UpdateStatus(ctx, o, meta.UpdateOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := a.cache.ArangoMember().Refresh(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -38,7 +38,6 @@ import (
|
|||
type Context interface {
|
||||
reconciler.DeploymentStatusUpdate
|
||||
reconciler.DeploymentAgencyMaintenance
|
||||
reconciler.ArangoMemberContext
|
||||
reconciler.DeploymentImageManager
|
||||
reconciler.ArangoAgency
|
||||
reconciler.ArangoApplier
|
||||
|
|
|
@ -32,6 +32,7 @@ import (
|
|||
memberState "github.com/arangodb/kube-arangodb/pkg/deployment/member"
|
||||
"github.com/arangodb/kube-arangodb/pkg/metrics"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/errors"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/globals"
|
||||
inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
|
||||
arangomemberv1 "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/arangomember/v1"
|
||||
)
|
||||
|
@ -127,9 +128,9 @@ func (r *Resources) EnsureArangoMembers(ctx context.Context, cachedStatus inspec
|
|||
for _, e := range s.Members.AsList() {
|
||||
name := e.Member.ArangoMemberName(r.context.GetAPIObject().GetName(), e.Group)
|
||||
|
||||
c := r.context.WithCurrentArangoMember(name)
|
||||
_, ok := cachedStatus.ArangoMember().V1().GetSimple(name)
|
||||
|
||||
if !c.Exists(ctx) {
|
||||
if !ok {
|
||||
// Create ArangoMember
|
||||
obj := &api.ArangoMember{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
|
@ -145,27 +146,30 @@ func (r *Resources) EnsureArangoMembers(ctx context.Context, cachedStatus inspec
|
|||
},
|
||||
}
|
||||
|
||||
if err := r.context.WithCurrentArangoMember(name).Create(ctx, obj); err != nil {
|
||||
nctx, c := globals.GetGlobals().Timeouts().Kubernetes().WithTimeout(ctx)
|
||||
defer c()
|
||||
|
||||
if _, err := cachedStatus.ArangoMemberModInterface().V1().Create(nctx, obj, meta.CreateOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
continue
|
||||
} else {
|
||||
if err := c.Update(ctx, func(m *api.ArangoMember) bool {
|
||||
if err := inspectorInterface.WithArangoMemberUpdate(ctx, cachedStatus, name, func(in *api.ArangoMember) (bool, error) {
|
||||
changed := false
|
||||
if len(m.OwnerReferences) == 0 {
|
||||
m.OwnerReferences = []meta.OwnerReference{
|
||||
if len(in.OwnerReferences) == 0 {
|
||||
in.OwnerReferences = []meta.OwnerReference{
|
||||
obj.AsOwner(),
|
||||
}
|
||||
changed = true
|
||||
}
|
||||
|
||||
if m.Spec.DeploymentUID == "" {
|
||||
m.Spec.DeploymentUID = obj.GetUID()
|
||||
if in.Spec.DeploymentUID == "" {
|
||||
in.Spec.DeploymentUID = obj.GetUID()
|
||||
changed = true
|
||||
}
|
||||
|
||||
return changed
|
||||
return changed, nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -177,7 +181,10 @@ func (r *Resources) EnsureArangoMembers(ctx context.Context, cachedStatus inspec
|
|||
|
||||
if !ok || g != member.Spec.Group {
|
||||
// Remove member
|
||||
if err := r.context.WithCurrentArangoMember(member.GetName()).Delete(ctx); err != nil {
|
||||
nctx, c := globals.GetGlobals().Timeouts().Kubernetes().WithTimeout(ctx)
|
||||
defer c()
|
||||
|
||||
if err := cachedStatus.ArangoMemberModInterface().V1().Delete(nctx, member.Name, meta.DeleteOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
96
pkg/util/k8sutil/inspector/helpers.go
Normal file
96
pkg/util/k8sutil/inspector/helpers.go
Normal file
|
@ -0,0 +1,96 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package inspector
|
||||
|
||||
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/globals"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/arangomember"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/mods"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/refresh"
|
||||
)
|
||||
|
||||
type ArangoMemberUpdateInterface interface {
|
||||
refresh.Inspector
|
||||
|
||||
arangomember.Inspector
|
||||
ArangoMemberModInterface() mods.ArangoMemberMods
|
||||
}
|
||||
|
||||
type ArangoMemberUpdateFunc func(in *api.ArangoMember) (bool, error)
|
||||
|
||||
func WithArangoMemberUpdate(ctx context.Context, client ArangoMemberUpdateInterface, name string, f ArangoMemberUpdateFunc) error {
|
||||
nctx, c := globals.GetGlobals().Timeouts().Kubernetes().WithTimeout(ctx)
|
||||
defer c()
|
||||
|
||||
obj, err := client.ArangoMember().V1().Read().Get(nctx, name, meta.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nobj := obj.DeepCopy()
|
||||
|
||||
if changed, err := f(nobj); err != nil {
|
||||
return err
|
||||
} else if changed {
|
||||
nctx, c := globals.GetGlobals().Timeouts().Kubernetes().WithTimeout(ctx)
|
||||
defer c()
|
||||
|
||||
if _, err := client.ArangoMemberModInterface().V1().Update(nctx, nobj, meta.UpdateOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return client.Refresh(ctx)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func WithArangoMemberStatusUpdate(ctx context.Context, client ArangoMemberUpdateInterface, name string, f ArangoMemberUpdateFunc) error {
|
||||
nctx, c := globals.GetGlobals().Timeouts().Kubernetes().WithTimeout(ctx)
|
||||
defer c()
|
||||
|
||||
obj, err := client.ArangoMember().V1().Read().Get(nctx, name, meta.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nobj := obj.DeepCopy()
|
||||
|
||||
if changed, err := f(nobj); err != nil {
|
||||
return err
|
||||
} else if changed {
|
||||
nctx, c := globals.GetGlobals().Timeouts().Kubernetes().WithTimeout(ctx)
|
||||
defer c()
|
||||
|
||||
if _, err := client.ArangoMemberModInterface().V1().UpdateStatus(nctx, nobj, meta.UpdateOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return client.Refresh(ctx)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Reference in a new issue