Skip to content

Commit 99770ce

Browse files
authored
[Feature] Add UpToDate Condition (#540)
1 parent fd8e98a commit 99770ce

33 files changed

+642
-562
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Change Log
22

33
## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A)
4+
- Added UpToDate condition in ArangoDeployment Status
45

56
## [1.0.1](https://github.com/arangodb/kube-arangodb/tree/1.0.1) (2020-03-25)
67
- Added Customizable Affinity settings for ArangoDB Member Pods

pkg/apis/deployment/v1/conditions.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ const (
5959
ConditionTypeBootstrapSucceded ConditionType = "BootstrapSucceded"
6060
// ConditionTypeTerminating indicates that the member is terminating but not yet terminated.
6161
ConditionTypeTerminating ConditionType = "Terminating"
62+
// ConditionTypeTerminating indicates that the deployment is up to date.
63+
ConditionTypeUpToDate ConditionType = "UpToDate"
6264
)
6365

6466
// Condition represents one current condition of a deployment or deployment member.
@@ -79,6 +81,10 @@ type Condition struct {
7981
Message string `json:"message,omitempty"`
8082
}
8183

84+
func (c Condition) IsTrue() bool {
85+
return c.Status == v1.ConditionTrue
86+
}
87+
8288
// ConditionList is a list of conditions.
8389
// Each type is allowed only once.
8490
type ConditionList []Condition
@@ -116,12 +122,17 @@ func (c Condition) Equal(other Condition) bool {
116122
// IsTrue return true when a condition with given type exists and its status is `True`.
117123
func (list ConditionList) IsTrue(conditionType ConditionType) bool {
118124
c, found := list.Get(conditionType)
119-
return found && c.Status == v1.ConditionTrue
125+
return found && c.IsTrue()
120126
}
121127

122128
// Get a condition by type.
123129
// Returns true if found, false if not found.
124130
func (list ConditionList) Get(conditionType ConditionType) (Condition, bool) {
131+
// Covers nil and empty lists
132+
if len(list) == 0 {
133+
return Condition{}, false
134+
}
135+
125136
for _, x := range list {
126137
if x.Type == conditionType {
127138
return x, true

pkg/apis/deployment/v1/deployment.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,13 @@ func (d *ArangoDeployment) ForeachServerGroup(cb ServerGroupFunc, status *Deploy
9393
}
9494
return nil
9595
}
96+
97+
// IsUpToDate checks if applied version match current version in spec
98+
func (d ArangoDeployment) IsUpToDate() (bool, error) {
99+
sha, err := d.Spec.Checksum()
100+
if err != nil {
101+
return false, err
102+
}
103+
104+
return sha == d.Status.AppliedVersion && d.Status.Conditions.IsTrue(ConditionTypeUpToDate), nil
105+
}

pkg/apis/deployment/v1/deployment_spec.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
package v1
2424

2525
import (
26+
"crypto/sha256"
27+
"encoding/json"
28+
"fmt"
2629
"reflect"
2730

2831
"github.com/arangodb/kube-arangodb/pkg/util"
@@ -413,3 +416,13 @@ func (s DeploymentSpec) ResetImmutableFields(target *DeploymentSpec) []string {
413416
}
414417
return resetFields
415418
}
419+
420+
// Checksum return checksum of current ArangoDeployment Spec section
421+
func (s DeploymentSpec) Checksum() (string, error) {
422+
data, err := json.Marshal(s)
423+
if err != nil {
424+
return "", err
425+
}
426+
427+
return fmt.Sprintf("%0x", sha256.Sum256(data)), nil
428+
}

pkg/apis/deployment/v1/deployment_status.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ type DeploymentStatus struct {
3333
// Reason contains a human readable reason for reaching the current state (can be empty)
3434
Reason string `json:"reason,omitempty"` // Reason for current state
3535

36+
// AppliedVersion defines checksum of applied spec
37+
AppliedVersion string `json:"appliedVersion"`
38+
3639
// ServiceName holds the name of the Service a client can use (inside the k8s cluster)
3740
// to access ArangoDB.
3841
ServiceName string `json:"serviceName,omitempty"`

pkg/apis/deployment/v1/plan.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ package v1
2525
import (
2626
"github.com/arangodb/kube-arangodb/pkg/util"
2727
"github.com/dchest/uniuri"
28+
"k8s.io/apimachinery/pkg/api/equality"
2829
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2930
)
3031

@@ -66,6 +67,8 @@ const (
6667
ActionTypePVCResize ActionType = "PVCResize"
6768
// ActionTypePVCResized waits for PVC to resize for defined time
6869
ActionTypePVCResized ActionType = "PVCResized"
70+
// UpToDateUpdateResized define up to date annotation in spec
71+
UpToDateUpdate ActionType = "UpToDateUpdate"
6972
)
7073

7174
const (
@@ -92,6 +95,8 @@ type Action struct {
9295
Reason string `json:"reason,omitempty"`
9396
// Image used in can of a SetCurrentImage action.
9497
Image string `json:"image,omitempty"`
98+
// Params additional parameters used for action
99+
Params map[string]interface{} `json:"params,omitempty"`
95100
}
96101

97102
// Equal compares two Actions
@@ -103,7 +108,30 @@ func (a Action) Equal(other Action) bool {
103108
util.TimeCompareEqual(a.CreationTime, other.CreationTime) &&
104109
util.TimeCompareEqualPointer(a.StartTime, other.StartTime) &&
105110
a.Reason == other.Reason &&
106-
a.Image == other.Image
111+
a.Image == other.Image &&
112+
equality.Semantic.DeepEqual(a.Params, other.Params)
113+
}
114+
115+
// AddParam returns copy of action with set parameter
116+
func (a Action) AddParam(key string, value interface{}) Action {
117+
if a.Params == nil {
118+
a.Params = map[string]interface{}{}
119+
}
120+
121+
a.Params[key] = value
122+
123+
return a
124+
}
125+
126+
// GetParam returns action parameter
127+
func (a Action) GetParam(key string) (interface{}, bool) {
128+
if a.Params == nil {
129+
return nil, false
130+
}
131+
132+
i, ok := a.Params[key]
133+
134+
return i, ok
107135
}
108136

109137
// NewAction instantiates a new Action.

pkg/deployment/context_impl.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ func (d *Deployment) GetStatus() (api.DeploymentStatus, int32) {
103103
d.status.mutex.Lock()
104104
defer d.status.mutex.Unlock()
105105

106+
return d.getStatus()
107+
}
108+
109+
func (d *Deployment) getStatus() (api.DeploymentStatus, int32) {
106110
version := d.status.version
107111
return *d.status.last.DeepCopy(), version
108112
}
@@ -115,6 +119,10 @@ func (d *Deployment) UpdateStatus(status api.DeploymentStatus, lastVersion int32
115119
d.status.mutex.Lock()
116120
defer d.status.mutex.Unlock()
117121

122+
return d.updateStatus(status, lastVersion, force...)
123+
}
124+
125+
func (d *Deployment) updateStatus(status api.DeploymentStatus, lastVersion int32, force ...bool) error {
118126
if d.status.version != lastVersion {
119127
// Status is obsolete
120128
d.deps.Log.Error().
@@ -483,3 +491,18 @@ func (d *Deployment) GetMetricsExporterImage() string {
483491
func (d *Deployment) GetArangoImage() string {
484492
return d.config.ArangoImage
485493
}
494+
495+
func (d *Deployment) WithStatusUpdate(action func(s *api.DeploymentStatus) bool, force ...bool) error {
496+
d.status.mutex.Lock()
497+
defer d.status.mutex.Unlock()
498+
499+
status, version := d.getStatus()
500+
501+
changed := action(&status)
502+
503+
if !changed {
504+
return nil
505+
}
506+
507+
return d.updateStatus(status, version, force...)
508+
}

0 commit comments

Comments
 (0)