Skip to content

Commit

Permalink
use unified HCO conditions
Browse files Browse the repository at this point in the history
Use common library to handle conditions in order to integrate with
proposed HCO design.

Signed-off-by: Petr Horacek <[email protected]>
  • Loading branch information
phoracek committed Aug 5, 2019
1 parent 75c1831 commit 0798a52
Show file tree
Hide file tree
Showing 19 changed files with 453 additions and 201 deletions.
9 changes: 9 additions & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ kubectl apply -f https://raw.githubusercontent.com/kubevirt/cluster-network-addo
Finally you can wait for the operator to finish deployment:

```shell
kubectl wait networkaddonsconfig cluster --for condition=Ready
kubectl wait networkaddonsconfig cluster --for condition=Available
```

In case something failed, you can find the error in the NetworkAddonsConfig Status field:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package v1alpha1

import (
conditionsv1 "github.com/openshift/custom-resource-status/conditions/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
Expand Down Expand Up @@ -44,36 +45,10 @@ type NetworkAddonsConfigStatus struct {
OperatorVersion string `json:"operatorVersion,omitempty"`
ObservedVersion string `json:"observedVersion,omitempty"`
TargetVersion string `json:"targetVersion,omitempty"`
Conditions []NetworkAddonsCondition `json:"conditions,omitempty" optional:"true"`
Conditions []conditionsv1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
Containers []Container `json:"containers,omitempty"`
}

// NetworkAddonsCondition represents a condition of a NetworkAddons deployment
// ---
// +k8s:openapi-gen=true
type NetworkAddonsCondition struct {
Type NetworkAddonsConditionType `json:"type"`
Status corev1.ConditionStatus `json:"status"`
LastProbeTime metav1.Time `json:"lastProbeTime,omitempty"`
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
Reason string `json:"reason,omitempty"`
Message string `json:"message,omitempty"`
}

// ---
// +k8s:openapi-gen=true
type NetworkAddonsConditionType string

// These are the valid NetworkAddons condition types
const (
// Whether operator failed during deployment
NetworkAddonsConditionFailing NetworkAddonsConditionType = "Failing"
// Whether is the deployment progressing
NetworkAddonsConditionProgressing NetworkAddonsConditionType = "Progressing"
// Whether all components were ready
NetworkAddonsConditionAvailable NetworkAddonsConditionType = "Ready"
)

type Container struct {
Namespace string `json:"namespace"`
ParentKind string `json:"parentKind"`
Expand Down
21 changes: 2 additions & 19 deletions pkg/apis/networkaddonsoperator/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

89 changes: 19 additions & 70 deletions pkg/controller/statusmanager/status_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strings"
"time"

conditionsv1 "github.com/openshift/custom-resource-status/conditions/v1"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -47,7 +48,7 @@ type StatusManager struct {
client client.Client
name string

failing [maxStatusLevel]*opv1alpha1.NetworkAddonsCondition
failing [maxStatusLevel]*conditionsv1.Condition

daemonSets []types.NamespacedName
deployments []types.NamespacedName
Expand All @@ -64,7 +65,7 @@ func New(client client.Client, name string) *StatusManager {
// the status, calling set is tried several times.
// TODO: Calling of Patch instead may save some problems. We can reiterate later,
// current collision problem is detected by functional tests
func (status *StatusManager) Set(reachedAvailableLevel bool, conditions ...opv1alpha1.NetworkAddonsCondition) {
func (status *StatusManager) Set(reachedAvailableLevel bool, conditions ...conditionsv1.Condition) {
for i := 0; i < conditionsUpdateRetries; i++ {
err := status.set(reachedAvailableLevel, conditions...)
if err == nil {
Expand All @@ -78,7 +79,7 @@ func (status *StatusManager) Set(reachedAvailableLevel bool, conditions ...opv1a
}

// set updates the NetworkAddonsConfig.Status with the provided conditions
func (status *StatusManager) set(reachedAvailableLevel bool, conditions ...opv1alpha1.NetworkAddonsCondition) error {
func (status *StatusManager) set(reachedAvailableLevel bool, conditions ...conditionsv1.Condition) error {
// Read the current NetworkAddonsConfig
config := &opv1alpha1.NetworkAddonsConfig{ObjectMeta: metav1.ObjectMeta{Name: status.name}}
err := status.client.Get(context.TODO(), types.NamespacedName{Name: status.name}, config)
Expand All @@ -91,7 +92,7 @@ func (status *StatusManager) set(reachedAvailableLevel bool, conditions ...opv1a

// Update Status field with given conditions
for _, condition := range conditions {
updateCondition(&config.Status, condition)
conditionsv1.SetStatusCondition(&config.Status.Conditions, condition)
}

config.Status.OperatorVersion = operatorVersion
Expand All @@ -103,11 +104,10 @@ func (status *StatusManager) set(reachedAvailableLevel bool, conditions ...opv1a

// In case that the status field has been updated with "Progressing" condition, make sure that
// "Ready" condition is set to False, even when not explicitly set.
progressingCondition := getCondition(&config.Status, opv1alpha1.NetworkAddonsConditionProgressing)
if progressingCondition != nil && progressingCondition.Status == corev1.ConditionTrue {
updateCondition(&config.Status,
opv1alpha1.NetworkAddonsCondition{
Type: opv1alpha1.NetworkAddonsConditionAvailable,
if conditionsv1.IsStatusConditionTrue(config.Status.Conditions, conditionsv1.ConditionProgressing) {
conditionsv1.SetStatusCondition(&config.Status.Conditions,
conditionsv1.Condition{
Type: conditionsv1.ConditionAvailable,
Status: corev1.ConditionFalse,
Reason: "Startup",
Message: "Configuration is in process",
Expand Down Expand Up @@ -141,8 +141,8 @@ func (status *StatusManager) syncFailing() {
}
status.Set(
false,
opv1alpha1.NetworkAddonsCondition{
Type: opv1alpha1.NetworkAddonsConditionFailing,
conditionsv1.Condition{
Type: conditionsv1.ConditionDegraded,
Status: corev1.ConditionFalse,
},
)
Expand All @@ -151,8 +151,8 @@ func (status *StatusManager) syncFailing() {
// SetFailing marks the operator as Failing with the given reason and message. If it
// is not already failing for a lower-level reason, the operator's status will be updated.
func (status *StatusManager) SetFailing(level StatusLevel, reason, message string) {
status.failing[level] = &opv1alpha1.NetworkAddonsCondition{
Type: opv1alpha1.NetworkAddonsConditionFailing,
status.failing[level] = &conditionsv1.Condition{
Type: conditionsv1.ConditionDegraded,
Status: corev1.ConditionTrue,
Reason: reason,
Message: message,
Expand Down Expand Up @@ -272,8 +272,8 @@ func (status *StatusManager) SetFromPods() {
if len(progressing) > 0 {
status.Set(
false,
opv1alpha1.NetworkAddonsCondition{
Type: opv1alpha1.NetworkAddonsConditionProgressing,
conditionsv1.Condition{
Type: conditionsv1.ConditionProgressing,
Status: corev1.ConditionTrue,
Reason: "Deploying",
Message: strings.Join(progressing, "\n"),
Expand All @@ -282,12 +282,12 @@ func (status *StatusManager) SetFromPods() {
} else {
status.Set(
true,
opv1alpha1.NetworkAddonsCondition{
Type: opv1alpha1.NetworkAddonsConditionProgressing,
conditionsv1.Condition{
Type: conditionsv1.ConditionProgressing,
Status: corev1.ConditionFalse,
},
opv1alpha1.NetworkAddonsCondition{
Type: opv1alpha1.NetworkAddonsConditionAvailable,
conditionsv1.Condition{
Type: conditionsv1.ConditionAvailable,
Status: corev1.ConditionTrue,
},
)
Expand All @@ -297,57 +297,6 @@ func (status *StatusManager) SetFromPods() {
status.SetNotFailing(PodDeployment)
}

// Set condition in the Status field. In case condition with given Type already exists, update it.
// This function also takes care of setting timestamps of LastProbeTime and LastTransitionTime.
func updateCondition(status *opv1alpha1.NetworkAddonsConfigStatus, condition opv1alpha1.NetworkAddonsCondition) {
originalCondition := getCondition(status, condition.Type)

// Check whether the condition is to be added or updated
isNew := originalCondition == nil

// Check whether there are any changes compared to the original condition
transition := (!isNew && (condition.Status != originalCondition.Status || condition.Reason != originalCondition.Reason || condition.Message != originalCondition.Message))

// Update Condition's timestamps
now := time.Now()

// LastProbeTime indicates the last time the condition has been checked
condition.LastProbeTime = metav1.Time{
Time: now,
}

// LastTransitionTime indicates the last time the condition has been changed or it has been added
if isNew || transition {
condition.LastTransitionTime = metav1.Time{
Time: now,
}
} else {
condition.LastTransitionTime = originalCondition.LastTransitionTime
}

// Update or add desired condition to the Status field
if isNew {
status.Conditions = append(status.Conditions, condition)
} else {
for i := range status.Conditions {
if status.Conditions[i].Type == condition.Type {
status.Conditions[i] = condition
break
}
}
}
}

// Get conditition of given type from NetworkAddonsConfig.Status
func getCondition(status *opv1alpha1.NetworkAddonsConfigStatus, conditionType opv1alpha1.NetworkAddonsConditionType) *opv1alpha1.NetworkAddonsCondition {
for _, condition := range status.Conditions {
if condition.Type == conditionType {
return &condition
}
}
return nil
}

func (status *StatusManager) SetContainers(containers []opv1alpha1.Container) {
status.containers = containers
}
46 changes: 0 additions & 46 deletions pkg/controller/statusmanager/status_manager_test.go

This file was deleted.

13 changes: 0 additions & 13 deletions pkg/controller/statusmanager/statusmanager_suite_test.go

This file was deleted.

3 changes: 2 additions & 1 deletion test/check/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
conditionsv1 "github.com/openshift/custom-resource-status/conditions/v1"
securityapi "github.com/openshift/origin/pkg/security/apis/security"
framework "github.com/operator-framework/operator-sdk/pkg/test"
"gopkg.in/yaml.v2"
Expand Down Expand Up @@ -396,7 +397,7 @@ func isNotFound(componentType string, componentName string, clientGetOutput erro

func checkConfigCondition(conf *opv1alpha1.NetworkAddonsConfig, conditionType ConditionType, conditionStatus ConditionStatus) error {
for _, condition := range conf.Status.Conditions {
if condition.Type == opv1alpha1.NetworkAddonsConditionType(conditionType) {
if condition.Type == conditionsv1.ConditionType(conditionType) {
if condition.Status == corev1.ConditionStatus(conditionStatus) {
return nil
}
Expand Down
11 changes: 5 additions & 6 deletions test/check/conditions.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
package check

import (
conditionsv1 "github.com/openshift/custom-resource-status/conditions/v1"
corev1 "k8s.io/api/core/v1"

opv1alpha1 "github.com/kubevirt/cluster-network-addons-operator/pkg/apis/networkaddonsoperator/v1alpha1"
)

type ConditionType opv1alpha1.NetworkAddonsConditionType
type ConditionType conditionsv1.ConditionType

type ConditionStatus corev1.ConditionStatus

const (
ConditionAvailable = ConditionType(opv1alpha1.NetworkAddonsConditionAvailable)
ConditionProgressing = ConditionType(opv1alpha1.NetworkAddonsConditionProgressing)
ConditionFailing = ConditionType(opv1alpha1.NetworkAddonsConditionFailing)
ConditionAvailable = ConditionType(conditionsv1.ConditionAvailable)
ConditionProgressing = ConditionType(conditionsv1.ConditionProgressing)
ConditionDegraded = ConditionType(conditionsv1.ConditionDegraded)

ConditionTrue = ConditionStatus(corev1.ConditionTrue)
ConditionFalse = ConditionStatus(corev1.ConditionFalse)
Expand Down
Loading

0 comments on commit 0798a52

Please sign in to comment.