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

[Feature] Add Maintenance Mode support (#623)

This commit is contained in:
Adam Janikowski 2020-09-03 08:53:56 +02:00 committed by GitHub
parent 7a8be98fa3
commit 9b5f145bc2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 619 additions and 64 deletions

View file

@ -1,6 +1,7 @@
# Change Log # Change Log
## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A) ## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A)
- Add Operator Maintenance Management feature
## [1.0.6](https://github.com/arangodb/kube-arangodb/tree/1.0.6) (2020-08-19) ## [1.0.6](https://github.com/arangodb/kube-arangodb/tree/1.0.6) (2020-08-19)
- Add Operator Namespaced mode (Alpha) - Add Operator Namespaced mode (Alpha)

View file

@ -60,25 +60,26 @@ covers individual newer features separately.
Feature-wise production readiness table: Feature-wise production readiness table:
| Feature | Operator Version | ArangoDB Version | ArangoDB Edition | State | Enabled | Flag | Remarks | | Feature | Operator Version | ArangoDB Version | ArangoDB Edition | State | Enabled | Flag | Remarks |
|---------------------------------|------------------|------------------|-----------------------|------------|---------|------------------------------------------|--------------------------------------------------------------------------| |-----------------------------------------|------------------|------------------|-----------------------|------------|---------|------------------------------------------|--------------------------------------------------------------------------|
| Pod Disruption Budgets | 0.3.10 | Any | Community, Enterprise | Alpha | True | N/A | N/A | | Pod Disruption Budgets | 0.3.10 | Any | Community, Enterprise | Alpha | True | N/A | N/A |
| Pod Disruption Budgets | 0.3.11 | Any | Community, Enterprise | Production | True | N/A | N/A | | Pod Disruption Budgets | 0.3.11 | Any | Community, Enterprise | Production | True | N/A | N/A |
| Volume Resizing | 0.3.10 | Any | Community, Enterprise | Alpha | True | N/A | N/A | | Volume Resizing | 0.3.10 | Any | Community, Enterprise | Alpha | True | N/A | N/A |
| Volume Resizing | 0.3.11 | Any | Community, Enterprise | Production | True | N/A | N/A | | Volume Resizing | 0.3.11 | Any | Community, Enterprise | Production | True | N/A | N/A |
| Disabling of liveness probes | 0.3.10 | Any | Community, Enterprise | Alpha | True | N/A | N/A | | Disabling of liveness probes | 0.3.10 | Any | Community, Enterprise | Alpha | True | N/A | N/A |
| Disabling of liveness probes | 0.3.11 | Any | Community, Enterprise | Production | True | N/A | N/A | | Disabling of liveness probes | 0.3.11 | Any | Community, Enterprise | Production | True | N/A | N/A |
| Volume Claim Templates | 0.3.11 | Any | Community, Enterprise | Alpha | True | N/A | N/A | | Volume Claim Templates | 0.3.11 | Any | Community, Enterprise | Alpha | True | N/A | N/A |
| Volume Claim Templates | 1.0.0 | Any | Community, Enterprise | Production | True | N/A | N/A | | Volume Claim Templates | 1.0.0 | Any | Community, Enterprise | Production | True | N/A | N/A |
| Prometheus Metrics Exporter | 0.3.11 | Any | Community, Enterprise | Alpha | True | N/A | Prometheus required | | Prometheus Metrics Exporter | 0.3.11 | Any | Community, Enterprise | Alpha | True | N/A | Prometheus required |
| Prometheus Metrics Exporter | 1.0.0 | Any | Community, Enterprise | Production | True | N/A | Prometheus required | | Prometheus Metrics Exporter | 1.0.0 | Any | Community, Enterprise | Production | True | N/A | Prometheus required |
| Sidecar Containers | 0.3.11 | Any | Community, Enterprise | Alpha | True | N/A | N/A | | Sidecar Containers | 0.3.11 | Any | Community, Enterprise | Alpha | True | N/A | N/A |
| Sidecar Containers | 1.0.0 | Any | Community, Enterprise | Production | True | N/A | N/A | | Sidecar Containers | 1.0.0 | Any | Community, Enterprise | Production | True | N/A | N/A |
| Operator Single Mode | 1.0.4 | Any | Community, Enterprise | Production | False | --mode.single | Only 1 instance of Operator allowed in namespace when feature is enabled | | Operator Single Mode | 1.0.4 | Any | Community, Enterprise | Production | False | --mode.single | Only 1 instance of Operator allowed in namespace when feature is enabled |
| TLS SNI Support | 1.0.3 | >= 3.7.0 | Enterprise | Production | True | --deployment.feature.tls-sni | N/A | | TLS SNI Support | 1.0.3 | >= 3.7.0 | Enterprise | Production | True | --deployment.feature.tls-sni | N/A |
| TLS Runtime Rotation Support | 1.0.4 | > 3.7.0 | Enterprise | Alpha | False | --deployment.feature.tls-rotation | N/A | | TLS Runtime Rotation Support | 1.0.4 | > 3.7.0 | Enterprise | Alpha | False | --deployment.feature.tls-rotation | N/A |
| JWT Rotation Support | 1.0.4 | > 3.7.0 | Enterprise | Alpha | False | --deployment.feature.jwt-rotation | N/A | | JWT Rotation Support | 1.0.4 | > 3.7.0 | Enterprise | Alpha | False | --deployment.feature.jwt-rotation | N/A |
| Encryption Key Rotation Support | 1.0.4 | > 3.7.0 | Enterprise | Alpha | False | --deployment.feature.encryption-rotation | N/A | | Encryption Key Rotation Support | 1.0.4 | > 3.7.0 | Enterprise | Alpha | False | --deployment.feature.encryption-rotation | N/A |
| Operator Maintenance Management Support | 1.0.7 | >= 3.5.0 | Community, Enterprise | Alpha | False | --deployment.feature.maintenance | N/A |
## Release notes for 0.3.16 ## Release notes for 0.3.16

View file

@ -0,0 +1,35 @@
//
// DISCLAIMER
//
// Copyright 2020 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
//
// Author Adam Janikowski
//
package v1
type DatabaseSpec struct {
Maintenance *bool `json:"maintenance,omitempty"`
}
func (m *DatabaseSpec) GetMaintenance() bool {
if m == nil || m.Maintenance == nil {
return false
}
return *m.Maintenance
}

View file

@ -95,6 +95,8 @@ type DeploymentSpec struct {
ID *ServerIDGroupSpec `json:"id,omitempty"` ID *ServerIDGroupSpec `json:"id,omitempty"`
Database *DatabaseSpec `json:"database,omitempty"`
Single ServerGroupSpec `json:"single"` Single ServerGroupSpec `json:"single"`
Agents ServerGroupSpec `json:"agents"` Agents ServerGroupSpec `json:"agents"`
DBServers ServerGroupSpec `json:"dbservers"` DBServers ServerGroupSpec `json:"dbservers"`
@ -295,6 +297,9 @@ func (s *DeploymentSpec) SetDefaultsFrom(source DeploymentSpec) {
if s.AllowUnsafeUpgrade == nil { if s.AllowUnsafeUpgrade == nil {
s.AllowUnsafeUpgrade = util.NewBoolOrNil(source.AllowUnsafeUpgrade) s.AllowUnsafeUpgrade = util.NewBoolOrNil(source.AllowUnsafeUpgrade)
} }
if s.Database == nil {
s.Database = source.Database.DeepCopy()
}
s.License.SetDefaultsFrom(source.License) s.License.SetDefaultsFrom(source.License)
s.ExternalAccess.SetDefaultsFrom(source.ExternalAccess) s.ExternalAccess.SetDefaultsFrom(source.ExternalAccess)

View file

@ -119,6 +119,10 @@ const (
ActionTypeJWTPropagated ActionType = "JWTPropagated" ActionTypeJWTPropagated ActionType = "JWTPropagated"
// ActionTypeClusterMemberCleanup removes member from cluster // ActionTypeClusterMemberCleanup removes member from cluster
ActionTypeClusterMemberCleanup ActionType = "ClusterMemberCleanup" ActionTypeClusterMemberCleanup ActionType = "ClusterMemberCleanup"
// ActionTypeEnableMaintenance enables maintenance on cluster.
ActionTypeEnableMaintenance ActionType = "EnableMaintenance"
// ActionTypeEnableMaintenance disables maintenance on cluster.
ActionTypeDisableMaintenance ActionType = "DisableMaintenance"
) )
const ( const (

View file

@ -258,6 +258,27 @@ func (in ConditionList) DeepCopy() ConditionList {
return *out return *out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DatabaseSpec) DeepCopyInto(out *DatabaseSpec) {
*out = *in
if in.Maintenance != nil {
in, out := &in.Maintenance, &out.Maintenance
*out = new(bool)
**out = **in
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatabaseSpec.
func (in *DatabaseSpec) DeepCopy() *DatabaseSpec {
if in == nil {
return nil
}
out := new(DatabaseSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DeploymentFeatures) DeepCopyInto(out *DeploymentFeatures) { func (in *DeploymentFeatures) DeepCopyInto(out *DeploymentFeatures) {
*out = *in *out = *in
@ -415,6 +436,11 @@ func (in *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) {
*out = new(ServerIDGroupSpec) *out = new(ServerIDGroupSpec)
(*in).DeepCopyInto(*out) (*in).DeepCopyInto(*out)
} }
if in.Database != nil {
in, out := &in.Database, &out.Database
*out = new(DatabaseSpec)
(*in).DeepCopyInto(*out)
}
in.Single.DeepCopyInto(&out.Single) in.Single.DeepCopyInto(&out.Single)
in.Agents.DeepCopyInto(&out.Agents) in.Agents.DeepCopyInto(&out.Agents)
in.DBServers.DeepCopyInto(&out.DBServers) in.DBServers.DeepCopyInto(&out.DBServers)

View file

@ -22,41 +22,25 @@
package agency package agency
type ArangoPlanDatabases map[string]ArangoPlanCollections import (
"context"
func (a ArangoPlanDatabases) IsDBServerInDatabases(name string) bool { "github.com/arangodb/go-driver/agency"
for _, collections := range a { "github.com/pkg/errors"
if collections.IsDBServerInCollections(name) { )
return true
type Fetcher func(ctx context.Context, i interface{}, keyParts ...string) error
func NewFetcher(a agency.Agency) Fetcher {
return func(ctx context.Context, i interface{}, keyParts ...string) error {
if err := a.ReadKey(ctx, []string{
ArangoKey,
PlanKey,
PlanCollectionsKey,
}, i); err != nil {
return errors.WithStack(err)
} }
return nil
} }
return false
} }
type ArangoPlanCollections map[string]ArangoPlanCollection
func (a ArangoPlanCollections) IsDBServerInCollections(name string) bool {
for _, collection := range a {
if collection.IsDBServerInShards(name) {
return true
}
}
return false
}
type ArangoPlanCollection struct {
Shards ArangoPlanShard `json:"shards"`
}
func (a ArangoPlanCollection) IsDBServerInShards(name string) bool {
for _, dbservers := range a.Shards {
for _, dbserver := range dbservers {
if dbserver == name {
return true
}
}
}
return false
}
type ArangoPlanShard map[string][]string

View file

@ -0,0 +1,78 @@
//
// DISCLAIMER
//
// Copyright 2020 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
//
// Author Adam Janikowski
//
package agency
import (
"context"
"github.com/pkg/errors"
)
func GetAgencyCollections(ctx context.Context, f Fetcher) (*ArangoPlanDatabases, error) {
ret := &ArangoPlanDatabases{}
if err := f(ctx, ret, ArangoKey, PlanKey, PlanCollectionsKey); err != nil {
return nil, errors.WithStack(err)
}
return ret, nil
}
type ArangoPlanDatabases map[string]ArangoPlanCollections
func (a ArangoPlanDatabases) IsDBServerInDatabases(name string) bool {
for _, collections := range a {
if collections.IsDBServerInCollections(name) {
return true
}
}
return false
}
type ArangoPlanCollections map[string]ArangoPlanCollection
func (a ArangoPlanCollections) IsDBServerInCollections(name string) bool {
for _, collection := range a {
if collection.IsDBServerInShards(name) {
return true
}
}
return false
}
type ArangoPlanCollection struct {
Shards ArangoPlanShard `json:"shards"`
}
func (a ArangoPlanCollection) IsDBServerInShards(name string) bool {
for _, dbservers := range a.Shards {
for _, dbserver := range dbservers {
if dbserver == name {
return true
}
}
}
return false
}
type ArangoPlanShard map[string][]string

View file

@ -0,0 +1,91 @@
//
// DISCLAIMER
//
// Copyright 2020 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
//
// Author Adam Janikowski
//
package agency
import (
"context"
"net/http"
"github.com/arangodb/go-driver"
)
type Maintenance struct {
Result string `json:"result"`
}
func (m Maintenance) Enabled() bool {
return m.Result == "Maintenance"
}
func GetMaintenanceMode(ctx context.Context, client driver.Client) (Maintenance, error) {
conn := client.Connection()
r, err := conn.NewRequest(http.MethodGet, "/_admin/cluster/maintenance")
if err != nil {
return Maintenance{}, err
}
resp, err := conn.Do(ctx, r)
if err != nil {
return Maintenance{}, err
}
if err := resp.CheckStatus(http.StatusOK); err != nil {
return Maintenance{}, err
}
var m Maintenance
if err := resp.ParseBody("", &m); err != nil {
return Maintenance{}, err
}
return m, nil
}
func SetMaintenanceMode(ctx context.Context, client driver.Client, enabled bool) error {
data := "on"
if !enabled {
data = "off"
}
conn := client.Connection()
r, err := conn.NewRequest(http.MethodPut, "/_admin/cluster/maintenance")
if err != nil {
return err
}
if _, err := r.SetBody(data); err != nil {
return err
}
resp, err := conn.Do(ctx, r)
if err != nil {
return err
}
if err := resp.CheckStatus(http.StatusOK); err != nil {
return err
}
return nil
}

View file

@ -17,6 +17,8 @@
// //
// Copyright holder is ArangoDB GmbH, Cologne, Germany // Copyright holder is ArangoDB GmbH, Cologne, Germany
// //
// Author Adam Janikowski
//
package features package features

View file

@ -17,6 +17,8 @@
// //
// Copyright holder is ArangoDB GmbH, Cologne, Germany // Copyright holder is ArangoDB GmbH, Cologne, Germany
// //
// Author Adam Janikowski
//
package features package features

View file

@ -17,6 +17,8 @@
// //
// Copyright holder is ArangoDB GmbH, Cologne, Germany // Copyright holder is ArangoDB GmbH, Cologne, Germany
// //
// Author Adam Janikowski
//
package features package features

View file

@ -17,6 +17,8 @@
// //
// Copyright holder is ArangoDB GmbH, Cologne, Germany // Copyright holder is ArangoDB GmbH, Cologne, Germany
// //
// Author Adam Janikowski
//
package features package features
@ -70,7 +72,7 @@ func Init(cmd *cobra.Command) {
if v != "" && feature.EnterpriseRequired() { if v != "" && feature.EnterpriseRequired() {
z = fmt.Sprintf("%s - Required version %s and Enterprise Edition", feature.Description(), v) z = fmt.Sprintf("%s - Required version %s and Enterprise Edition", feature.Description(), v)
} else if v != "" { } else if v != "" {
z = fmt.Sprintf("%s. Required version %s", feature.Description(), v) z = fmt.Sprintf("%s - Required version %s", feature.Description(), v)
} else if feature.EnterpriseRequired() { } else if feature.EnterpriseRequired() {
z = fmt.Sprintf("%s - Required Enterprise Edition", feature.Description()) z = fmt.Sprintf("%s - Required Enterprise Edition", feature.Description())
} else { } else {

View file

@ -0,0 +1,39 @@
//
// DISCLAIMER
//
// Copyright 2020 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
//
// Author Adam Janikowski
//
package features
func init() {
registerFeature(maintenance)
}
var maintenance = &feature{
name: "maintenance",
description: "Database maintenance mode management",
version: "3.5.0",
enterpriseRequired: false,
enabledByDefault: false,
}
func Maintenance() Feature {
return maintenance
}

View file

@ -17,6 +17,8 @@
// //
// Copyright holder is ArangoDB GmbH, Cologne, Germany // Copyright holder is ArangoDB GmbH, Cologne, Germany
// //
// Author Adam Janikowski
//
package features package features

View file

@ -17,6 +17,8 @@
// //
// Copyright holder is ArangoDB GmbH, Cologne, Germany // Copyright holder is ArangoDB GmbH, Cologne, Germany
// //
// Author Adam Janikowski
//
package reconcile package reconcile

View file

@ -17,6 +17,8 @@
// //
// Copyright holder is ArangoDB GmbH, Cologne, Germany // Copyright holder is ArangoDB GmbH, Cologne, Germany
// //
// Author Adam Janikowski
//
package reconcile package reconcile

View file

@ -0,0 +1,72 @@
//
// DISCLAIMER
//
// Copyright 2020 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
//
// Author Adam Janikowski
//
package reconcile
import (
"context"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/deployment/agency"
"github.com/rs/zerolog"
)
func init() {
registerAction(api.ActionTypeDisableMaintenance, newDisableMaintenanceAction)
}
func newDisableMaintenanceAction(log zerolog.Logger, action api.Action, actionCtx ActionContext) Action {
a := &actionDisableMaintenance{}
a.actionImpl = newActionImpl(log, action, actionCtx, addMemberTimeout, &a.newMemberID)
return a
}
type actionDisableMaintenance struct {
// actionImpl implement timeout and member id functions
actionImpl
actionEmptyCheckProgress
newMemberID string
}
func (a *actionDisableMaintenance) Start(ctx context.Context) (bool, error) {
switch a.actionCtx.GetMode() {
case api.DeploymentModeSingle:
return true, nil
}
client, err := a.actionCtx.GetDatabaseClient(ctx)
if err != nil {
a.log.Error().Err(err).Msgf("Unable to get agency client")
return true, nil
}
if err := agency.SetMaintenanceMode(ctx, client, false); err != nil {
a.log.Error().Err(err).Msgf("Unable to disable maintenance")
return true, nil
}
return true, nil
}

View file

@ -0,0 +1,72 @@
//
// DISCLAIMER
//
// Copyright 2020 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
//
// Author Adam Janikowski
//
package reconcile
import (
"context"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/deployment/agency"
"github.com/rs/zerolog"
)
func init() {
registerAction(api.ActionTypeEnableMaintenance, newEnableMaintenanceAction)
}
func newEnableMaintenanceAction(log zerolog.Logger, action api.Action, actionCtx ActionContext) Action {
a := &actionEnableMaintenance{}
a.actionImpl = newActionImpl(log, action, actionCtx, addMemberTimeout, &a.newMemberID)
return a
}
type actionEnableMaintenance struct {
// actionImpl implement timeout and member id functions
actionImpl
actionEmptyCheckProgress
newMemberID string
}
func (a *actionEnableMaintenance) Start(ctx context.Context) (bool, error) {
switch a.actionCtx.GetMode() {
case api.DeploymentModeSingle:
return true, nil
}
client, err := a.actionCtx.GetDatabaseClient(ctx)
if err != nil {
a.log.Error().Err(err).Msgf("Unable to get agency client")
return true, nil
}
if err := agency.SetMaintenanceMode(ctx, client, true); err != nil {
a.log.Error().Err(err).Msgf("Unable to set maintenance")
return true, nil
}
return true, nil
}

View file

@ -0,0 +1,44 @@
//
// DISCLAIMER
//
// Copyright 2020 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
//
// Author Adam Janikowski
//
package reconcile
import (
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/deployment/features"
)
func withMaintenance(plan ...api.Action) api.Plan {
if !features.Maintenance().Enabled() {
return plan
}
var newPlan api.Plan
newPlan = append(newPlan, api.NewAction(api.ActionTypeEnableMaintenance, api.ServerGroupUnknown, "", "Enable maintenance before actions"))
newPlan = append(newPlan, plan...)
newPlan = append(newPlan, api.NewAction(api.ActionTypeDisableMaintenance, api.ServerGroupUnknown, "", "Disable maintenance after actions"))
return newPlan
}

View file

@ -97,13 +97,7 @@ func fetchAgency(ctx context.Context, log zerolog.Logger,
agencyCtx, agencyCancel := goContext.WithTimeout(ctx, time.Minute) agencyCtx, agencyCancel := goContext.WithTimeout(ctx, time.Minute)
defer agencyCancel() defer agencyCancel()
ret := &agency.ArangoPlanDatabases{} return agency.GetAgencyCollections(agencyCtx, context.GetAgencyData)
if err := context.GetAgencyData(agencyCtx, cache, agency.ArangoKey, agency.PlanKey, agency.PlanCollectionsKey); err != nil {
return nil, err
}
return ret, nil
} else { } else {
return nil, fmt.Errorf("not able to read from agency when agency is down") return nil, fmt.Errorf("not able to read from agency when agency is down")
} }
@ -214,6 +208,10 @@ func createPlan(ctx context.Context, log zerolog.Logger, apiObject k8sutil.APIOb
plan = pb.Apply(createJWTStatusUpdate) plan = pb.Apply(createJWTStatusUpdate)
} }
if plan.IsEmpty() {
plan = pb.Apply(createMaintenanceManagementPlan)
}
// Check for scale up/down // Check for scale up/down
if plan.IsEmpty() { if plan.IsEmpty() {
plan = pb.Apply(createScaleMemeberPlan) plan = pb.Apply(createScaleMemeberPlan)

View file

@ -0,0 +1,72 @@
//
// DISCLAIMER
//
// Copyright 2020 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
//
// Author Adam Janikowski
//
package reconcile
import (
"context"
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
"github.com/arangodb/kube-arangodb/pkg/deployment/agency"
"github.com/arangodb/kube-arangodb/pkg/deployment/features"
"github.com/arangodb/kube-arangodb/pkg/deployment/resources/inspector"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
"github.com/rs/zerolog"
)
func createMaintenanceManagementPlan(ctx context.Context,
log zerolog.Logger, apiObject k8sutil.APIObject,
spec api.DeploymentSpec, status api.DeploymentStatus,
cachedStatus inspector.Inspector, context PlanBuilderContext) api.Plan {
if spec.Mode.Get() == api.DeploymentModeSingle {
return nil
}
if !features.Maintenance().Enabled() {
// Maintenance feature is not enabled
return nil
}
client, err := context.GetDatabaseClient(ctx)
if err != nil {
log.Error().Err(err).Msgf("Unable to get agency client")
return nil
}
m, err := agency.GetMaintenanceMode(ctx, client)
if err != nil {
log.Error().Err(err).Msgf("Unable to get agency maintenance mode")
return nil
}
if !m.Enabled() && spec.Database.GetMaintenance() {
log.Info().Msgf("Enabling maintenance mode")
return api.Plan{api.NewAction(api.ActionTypeEnableMaintenance, api.ServerGroupUnknown, "")}
}
if m.Enabled() && !spec.Database.GetMaintenance() {
log.Info().Msgf("Disabling maintenance mode")
return api.Plan{api.NewAction(api.ActionTypeEnableMaintenance, api.ServerGroupUnknown, "")}
}
return nil
}

View file

@ -25,6 +25,8 @@ package reconcile
import ( import (
"context" "context"
"github.com/arangodb/go-driver/agency"
"github.com/arangodb/kube-arangodb/pkg/deployment/resources/inspector" "github.com/arangodb/kube-arangodb/pkg/deployment/resources/inspector"
backupApi "github.com/arangodb/kube-arangodb/pkg/apis/backup/v1" backupApi "github.com/arangodb/kube-arangodb/pkg/apis/backup/v1"
@ -69,6 +71,8 @@ type PlanBuilderContext interface {
GetBackup(backup string) (*backupApi.ArangoBackup, error) GetBackup(backup string) (*backupApi.ArangoBackup, error)
// GetName receives deployment name // GetName receives deployment name
GetName() string 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 // newPlanBuilderContext creates a PlanBuilderContext from the given context

View file

@ -75,14 +75,25 @@ func createRestorePlan(ctx context.Context,
} }
} }
return api.Plan{ return restorePlan(spec.Mode.Get())
api.NewAction(api.ActionTypeBackupRestore, api.ServerGroupUnknown, ""),
}
} }
return nil return nil
} }
func restorePlan(mode api.DeploymentMode) api.Plan {
p := api.Plan{
api.NewAction(api.ActionTypeBackupRestore, api.ServerGroupUnknown, ""),
}
switch mode {
case api.DeploymentModeActiveFailover:
p = withMaintenance(p...)
}
return p
}
func createRestorePlanEncryption(ctx context.Context, log zerolog.Logger, spec api.DeploymentSpec, status api.DeploymentStatus, builderCtx PlanBuilderContext, backup *backupv1.ArangoBackup) (bool, api.Plan) { func createRestorePlanEncryption(ctx context.Context, log zerolog.Logger, spec api.DeploymentSpec, status api.DeploymentStatus, builderCtx PlanBuilderContext, backup *backupv1.ArangoBackup) (bool, api.Plan) {
if spec.RestoreEncryptionSecret != nil { if spec.RestoreEncryptionSecret != nil {
if !spec.RocksDB.IsEncrypted() { if !spec.RocksDB.IsEncrypted() {

View file

@ -17,6 +17,8 @@
// //
// Copyright holder is ArangoDB GmbH, Cologne, Germany // Copyright holder is ArangoDB GmbH, Cologne, Germany
// //
// Author Adam Janikowski
//
package resources package resources

View file

@ -17,6 +17,8 @@
// //
// Copyright holder is ArangoDB GmbH, Cologne, Germany // Copyright holder is ArangoDB GmbH, Cologne, Germany
// //
// Author Adam Janikowski
//
package resources package resources