From ec3c0054bd74406423bb7882975b4303b4e49d69 Mon Sep 17 00:00:00 2001 From: ajanikow <12255597+ajanikow@users.noreply.github.com> Date: Thu, 3 Feb 2022 01:48:19 +0000 Subject: [PATCH] [Cleanup] Reorganize main reconciliation context --- CHANGELOG.md | 1 + pkg/deployment/client/client_cache.go | 7 +- pkg/deployment/context_impl.go | 18 +- pkg/deployment/deployment.go | 2 +- pkg/deployment/reconcile/action_context.go | 66 +++--- pkg/deployment/reconcile/context.go | 52 ++--- .../reconcile/plan_builder_context.go | 40 +--- pkg/deployment/reconcile/plan_builder_test.go | 33 ++- pkg/deployment/reconciler/context.go | 204 ++++++++++++++++++ pkg/deployment/resilience/context.go | 10 +- pkg/deployment/resilience/member_failure.go | 2 +- pkg/deployment/resources/context.go | 159 ++------------ pkg/deployment/resources/pod_termination.go | 2 +- pkg/deployment/resources/secret_hashes.go | 6 +- pkg/deployment/server_api.go | 4 +- pkg/server/handlers_deployment.go | 4 +- 16 files changed, 330 insertions(+), 280 deletions(-) create mode 100644 pkg/deployment/reconciler/context.go diff --git a/CHANGELOG.md b/CHANGELOG.md index ce895eb47..d15100cfe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/pkg/deployment/client/client_cache.go b/pkg/deployment/client/client_cache.go index c24f6ec7b..966da037b 100644 --- a/pkg/deployment/client/client_cache.go +++ b/pkg/deployment/client/client_cache.go @@ -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 { diff --git a/pkg/deployment/context_impl.go b/pkg/deployment/context_impl.go index 5f8f3e747..14b7d1e2b 100644 --- a/pkg/deployment/context_impl.go +++ b/pkg/deployment/context_impl.go @@ -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 diff --git a/pkg/deployment/deployment.go b/pkg/deployment/deployment.go index 2bcb6fce7..1ba5893de 100644 --- a/pkg/deployment/deployment.go +++ b/pkg/deployment/deployment.go @@ -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 } diff --git a/pkg/deployment/reconcile/action_context.go b/pkg/deployment/reconcile/action_context.go index a75a01359..4cbd90b3e 100644 --- a/pkg/deployment/reconcile/action_context.go +++ b/pkg/deployment/reconcile/action_context.go @@ -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 - - // 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) + reconciler.DeploymentStatusUpdate + reconciler.DeploymentAgencyMaintenance + reconciler.ArangoMemberContext + reconciler.DeploymentPodRenderer + reconciler.DeploymentModInterfaces + reconciler.DeploymentCachedStatus + reconciler.ArangoAgencyGet + reconciler.DeploymentInfoGetter + reconciler.DeploymentClient + reconciler.DeploymentSyncClient + // 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) } diff --git a/pkg/deployment/reconcile/context.go b/pkg/deployment/reconcile/context.go index d53d2a67b..e54c25fd5 100644 --- a/pkg/deployment/reconcile/context.go +++ b/pkg/deployment/reconcile/context.go @@ -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 } diff --git a/pkg/deployment/reconcile/plan_builder_context.go b/pkg/deployment/reconcile/plan_builder_context.go index 30bfc5a2b..4cda79dce 100644 --- a/pkg/deployment/reconcile/plan_builder_context.go +++ b/pkg/deployment/reconcile/plan_builder_context.go @@ -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 diff --git a/pkg/deployment/reconcile/plan_builder_test.go b/pkg/deployment/reconcile/plan_builder_test.go index a187f1ee8..b38acb87d 100644 --- a/pkg/deployment/reconcile/plan_builder_test.go +++ b/pkg/deployment/reconcile/plan_builder_test.go @@ -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") } diff --git a/pkg/deployment/reconciler/context.go b/pkg/deployment/reconciler/context.go new file mode 100644 index 000000000..455083a9f --- /dev/null +++ b/pkg/deployment/reconciler/context.go @@ -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 +} diff --git a/pkg/deployment/resilience/context.go b/pkg/deployment/resilience/context.go index 866b58c74..8b0a231d4 100644 --- a/pkg/deployment/resilience/context.go +++ b/pkg/deployment/resilience/context.go @@ -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) } diff --git a/pkg/deployment/resilience/member_failure.go b/pkg/deployment/resilience/member_failure.go index 5ccfb39f6..d39be701d 100644 --- a/pkg/deployment/resilience/member_failure.go +++ b/pkg/deployment/resilience/member_failure.go @@ -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) } diff --git a/pkg/deployment/resources/context.go b/pkg/deployment/resources/context.go index 0f8792245..160bab149 100644 --- a/pkg/deployment/resources/context.go +++ b/pkg/deployment/resources/context.go @@ -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 diff --git a/pkg/deployment/resources/pod_termination.go b/pkg/deployment/resources/pod_termination.go index 1ac1b9d41..b5ddaca8e 100644 --- a/pkg/deployment/resources/pod_termination.go +++ b/pkg/deployment/resources/pod_termination.go @@ -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) diff --git a/pkg/deployment/resources/secret_hashes.go b/pkg/deployment/resources/secret_hashes.go index c831f95dd..3a777ac73 100644 --- a/pkg/deployment/resources/secret_hashes.go +++ b/pkg/deployment/resources/secret_hashes.go @@ -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 diff --git a/pkg/deployment/server_api.go b/pkg/deployment/server_api.go index ad010947a..11eb701d4 100644 --- a/pkg/deployment/server_api.go +++ b/pkg/deployment/server_api.go @@ -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() } diff --git a/pkg/server/handlers_deployment.go b/pkg/server/handlers_deployment.go index 9f5beeb08..b881006ba 100644 --- a/pkg/server/handlers_deployment.go +++ b/pkg/server/handlers_deployment.go @@ -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(),