1
0
Fork 0
mirror of https://github.com/arangodb/kube-arangodb.git synced 2024-12-14 11:57:37 +00:00

[Cleanup] Reorganize main reconciliation context (#901)

This commit is contained in:
Adam Janikowski 2022-02-03 11:05:40 +01:00 committed by GitHub
parent 0350466568
commit 58b2ff94c4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 329 additions and 279 deletions

View file

@ -6,6 +6,7 @@
- Define MemberReplacementRequired condition
- Remove pod immediately when annotation is turned on
- (ARM64) Add support for ARM64 enablement
- (Cleanup) Reorganize main reconciliation context
## [1.2.7](https://github.com/arangodb/kube-arangodb/tree/1.2.7) (2022-01-17)
- Add Plan BackOff functionality

View file

@ -26,8 +26,6 @@ import (
"strconv"
"sync"
"github.com/arangodb/kube-arangodb/pkg/deployment/resources"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
"github.com/arangodb/go-driver/agency"
@ -36,6 +34,7 @@ import (
driver "github.com/arangodb/go-driver"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/deployment/reconciler"
)
type Cache interface {
@ -49,8 +48,8 @@ type Cache interface {
}
type CacheGen interface {
resources.DeploymentEndpoints
resources.DeploymentInfoGetter
reconciler.DeploymentEndpoints
reconciler.DeploymentInfoGetter
}
func NewClientCache(in CacheGen, factory conn.Factory) Cache {

View file

@ -76,6 +76,7 @@ import (
backupApi "github.com/arangodb/kube-arangodb/pkg/apis/backup/v1"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/deployment/reconciler"
"github.com/arangodb/kube-arangodb/pkg/deployment/resources"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
core "k8s.io/api/core/v1"
@ -97,7 +98,7 @@ func (d *Deployment) GetAPIObject() k8sutil.APIObject {
}
// GetServerGroupIterator returns the deployment as ServerGroupIterator.
func (d *Deployment) GetServerGroupIterator() resources.ServerGroupIterator {
func (d *Deployment) GetServerGroupIterator() reconciler.ServerGroupIterator {
return d.apiObject
}
@ -226,8 +227,13 @@ func (d *Deployment) GetAuthentication() conn.Auth {
}
// GetAgencyClients returns a client connection for every agency member.
func (d *Deployment) GetAgencyClients(ctx context.Context) ([]driver.Connection, error) {
return d.GetAgencyClientsWithPredicate(ctx, nil)
}
// GetAgencyClientsWithPredicate returns a client connection for every agency member.
// If the given predicate is not nil, only agents are included where the given predicate returns true.
func (d *Deployment) GetAgencyClients(ctx context.Context, predicate func(id string) bool) ([]driver.Connection, error) {
func (d *Deployment) GetAgencyClientsWithPredicate(ctx context.Context, predicate func(id string) bool) ([]driver.Connection, error) {
agencyMembers := d.status.last.Members.Agents
result := make([]driver.Connection, 0, len(agencyMembers))
for _, m := range agencyMembers {
@ -591,7 +597,7 @@ func (d *Deployment) GetArangoImage() string {
return d.config.ArangoImage
}
func (d *Deployment) WithStatusUpdateErr(ctx context.Context, action resources.DeploymentStatusUpdateErrFunc, force ...bool) error {
func (d *Deployment) WithStatusUpdateErr(ctx context.Context, action reconciler.DeploymentStatusUpdateErrFunc, force ...bool) error {
d.status.mutex.Lock()
defer d.status.mutex.Unlock()
@ -610,7 +616,7 @@ func (d *Deployment) WithStatusUpdateErr(ctx context.Context, action resources.D
return d.updateStatus(ctx, status, version, force...)
}
func (d *Deployment) WithStatusUpdate(ctx context.Context, action resources.DeploymentStatusUpdateFunc, force ...bool) error {
func (d *Deployment) WithStatusUpdate(ctx context.Context, action reconciler.DeploymentStatusUpdateFunc, force ...bool) error {
return d.WithStatusUpdateErr(ctx, func(s *api.DeploymentStatus) (bool, error) {
return action(s), nil
}, force...)
@ -680,7 +686,7 @@ func (d *Deployment) SetCachedStatus(i inspectorInterface.Inspector) {
d.currentState = i
}
func (d *Deployment) WithArangoMemberUpdate(ctx context.Context, namespace, name string, action resources.ArangoMemberUpdateFunc) error {
func (d *Deployment) WithArangoMemberUpdate(ctx context.Context, namespace, name string, action reconciler.ArangoMemberUpdateFunc) error {
o, err := d.deps.DatabaseCRCli.DatabaseV1().ArangoMembers(namespace).Get(ctx, name, meta.GetOptions{})
if err != nil {
return err
@ -695,7 +701,7 @@ func (d *Deployment) WithArangoMemberUpdate(ctx context.Context, namespace, name
return nil
}
func (d *Deployment) WithArangoMemberStatusUpdate(ctx context.Context, namespace, name string, action resources.ArangoMemberStatusUpdateFunc) error {
func (d *Deployment) WithArangoMemberStatusUpdate(ctx context.Context, namespace, name string, action reconciler.ArangoMemberStatusUpdateFunc) error {
o, err := d.deps.DatabaseCRCli.DatabaseV1().ArangoMembers(namespace).Get(ctx, name, meta.GetOptions{})
if err != nil {
return err

View file

@ -164,7 +164,7 @@ func (d *Deployment) RefreshAgencyCache(ctx context.Context) (uint64, error) {
}
func (d *Deployment) SetAgencyMaintenanceMode(ctx context.Context, enabled bool) error {
if !d.Mode().HasAgents() {
if !d.GetMode().HasAgents() {
return nil
}

View file

@ -29,13 +29,13 @@ import (
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/arangodb/arangosync-client/client"
"github.com/arangodb/go-driver"
"github.com/arangodb/go-driver/agency"
"github.com/arangodb/go-driver"
backupApi "github.com/arangodb/kube-arangodb/pkg/apis/backup/v1"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
agencyCache "github.com/arangodb/kube-arangodb/pkg/deployment/agency"
"github.com/arangodb/kube-arangodb/pkg/deployment/resources"
"github.com/arangodb/kube-arangodb/pkg/deployment/reconciler"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
@ -52,31 +52,17 @@ import (
// ActionContext provides methods to the Action implementations
// to control their context.
type ActionContext interface {
resources.DeploymentStatusUpdate
resources.DeploymentAgencyMaintenance
resources.ArangoMemberContext
resources.DeploymentPodRenderer
resources.DeploymentModInterfaces
resources.DeploymentCachedStatus
resources.ArangoAgencyGet
resources.DeploymentInfoGetter
reconciler.DeploymentStatusUpdate
reconciler.DeploymentAgencyMaintenance
reconciler.ArangoMemberContext
reconciler.DeploymentPodRenderer
reconciler.DeploymentModInterfaces
reconciler.DeploymentCachedStatus
reconciler.ArangoAgencyGet
reconciler.DeploymentInfoGetter
reconciler.DeploymentClient
reconciler.DeploymentSyncClient
// Gets the specified mode of deployment
GetMode() api.DeploymentMode
// GetDatabaseClient returns a cached client for the entire database (cluster coordinators or single server),
// creating one if needed.
GetDatabaseClient(ctx context.Context) (driver.Client, error)
// GetServerClient returns a cached client for a specific server.
GetServerClient(ctx context.Context, group api.ServerGroup, id string) (driver.Client, error)
// GetAgencyClients returns a client connection for every agency member.
GetAgencyClients(ctx context.Context) ([]driver.Connection, error)
// GetAgency returns a connection to the entire agency.
GetAgency(ctx context.Context) (agency.Agency, error)
// GetSyncServerClient returns a cached client for a specific arangosync server.
GetSyncServerClient(ctx context.Context, group api.ServerGroup, id string) (client.API, error)
// CreateEvent creates a given event.
// On error, the error is logged.
CreateEvent(evt *k8sutil.Event)
// GetMemberStatusByID returns the current member status
// for the member with given id.
// Returns member status, true when found, or false
@ -119,7 +105,7 @@ type ActionContext interface {
// GetImageInfo returns the image info for an image with given name.
// Returns: (info, infoFound)
GetImageInfo(imageName string) (api.ImageInfo, bool)
// GetImageInfo returns the image info for an current image.
// GetCurrentImageInfo returns the image info for an current image.
// Returns: (info, infoFound)
GetCurrentImageInfo() (api.ImageInfo, bool)
// SetCurrentImage changes the CurrentImage field in the deployment
@ -135,7 +121,7 @@ type ActionContext interface {
DisableScalingCluster(ctx context.Context) error
// EnableScalingCluster enables scaling DBservers and coordinators
EnableScalingCluster(ctx context.Context) error
// WithStatusUpdate update status of ArangoDeployment with defined modifier. If action returns True action is taken
// UpdateClusterCondition update status of ArangoDeployment with defined modifier. If action returns True action is taken
UpdateClusterCondition(ctx context.Context, conditionType api.ConditionType, status bool, reason, message string) error
// GetBackup receives information about a backup resource
GetBackup(ctx context.Context, backup string) (*backupApi.ArangoBackup, error)
@ -161,6 +147,18 @@ type actionContext struct {
cachedStatus inspectorInterface.Inspector
}
func (ac *actionContext) UpdateStatus(ctx context.Context, status api.DeploymentStatus, lastVersion int32, force ...bool) error {
return ac.context.UpdateStatus(ctx, status, lastVersion, force...)
}
func (ac *actionContext) GetNamespace() string {
return ac.context.GetNamespace()
}
func (ac *actionContext) GetAgencyClientsWithPredicate(ctx context.Context, predicate func(id string) bool) ([]driver.Connection, error) {
return ac.context.GetAgencyClientsWithPredicate(ctx, predicate)
}
func (ac *actionContext) GetStatus() (api.DeploymentStatus, int32) {
return ac.context.GetStatus()
}
@ -189,11 +187,11 @@ func (ac *actionContext) SetAgencyMaintenanceMode(ctx context.Context, enabled b
return ac.context.SetAgencyMaintenanceMode(ctx, enabled)
}
func (ac *actionContext) WithArangoMemberUpdate(ctx context.Context, namespace, name string, action resources.ArangoMemberUpdateFunc) error {
func (ac *actionContext) WithArangoMemberUpdate(ctx context.Context, namespace, name string, action reconciler.ArangoMemberUpdateFunc) error {
return ac.context.WithArangoMemberUpdate(ctx, namespace, name, action)
}
func (ac *actionContext) WithArangoMemberStatusUpdate(ctx context.Context, namespace, name string, action resources.ArangoMemberStatusUpdateFunc) error {
func (ac *actionContext) WithArangoMemberStatusUpdate(ctx context.Context, namespace, name string, action reconciler.ArangoMemberStatusUpdateFunc) error {
return ac.context.WithArangoMemberStatusUpdate(ctx, namespace, name, action)
}
@ -221,11 +219,11 @@ func (ac *actionContext) GetBackup(ctx context.Context, backup string) (*backupA
return ac.context.GetBackup(ctx, backup)
}
func (ac *actionContext) WithStatusUpdateErr(ctx context.Context, action resources.DeploymentStatusUpdateErrFunc, force ...bool) error {
func (ac *actionContext) WithStatusUpdateErr(ctx context.Context, action reconciler.DeploymentStatusUpdateErrFunc, force ...bool) error {
return ac.context.WithStatusUpdateErr(ctx, action, force...)
}
func (ac *actionContext) WithStatusUpdate(ctx context.Context, action resources.DeploymentStatusUpdateFunc, force ...bool) error {
func (ac *actionContext) WithStatusUpdate(ctx context.Context, action reconciler.DeploymentStatusUpdateFunc, force ...bool) error {
return ac.context.WithStatusUpdate(ctx, action, force...)
}
@ -322,7 +320,7 @@ func (ac *actionContext) GetServerClient(ctx context.Context, group api.ServerGr
// GetAgencyClients returns a client connection for every agency member.
func (ac *actionContext) GetAgencyClients(ctx context.Context) ([]driver.Connection, error) {
c, err := ac.context.GetAgencyClients(ctx, nil)
c, err := ac.context.GetAgencyClients(ctx)
if err != nil {
return nil, errors.WithStack(err)
}

View file

@ -23,54 +23,34 @@ package reconcile
import (
"context"
"github.com/arangodb/arangosync-client/client"
"github.com/arangodb/go-driver"
"github.com/arangodb/go-driver/agency"
v1 "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/arangodb/go-driver"
backupApi "github.com/arangodb/kube-arangodb/pkg/apis/backup/v1"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/deployment/resources"
"github.com/arangodb/kube-arangodb/pkg/deployment/reconciler"
"github.com/arangodb/kube-arangodb/pkg/util/arangod/conn"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
)
type CreateMemberMod func(s *api.DeploymentStatus, g api.ServerGroup, m *api.MemberStatus) error
// Context provides methods to the reconcile package.
type Context interface {
resources.DeploymentStatusUpdate
resources.DeploymentAgencyMaintenance
resources.ArangoMemberContext
resources.DeploymentPodRenderer
resources.DeploymentImageManager
resources.DeploymentModInterfaces
resources.DeploymentCachedStatus
resources.ArangoAgencyGet
resources.ArangoApplier
resources.DeploymentInfoGetter
reconciler.DeploymentStatusUpdate
reconciler.DeploymentAgencyMaintenance
reconciler.ArangoMemberContext
reconciler.DeploymentPodRenderer
reconciler.DeploymentImageManager
reconciler.DeploymentModInterfaces
reconciler.DeploymentCachedStatus
reconciler.ArangoAgencyGet
reconciler.ArangoApplier
reconciler.DeploymentInfoGetter
reconciler.DeploymentClient
reconciler.KubernetesEventGenerator
reconciler.DeploymentSyncClient
// UpdateStatus replaces the status of the deployment with the given status and
// updates the resources in k8s.
UpdateStatus(ctx context.Context, status api.DeploymentStatus, lastVersion int32, force ...bool) error
// UpdateMember updates the deployment status wrt the given member.
UpdateMember(ctx context.Context, member api.MemberStatus) error
// GetDatabaseClient returns a cached client for the entire database (cluster coordinators or single server),
// creating one if needed.
GetDatabaseClient(ctx context.Context) (driver.Client, error)
// GetServerClient returns a cached client for a specific server.
GetServerClient(ctx context.Context, group api.ServerGroup, id string) (driver.Client, error)
// GetAgencyClients returns a client connection for every agency member.
// If the given predicate is not nil, only agents are included where the given predicate returns true.
GetAgencyClients(ctx context.Context, predicate func(id string) bool) ([]driver.Connection, error)
// GetAgency returns a connection to the entire agency.
GetAgency(ctx context.Context) (agency.Agency, error)
// GetSyncServerClient returns a cached client for a specific arangosync server.
GetSyncServerClient(ctx context.Context, group api.ServerGroup, id string) (client.API, error)
// CreateEvent creates a given event.
// On error, the error is logged.
CreateEvent(evt *k8sutil.Event)
// CreateMember adds a new member to the given group.
// If ID is non-empty, it will be used, otherwise a new ID is created.
// Returns ID, error
@ -112,8 +92,6 @@ type Context interface {
EnableScalingCluster(ctx context.Context) error
// GetBackup receives information about a backup resource
GetBackup(ctx context.Context, backup string) (*backupApi.ArangoBackup, error)
// GetName receives deployment name
GetName() string
// GetAuthentication return authentication for members
GetAuthentication() conn.Auth
}

View file

@ -23,59 +23,41 @@ package reconcile
import (
"context"
"github.com/arangodb/kube-arangodb/pkg/deployment/resources"
"github.com/arangodb/go-driver/agency"
"github.com/arangodb/kube-arangodb/pkg/util/arangod/conn"
backupApi "github.com/arangodb/kube-arangodb/pkg/apis/backup/v1"
"github.com/arangodb/go-driver"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
"github.com/arangodb/kube-arangodb/pkg/deployment/reconciler"
core "k8s.io/api/core/v1"
)
// PlanBuilderContext contains context methods provided to plan builders.
type PlanBuilderContext interface {
resources.DeploymentAgencyMaintenance
resources.ArangoMemberContext
resources.DeploymentPodRenderer
resources.DeploymentImageManager
resources.DeploymentModInterfaces
resources.DeploymentCachedStatus
resources.ArangoAgencyGet
reconciler.DeploymentInfoGetter
reconciler.DeploymentAgencyMaintenance
reconciler.ArangoMemberContext
reconciler.DeploymentPodRenderer
reconciler.DeploymentImageManager
reconciler.DeploymentModInterfaces
reconciler.DeploymentCachedStatus
reconciler.ArangoAgencyGet
reconciler.DeploymentClient
reconciler.KubernetesEventGenerator
// GetTLSKeyfile returns the keyfile encoded TLS certificate+key for
// the given member.
GetTLSKeyfile(group api.ServerGroup, member api.MemberStatus) (string, error)
// CreateEvent creates a given event.
// On error, the error is logged.
CreateEvent(evt *k8sutil.Event)
// GetPvc gets a PVC by the given name, in the samespace of the deployment.
GetPvc(ctx context.Context, pvcName string) (*core.PersistentVolumeClaim, error)
// GetShardSyncStatus returns true if all shards are in sync
GetShardSyncStatus() bool
// InvalidateSyncStatus resets the sync state to false and triggers an inspection
InvalidateSyncStatus()
// GetStatus returns the current status of the deployment
GetStatus() (api.DeploymentStatus, int32)
// GetStatus returns the current spec of the deployment
GetSpec() api.DeploymentSpec
// GetDatabaseClient returns a cached client for the entire database (cluster coordinators or single server),
// creating one if needed.
GetDatabaseClient(ctx context.Context) (driver.Client, error)
// GetServerClient returns a cached client for a specific server.
GetServerClient(ctx context.Context, group api.ServerGroup, id string) (driver.Client, error)
// GetAuthentication return authentication for members
GetAuthentication() conn.Auth
// GetBackup receives information about a backup resource
GetBackup(ctx context.Context, backup string) (*backupApi.ArangoBackup, error)
// GetName receives deployment name
GetName() string
// GetAgency returns a connection to the entire agency.
GetAgency(ctx context.Context) (agency.Agency, error)
}
// newPlanBuilderContext creates a PlanBuilderContext from the given context

View file

@ -72,6 +72,7 @@ import (
driver "github.com/arangodb/go-driver"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/deployment/reconciler"
"github.com/arangodb/kube-arangodb/pkg/util"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
core "k8s.io/api/core/v1"
@ -93,6 +94,26 @@ type testContext struct {
Inspector inspectorInterface.Inspector
}
func (c *testContext) GetMode() api.DeploymentMode {
//TODO implement me
panic("implement me")
}
func (c *testContext) GetNamespace() string {
//TODO implement me
panic("implement me")
}
func (c *testContext) GetAgencyClients(ctx context.Context) ([]driver.Connection, error) {
//TODO implement me
panic("implement me")
}
func (c *testContext) GetAgencyClientsWithPredicate(ctx context.Context, predicate func(id string) bool) ([]driver.Connection, error) {
//TODO implement me
panic("implement me")
}
func (c *testContext) ApplyPatchOnPod(ctx context.Context, pod *core.Pod, p ...patch.Item) error {
panic("implement me")
}
@ -150,7 +171,7 @@ func (c *testContext) GetCachedStatus() inspectorInterface.Inspector {
panic("implement me")
}
func (c *testContext) WithStatusUpdateErr(ctx context.Context, action resources.DeploymentStatusUpdateErrFunc, force ...bool) error {
func (c *testContext) WithStatusUpdateErr(ctx context.Context, action reconciler.DeploymentStatusUpdateErrFunc, force ...bool) error {
_, err := action(&c.ArangoDeployment.Status)
return err
}
@ -183,11 +204,11 @@ func (c *testContext) RenderPodTemplateForMember(ctx context.Context, cachedStat
panic("implement me")
}
func (c *testContext) WithArangoMemberUpdate(ctx context.Context, namespace, name string, action resources.ArangoMemberUpdateFunc) error {
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 resources.ArangoMemberStatusUpdateFunc) error {
func (c *testContext) WithArangoMemberStatusUpdate(ctx context.Context, namespace, name string, action reconciler.ArangoMemberStatusUpdateFunc) error {
panic("implement me")
}
@ -199,7 +220,7 @@ func (c *testContext) SetAgencyMaintenanceMode(ctx context.Context, enabled bool
panic("implement me")
}
func (c *testContext) WithStatusUpdate(ctx context.Context, action resources.DeploymentStatusUpdateFunc, force ...bool) error {
func (c *testContext) WithStatusUpdate(ctx context.Context, action reconciler.DeploymentStatusUpdateFunc, force ...bool) error {
action(&c.ArangoDeployment.Status)
return nil
}
@ -289,10 +310,6 @@ func (c *testContext) GetServerClient(ctx context.Context, group api.ServerGroup
panic("implement me")
}
func (c *testContext) GetAgencyClients(ctx context.Context, predicate func(id string) bool) ([]driver.Connection, error) {
panic("implement me")
}
func (c *testContext) GetAgency(ctx context.Context) (agency.Agency, error) {
panic("implement me")
}

View file

@ -0,0 +1,204 @@
//
// 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"
"github.com/arangodb/arangosync-client/client"
"github.com/arangodb/go-driver"
"github.com/arangodb/go-driver/agency"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
agencyCache "github.com/arangodb/kube-arangodb/pkg/deployment/agency"
"github.com/arangodb/kube-arangodb/pkg/deployment/patch"
"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/inspector/arangomember"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/persistentvolumeclaim"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/pod"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/poddisruptionbudget"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/secret"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/service"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/serviceaccount"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/servicemonitor"
core "k8s.io/api/core/v1"
)
// ServerGroupIterator provides a helper to callback on every server
// group of the deployment.
type ServerGroupIterator interface {
// ForeachServerGroup calls the given callback for all server groups.
// If the callback returns an error, this error is returned and no other server
// groups are processed.
// Groups are processed in this order: agents, single, dbservers, coordinators, syncmasters, syncworkers
ForeachServerGroup(cb api.ServerGroupFunc, status *api.DeploymentStatus) error
}
type DeploymentStatusUpdateErrFunc func(s *api.DeploymentStatus) (bool, error)
type DeploymentStatusUpdateFunc func(s *api.DeploymentStatus) bool
type DeploymentStatusUpdate interface {
// WithStatusUpdateErr update status of ArangoDeployment with defined modifier. If action returns True action is taken
WithStatusUpdateErr(ctx context.Context, action DeploymentStatusUpdateErrFunc, force ...bool) error
// WithStatusUpdate update status of ArangoDeployment with defined modifier. If action returns True action is taken
WithStatusUpdate(ctx context.Context, action DeploymentStatusUpdateFunc, force ...bool) error
// UpdateStatus replaces the status of the deployment with the given status and
// updates the resources in k8s.
UpdateStatus(ctx context.Context, status api.DeploymentStatus, lastVersion int32, force ...bool) error
// UpdateMember updates the deployment status wrt the given member.
UpdateMember(ctx context.Context, member api.MemberStatus) error
}
type DeploymentAgencyMaintenance interface {
// SetAgencyMaintenanceMode set maintenance mode info
SetAgencyMaintenanceMode(ctx context.Context, enabled bool) error
}
type DeploymentPodRenderer interface {
// RenderPodForMember Renders Pod definition for member
RenderPodForMember(ctx context.Context, cachedStatus inspectorInterface.Inspector, spec api.DeploymentSpec, status api.DeploymentStatus, memberID string, imageInfo api.ImageInfo) (*core.Pod, error)
// RenderPodTemplateForMember Renders PodTemplate definition for member
RenderPodTemplateForMember(ctx context.Context, cachedStatus inspectorInterface.Inspector, spec api.DeploymentSpec, status api.DeploymentStatus, memberID string, imageInfo api.ImageInfo) (*core.PodTemplateSpec, error)
// RenderPodForMemberFromCurrent Renders PodTemplate definition for member from current state
RenderPodForMemberFromCurrent(ctx context.Context, cachedStatus inspectorInterface.Inspector, memberID string) (*core.Pod, error)
// RenderPodTemplateForMemberFromCurrent Renders PodTemplate definition for member
RenderPodTemplateForMemberFromCurrent(ctx context.Context, cachedStatus inspectorInterface.Inspector, memberID string) (*core.PodTemplateSpec, error)
DeploymentEndpoints
}
type DeploymentEndpoints interface {
// GenerateMemberEndpoint generates endpoint for a member
GenerateMemberEndpoint(group api.ServerGroup, member api.MemberStatus) (string, error)
}
type DeploymentImageManager interface {
// SelectImage select currently used image by pod
SelectImage(spec api.DeploymentSpec, status api.DeploymentStatus) (api.ImageInfo, bool)
// SelectImageForMember select currently used image by pod in member
SelectImageForMember(spec api.DeploymentSpec, status api.DeploymentStatus, member api.MemberStatus) (api.ImageInfo, bool)
}
type DeploymentModInterfaces interface {
// SecretsModInterface define secret modification interface
SecretsModInterface() secret.ModInterface
// PodsModInterface define pod modification interface
PodsModInterface() pod.ModInterface
// ServiceAccountsModInterface define serviceaccounts modification interface
ServiceAccountsModInterface() serviceaccount.ModInterface
// ServicesModInterface define services modification interface
ServicesModInterface() service.ModInterface
// PersistentVolumeClaimsModInterface define persistentvolumeclaims modification interface
PersistentVolumeClaimsModInterface() persistentvolumeclaim.ModInterface
// PodDisruptionBudgetsModInterface define poddisruptionbudgets modification interface
PodDisruptionBudgetsModInterface() poddisruptionbudget.ModInterface
// ServiceMonitorsModInterface define servicemonitor modification interface
ServiceMonitorsModInterface() servicemonitor.ModInterface
// ArangoMembersModInterface define arangomembers modification interface
ArangoMembersModInterface() arangomember.ModInterface
}
type DeploymentCachedStatus interface {
// GetCachedStatus current cached state of deployment
GetCachedStatus() inspectorInterface.Inspector
}
type ArangoMemberUpdateFunc func(obj *api.ArangoMember) bool
type ArangoMemberStatusUpdateFunc func(obj *api.ArangoMember, s *api.ArangoMemberStatus) bool
type ArangoMemberContext interface {
// WithArangoMemberUpdate run action with update of ArangoMember
WithArangoMemberUpdate(ctx context.Context, namespace, name string, action ArangoMemberUpdateFunc) error
// WithArangoMemberStatusUpdate run action with update of ArangoMember Status
WithArangoMemberStatusUpdate(ctx context.Context, namespace, name string, action ArangoMemberStatusUpdateFunc) error
}
type ArangoAgencyGet interface {
GetAgencyCache() (agencyCache.State, bool)
}
type ArangoAgency interface {
ArangoAgencyGet
RefreshAgencyCache(ctx context.Context) (uint64, error)
}
type DeploymentInfoGetter interface {
// GetAPIObject returns the deployment as k8s object.
GetAPIObject() k8sutil.APIObject
// GetSpec returns the current specification of the deployment
GetSpec() api.DeploymentSpec
// GetStatus returns the current status of the deployment
GetStatus() (api.DeploymentStatus, int32)
// GetStatusSnapshot returns the current status of the deployment without revision
GetStatusSnapshot() api.DeploymentStatus
// GetMode the specified mode of deployment
GetMode() api.DeploymentMode
// GetName returns the name of the deployment
GetName() string
// GetNamespace returns the namespace that contains the deployment
GetNamespace() string
}
type ArangoApplier interface {
ApplyPatchOnPod(ctx context.Context, pod *core.Pod, p ...patch.Item) error
ApplyPatch(ctx context.Context, p ...patch.Item) error
}
type DeploymentAgencyClient interface {
// GetAgencyClients returns a client connection for every agency member.
GetAgencyClients(ctx context.Context) ([]driver.Connection, error)
// GetAgencyClientsWithPredicate returns a client connection for every agency member which match condition.
GetAgencyClientsWithPredicate(ctx context.Context, predicate func(id string) bool) ([]driver.Connection, error)
// GetAgency returns a connection to the entire agency.
GetAgency(ctx context.Context) (agency.Agency, error)
}
type DeploymentDatabaseClient interface {
// GetDatabaseClient returns a cached client for the entire database (cluster coordinators or single server),
// creating one if needed.
GetDatabaseClient(ctx context.Context) (driver.Client, error)
}
type DeploymentMemberClient interface {
// GetServerClient returns a cached client for a specific server.
GetServerClient(ctx context.Context, group api.ServerGroup, id string) (driver.Client, error)
}
type DeploymentSyncClient interface {
// GetSyncServerClient returns a cached client for a specific arangosync server.
GetSyncServerClient(ctx context.Context, group api.ServerGroup, id string) (client.API, error)
}
type KubernetesEventGenerator interface {
// CreateEvent creates a given event.
// On error, the error is logged.
CreateEvent(evt *k8sutil.Event)
}
type DeploymentClient interface {
DeploymentAgencyClient
DeploymentDatabaseClient
DeploymentMemberClient
}

View file

@ -23,12 +23,14 @@ package resilience
import (
"context"
driver "github.com/arangodb/go-driver"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/deployment/reconciler"
)
// Context provides methods to the resilience package.
type Context interface {
reconciler.DeploymentDatabaseClient
reconciler.DeploymentAgencyClient
// GetSpec returns the current specification of the deployment
GetSpec() api.DeploymentSpec
// GetStatus returns the current status of the deployment
@ -36,10 +38,4 @@ type Context interface {
// UpdateStatus replaces the status of the deployment with the given status and
// updates the resources in k8s.
UpdateStatus(ctx context.Context, status api.DeploymentStatus, lastVersion int32, force ...bool) error
// GetAgencyClients returns a client connection for every agency member.
// If the given predicate is not nil, only agents are included where the given predicate returns true.
GetAgencyClients(ctx context.Context, predicate func(id string) bool) ([]driver.Connection, error)
// GetDatabaseClient returns a cached client for the entire database (cluster coordinators or single server),
// creating one if needed.
GetDatabaseClient(ctx context.Context) (driver.Client, error)
}

View file

@ -133,7 +133,7 @@ func (r *Resilience) isMemberFailureAcceptable(ctx context.Context, group api.Se
// All good when remaining agents are health
ctxChild, cancel := globals.GetGlobalTimeouts().ArangoD().WithTimeout(ctx)
defer cancel()
clients, err := r.context.GetAgencyClients(ctxChild, func(id string) bool { return id != m.ID })
clients, err := r.context.GetAgencyClientsWithPredicate(ctxChild, func(id string) bool { return id != m.ID })
if err != nil {
return false, "", errors.WithStack(err)
}

View file

@ -23,155 +23,35 @@ package resources
import (
"context"
"github.com/arangodb/go-driver"
"github.com/arangodb/go-driver/agency"
core "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
backupApi "github.com/arangodb/kube-arangodb/pkg/apis/backup/v1"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
agencyCache "github.com/arangodb/kube-arangodb/pkg/deployment/agency"
"github.com/arangodb/kube-arangodb/pkg/deployment/patch"
"github.com/arangodb/kube-arangodb/pkg/deployment/reconciler"
"github.com/arangodb/kube-arangodb/pkg/operator/scope"
"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/inspector/arangomember"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/persistentvolumeclaim"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/pod"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/poddisruptionbudget"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/secret"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/service"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/serviceaccount"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/servicemonitor"
)
// ServerGroupIterator provides a helper to callback on every server
// group of the deployment.
type ServerGroupIterator interface {
// ForeachServerGroup calls the given callback for all server groups.
// If the callback returns an error, this error is returned and no other server
// groups are processed.
// Groups are processed in this order: agents, single, dbservers, coordinators, syncmasters, syncworkers
ForeachServerGroup(cb api.ServerGroupFunc, status *api.DeploymentStatus) error
}
type DeploymentStatusUpdateErrFunc func(s *api.DeploymentStatus) (bool, error)
type DeploymentStatusUpdateFunc func(s *api.DeploymentStatus) bool
type DeploymentStatusUpdate interface {
// WithStatusUpdateErr update status of ArangoDeployment with defined modifier. If action returns True action is taken
WithStatusUpdateErr(ctx context.Context, action DeploymentStatusUpdateErrFunc, force ...bool) error
// WithStatusUpdate update status of ArangoDeployment with defined modifier. If action returns True action is taken
WithStatusUpdate(ctx context.Context, action DeploymentStatusUpdateFunc, force ...bool) error
}
type DeploymentAgencyMaintenance interface {
// SetAgencyMaintenanceMode set maintenance mode info
SetAgencyMaintenanceMode(ctx context.Context, enabled bool) error
}
type DeploymentPodRenderer interface {
// RenderPodForMember Renders Pod definition for member
RenderPodForMember(ctx context.Context, cachedStatus inspectorInterface.Inspector, spec api.DeploymentSpec, status api.DeploymentStatus, memberID string, imageInfo api.ImageInfo) (*core.Pod, error)
// RenderPodTemplateForMember Renders PodTemplate definition for member
RenderPodTemplateForMember(ctx context.Context, cachedStatus inspectorInterface.Inspector, spec api.DeploymentSpec, status api.DeploymentStatus, memberID string, imageInfo api.ImageInfo) (*core.PodTemplateSpec, error)
// RenderPodTemplateForMember Renders PodTemplate definition for member from current state
RenderPodForMemberFromCurrent(ctx context.Context, cachedStatus inspectorInterface.Inspector, memberID string) (*core.Pod, error)
// RenderPodTemplateForMemberFromCurrent Renders PodTemplate definition for member
RenderPodTemplateForMemberFromCurrent(ctx context.Context, cachedStatus inspectorInterface.Inspector, memberID string) (*core.PodTemplateSpec, error)
DeploymentEndpoints
}
type DeploymentEndpoints interface {
// GenerateMemberEndpoint generates endpoint for a member
GenerateMemberEndpoint(group api.ServerGroup, member api.MemberStatus) (string, error)
}
type DeploymentImageManager interface {
// SelectImage select currently used image by pod
SelectImage(spec api.DeploymentSpec, status api.DeploymentStatus) (api.ImageInfo, bool)
// SelectImage select currently used image by pod in member
SelectImageForMember(spec api.DeploymentSpec, status api.DeploymentStatus, member api.MemberStatus) (api.ImageInfo, bool)
}
type DeploymentModInterfaces interface {
// SecretsModInterface define secret modification interface
SecretsModInterface() secret.ModInterface
// PodModInterface define pod modification interface
PodsModInterface() pod.ModInterface
// ServiceAccountModInterface define serviceaccounts modification interface
ServiceAccountsModInterface() serviceaccount.ModInterface
// ServicesModInterface define services modification interface
ServicesModInterface() service.ModInterface
// PersistentVolumeClaimsModInterface define persistentvolumeclaims modification interface
PersistentVolumeClaimsModInterface() persistentvolumeclaim.ModInterface
// PodDisruptionBudgetsModInterface define poddisruptionbudgets modification interface
PodDisruptionBudgetsModInterface() poddisruptionbudget.ModInterface
// ServiceMonitorModInterface define servicemonitor modification interface
ServiceMonitorsModInterface() servicemonitor.ModInterface
// ArangoMembersModInterface define arangomembers modification interface
ArangoMembersModInterface() arangomember.ModInterface
}
type DeploymentCachedStatus interface {
// GetCachedStatus current cached state of deployment
GetCachedStatus() inspectorInterface.Inspector
}
type ArangoMemberUpdateFunc func(obj *api.ArangoMember) bool
type ArangoMemberStatusUpdateFunc func(obj *api.ArangoMember, s *api.ArangoMemberStatus) bool
type ArangoMemberContext interface {
// WithArangoMemberUpdate run action with update of ArangoMember
WithArangoMemberUpdate(ctx context.Context, namespace, name string, action ArangoMemberUpdateFunc) error
// WithArangoMemberStatusUpdate run action with update of ArangoMember Status
WithArangoMemberStatusUpdate(ctx context.Context, namespace, name string, action ArangoMemberStatusUpdateFunc) error
}
type ArangoAgencyGet interface {
GetAgencyCache() (agencyCache.State, bool)
}
type ArangoAgency interface {
ArangoAgencyGet
RefreshAgencyCache(ctx context.Context) (uint64, error)
}
type DeploymentInfoGetter interface {
// GetAPIObject returns the deployment as k8s object.
GetAPIObject() k8sutil.APIObject
// GetSpec returns the current specification of the deployment
GetSpec() api.DeploymentSpec
// GetStatus returns the current status of the deployment
GetStatus() (api.DeploymentStatus, int32)
// GetStatus returns the current status of the deployment without revision
GetStatusSnapshot() api.DeploymentStatus
}
type ArangoApplier interface {
ApplyPatchOnPod(ctx context.Context, pod *core.Pod, p ...patch.Item) error
ApplyPatch(ctx context.Context, p ...patch.Item) error
}
// Context provides all functions needed by the Resources service
// to perform its service.
type Context interface {
DeploymentStatusUpdate
DeploymentAgencyMaintenance
ArangoMemberContext
DeploymentImageManager
DeploymentModInterfaces
DeploymentCachedStatus
ArangoAgency
ArangoApplier
DeploymentInfoGetter
reconciler.DeploymentStatusUpdate
reconciler.DeploymentAgencyMaintenance
reconciler.ArangoMemberContext
reconciler.DeploymentImageManager
reconciler.DeploymentModInterfaces
reconciler.DeploymentCachedStatus
reconciler.ArangoAgency
reconciler.ArangoApplier
reconciler.DeploymentInfoGetter
reconciler.DeploymentClient
reconciler.DeploymentSyncClient
reconciler.KubernetesEventGenerator
// GetServerGroupIterator returns the deployment as ServerGroupIterator.
GetServerGroupIterator() ServerGroupIterator
GetServerGroupIterator() reconciler.ServerGroupIterator
// UpdateStatus replaces the status of the deployment with the given status and
// updates the resources in k8s.
UpdateStatus(ctx context.Context, status api.DeploymentStatus, lastVersion int32, force ...bool) error
@ -179,10 +59,6 @@ type Context interface {
GetOperatorImage() string
// GetArangoImage returns the image name containing the default arango image
GetArangoImage() string
// GetName returns the name of the deployment
GetName() string
// GetNamespace returns the namespace that contains the deployment
GetNamespace() string
// CreateEvent creates a given event.
// On error, the error is logged.
CreateEvent(evt *k8sutil.Event)
@ -197,13 +73,6 @@ type Context interface {
// DeletePvc deletes a persistent volume claim with given name in the namespace
// of the deployment. If the pvc does not exist, the error is ignored.
DeletePvc(ctx context.Context, pvcName string) error
// GetAgencyClients returns a client connection for every agency member.
GetAgencyClients(ctx context.Context, predicate func(memberID string) bool) ([]driver.Connection, error)
// GetDatabaseClient returns a cached client for the entire database (cluster coordinators or single server),
// creating one if needed.
GetDatabaseClient(ctx context.Context) (driver.Client, error)
// GetAgency returns a connection to the entire agency.
GetAgency(ctx context.Context) (agency.Agency, error)
// GetBackup receives information about a backup resource
GetBackup(ctx context.Context, backup string) (*backupApi.ArangoBackup, error)
GetScope() scope.Scope

View file

@ -92,7 +92,7 @@ func (r *Resources) prepareAgencyPodTermination(ctx context.Context, log zerolog
defer cancel()
ctxLeader := agency.WithAllowNoLeader(ctxChild) // The ID we're checking may be the leader, so ignore situations where all other agents are followers
agencyConns, err := r.context.GetAgencyClients(ctxLeader, func(id string) bool { return id != memberStatus.ID })
agencyConns, err := r.context.GetAgencyClientsWithPredicate(ctxLeader, func(id string) bool { return id != memberStatus.ID })
if err != nil {
log.Debug().Err(err).Msg("Failed to create member client")
return errors.WithStack(err)

View file

@ -35,7 +35,7 @@ import (
"github.com/arangodb/kube-arangodb/pkg/deployment/pod"
v1 "k8s.io/api/core/v1"
core "k8s.io/api/core/v1"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
@ -53,7 +53,7 @@ func (r *Resources) ValidateSecretHashes(ctx context.Context, cachedStatus inspe
validate := func(secretName string,
getExpectedHash func() string,
setExpectedHash func(string) error,
actionHashChanged func(Context, *v1.Secret) error) (bool, error) {
actionHashChanged func(Context, *core.Secret) error) (bool, error) {
log := r.log.With().Str("secret-name", secretName).Logger()
expectedHash := getExpectedHash()
@ -230,7 +230,7 @@ func (r *Resources) ValidateSecretHashes(ctx context.Context, cachedStatus inspe
}
// getSecretHash fetches a secret with given name and returns a hash over its value.
func (r *Resources) getSecretHash(cachedStatus inspectorInterface.Inspector, secretName string) (*v1.Secret, string, bool) {
func (r *Resources) getSecretHash(cachedStatus inspectorInterface.Inspector, secretName string) (*core.Secret, string, bool) {
s, exists := cachedStatus.Secret(secretName)
if !exists {
return nil, "", false

View file

@ -44,8 +44,8 @@ func (d *Deployment) Namespace() string {
return d.apiObject.Namespace
}
// Mode returns the mode of the deployment.
func (d *Deployment) Mode() api.DeploymentMode {
// GetMode returns the mode of the deployment.
func (d *Deployment) GetMode() api.DeploymentMode {
return d.GetSpec().GetMode()
}

View file

@ -34,7 +34,7 @@ import (
type Deployment interface {
Name() string
Namespace() string
Mode() api.DeploymentMode
GetMode() api.DeploymentMode
Environment() api.Environment
StateColor() StateColor
PodCount() int
@ -98,7 +98,7 @@ func newDeploymentInfo(d Deployment) DeploymentInfo {
return DeploymentInfo{
Name: d.Name(),
Namespace: d.Namespace(),
Mode: d.Mode(),
Mode: d.GetMode(),
Environment: d.Environment(),
StateColor: d.StateColor(),
PodCount: d.PodCount(),