Skip to content

Commit

Permalink
MAISTRA-2518 add conditions to federation status
Browse files Browse the repository at this point in the history
Signed-off-by: rcernich <[email protected]>
  • Loading branch information
rcernich committed Aug 18, 2021
1 parent 149e082 commit 9083414
Show file tree
Hide file tree
Showing 13 changed files with 468 additions and 6 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ module istio.io/istio

go 1.15

replace maistra.io/api => ../../maistra.io/api

// pin to v1.9.5
replace istio.io/api => github.com/istio/api v0.0.0-20210419172736-e076ff10ec38

Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1440,8 +1440,6 @@ k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
k8s.io/utils v0.0.0-20200912215256-4140de9c8800/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
maistra.io/api v0.0.0-20210726125459-3d5819d0bd1b h1:LLp9dJctk8s7WTgau8laV+29lc/lQ2cm5RIyZSDN3Cw=
maistra.io/api v0.0.0-20210726125459-3d5819d0bd1b/go.mod h1:lr+bFp/3PnYhRC/0IrDhCy7GfnQPhiOTW/CQ8qgTV9U=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,32 @@ spec:
type: object
status:
properties:
conditions:
description: Represents the latest available observations of a federation's current state.
items:
description: Condition describes the state of a federation at a certain point.
properties:
lastTransitionTime:
description: Last time the condition transitioned from one status to another.
format: date-time
type: string
message:
description: A human readable message indicating details about the transition.
type: string
reason:
description: The reason for the condition's last transition.
type: string
status:
description: Status of the condition, one of True, False, Unknown.
type: string
type:
description: Type of federation condition.
type: string
required:
- status
- type
type: object
type: array
exportedServices:
description: Exports provides details about the services exported by this mesh.
items:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,32 @@ spec:
type: object
status:
properties:
conditions:
description: Represents the latest available observations of a federation's current state.
items:
description: Condition describes the state of a federation at a certain point.
properties:
lastTransitionTime:
description: Last time the condition transitioned from one status to another.
format: date-time
type: string
message:
description: A human readable message indicating details about the transition.
type: string
reason:
description: The reason for the condition's last transition.
type: string
status:
description: Status of the condition, one of True, False, Unknown.
type: string
type:
description: Type of federation condition.
type: string
required:
- status
- type
type: object
type: array
importedServices:
description: Imports provides details about the services imported by this mesh.
items:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,32 @@ spec:
status:
description: ServiceMeshPeerStatus provides information related to the other mesh.
properties:
conditions:
description: Represents the latest available observations of a federation's current state.
items:
description: Condition describes the state of a federation at a certain point.
properties:
lastTransitionTime:
description: Last time the condition transitioned from one status to another.
format: date-time
type: string
message:
description: A human readable message indicating details about the transition.
type: string
reason:
description: The reason for the condition's last transition.
type: string
status:
description: Status of the condition, one of True, False, Unknown.
type: string
type:
description: Type of federation condition.
type: string
required:
- status
- type
type: object
type: array
discoveryStatus:
description: DiscoveryStatus represents the discovery status of each pilot/istiod pod in the mesh.
properties:
Expand Down
78 changes: 78 additions & 0 deletions manifests/charts/base/files/gen-istio-cluster.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3639,6 +3639,32 @@ spec:
type: object
status:
properties:
conditions:
description: Represents the latest available observations of a federation's current state.
items:
description: Condition describes the state of a federation at a certain point.
properties:
lastTransitionTime:
description: Last time the condition transitioned from one status to another.
format: date-time
type: string
message:
description: A human readable message indicating details about the transition.
type: string
reason:
description: The reason for the condition's last transition.
type: string
status:
description: Status of the condition, one of True, False, Unknown.
type: string
type:
description: Type of federation condition.
type: string
required:
- status
- type
type: object
type: array
exportedServices:
description: Exports provides details about the services exported by this mesh.
items:
Expand Down Expand Up @@ -3776,6 +3802,32 @@ spec:
type: object
status:
properties:
conditions:
description: Represents the latest available observations of a federation's current state.
items:
description: Condition describes the state of a federation at a certain point.
properties:
lastTransitionTime:
description: Last time the condition transitioned from one status to another.
format: date-time
type: string
message:
description: A human readable message indicating details about the transition.
type: string
reason:
description: The reason for the condition's last transition.
type: string
status:
description: Status of the condition, one of True, False, Unknown.
type: string
type:
description: Type of federation condition.
type: string
required:
- status
- type
type: object
type: array
importedServices:
description: Imports provides details about the services imported by this mesh.
items:
Expand Down Expand Up @@ -3929,6 +3981,32 @@ spec:
status:
description: ServiceMeshPeerStatus provides information related to the other mesh.
properties:
conditions:
description: Represents the latest available observations of a federation's current state.
items:
description: Condition describes the state of a federation at a certain point.
properties:
lastTransitionTime:
description: Last time the condition transitioned from one status to another.
format: date-time
type: string
message:
description: A human readable message indicating details about the transition.
type: string
reason:
description: The reason for the condition's last transition.
type: string
status:
description: Status of the condition, one of True, False, Unknown.
type: string
type:
description: Type of federation condition.
type: string
required:
- status
- type
type: object
type: array
discoveryStatus:
description: DiscoveryStatus represents the discovery status of each pilot/istiod pod in the mesh.
properties:
Expand Down
125 changes: 122 additions & 3 deletions pkg/servicemesh/federation/status/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ package status
import (
"context"
"encoding/json"
"fmt"
"reflect"
"sort"
"strings"
"sync"
"time"

corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
Expand Down Expand Up @@ -448,7 +450,7 @@ func (h *handler) Flush() error {
return err
}
oldStatus := mf.Status.DeepCopy()
newStatus := &v1.ServiceMeshPeerStatus{}
newStatus := &v1.ServiceMeshPeerStatus{StatusConditions: *oldStatus.StatusConditions.DeepCopy()}

newStatus.DiscoveryStatus = oldStatus.DeepCopy().DiscoveryStatus
if h.discoveryStatus.Watch.Connected {
Expand All @@ -472,6 +474,8 @@ func (h *handler) Flush() error {
}
}

h.updateConditions(newStatus)

// XXX: the created patch does not merge properly and can cause duplicate entries in discovery status
patch, err := h.createPatch(&v1.ServiceMeshPeer{Status: *newStatus}, &v1.ServiceMeshPeer{Status: *oldStatus}, peerStatusPatchMetadata)
if err != nil {
Expand All @@ -494,6 +498,77 @@ func (h *handler) Flush() error {
return utilerrors.NewAggregate(allErrors)
}

func (h *handler) updateConditions(status *v1.ServiceMeshPeerStatus) {
connected, degradedMessage, servingCount, ready := func() (bool, string, int, bool) {
activeConnections := len(status.DiscoveryStatus.Active)
inactiveConnections := len(status.DiscoveryStatus.Inactive)
var degradedMessage string
if inactiveConnections > 0 {
degradedMessage = fmt.Sprintf("%d of %d connections are inactive", inactiveConnections, inactiveConnections+activeConnections)
}
servingCount := 0
for _, details := range status.DiscoveryStatus.Active {
for _, remote := range details.Remotes {
if remote.Connected {
servingCount++
}
}
}
for _, details := range status.DiscoveryStatus.Inactive {
for _, remote := range details.Remotes {
if remote.Connected {
servingCount++
}
}
}
return inactiveConnections == 0, degradedMessage, servingCount, degradedMessage == ""
}()

connectedCondition := v1.Condition{Type: v1.ConnectedServiceMeshPeerCondition}
if connected {
connectedCondition.Reason = "Connected"
connectedCondition.Status = corev1.ConditionTrue
} else {
connectedCondition.Reason = "NotConnected"
connectedCondition.Status = corev1.ConditionFalse
}
status.SetCondition(connectedCondition)

degradedCondition := v1.Condition{Type: v1.DegradedServiceMeshPeerCondition}
if degradedMessage == "" || !connected {
degradedCondition.Reason = v1.NotDegradedConditionReason
degradedCondition.Status = corev1.ConditionFalse
degradedCondition.Message = ""
} else {
degradedCondition.Reason = v1.DegradedConditionReason
degradedCondition.Status = corev1.ConditionTrue
degradedCondition.Message = degradedMessage
}
status.SetCondition(degradedCondition)

servingCondition := v1.Condition{Type: v1.ServingServiceMeshPeerCondition}
if servingCount == 0 {
servingCondition.Reason = v1.NotServingConditionReason
servingCondition.Message = fmt.Sprintf("no connections from peer '%s'", h.mesh.Name)
servingCondition.Status = corev1.ConditionFalse
} else {
servingCondition.Reason = v1.ServingConditionReason
servingCondition.Message = fmt.Sprintf("servicing %d connections from peer '%s'", servingCount, h.mesh.Name)
servingCondition.Status = corev1.ConditionTrue
}
status.SetCondition(servingCondition)

readyCondition := v1.Condition{Type: v1.ReadyServiceMeshPeerCondition, Message: degradedMessage}
if ready {
readyCondition.Reason = v1.ReadyConditionReason
readyCondition.Status = corev1.ConditionTrue
} else {
readyCondition.Reason = v1.NotReadyConditionReason
readyCondition.Status = corev1.ConditionFalse
}
status.SetCondition(readyCondition)
}

func (h *handler) patchExports() error {
exportSet, err := h.manager.rm.ExportsInformer().Lister().ExportedServiceSets(h.mesh.Namespace).Get(h.mesh.Name)
if err != nil {
Expand All @@ -504,7 +579,22 @@ func (h *handler) patchExports() error {
return err
}

patch, err := h.createPatch(&v1.ExportedServiceSet{Status: v1.ExportedServiceSetStatus{ExportedServices: h.exportsStatus}},
newStatus := exportSet.Status.DeepCopy()
condition := v1.Condition{Type: v1.ExportingExportedServiceSetCondition}
if len(h.exportsStatus) > 0 {
condition.Status = corev1.ConditionTrue
condition.Reason = v1.ExportingConditionReason
} else {
condition.Status = corev1.ConditionFalse
if len(exportSet.Spec.ExportRules) > 0 {
condition.Reason = v1.NoRulesMatchedConditionReason
} else {
condition.Reason = v1.NoRulesDefinedConditionReason
}
}
newStatus.SetCondition(condition)
newStatus.ExportedServices = h.exportsStatus
patch, err := h.createPatch(&v1.ExportedServiceSet{Status: *newStatus},
&v1.ExportedServiceSet{Status: exportSet.DeepCopy().Status}, exportStatusPatchMetadata)
if err != nil {
return err
Expand Down Expand Up @@ -535,7 +625,36 @@ func (h *handler) patchImports() error {
return err
}

patch, err := h.createPatch(&v1.ImportedServiceSet{Status: v1.ImportedServiceSetStatus{ImportedServices: h.importsStatus}},
newStatus := importSet.Status.DeepCopy()
condition := v1.Condition{Type: v1.ImportingImportedServiceSetCondition}
hasImportsAvailable, isImportingServices := func() (bool, bool) {
importsAvailable := false
for _, service := range h.importsStatus {
importsAvailable = true
if service.LocalService.Name != "" {
return importsAvailable, true
}
}
return importsAvailable, false
}()
if isImportingServices {
condition.Status = corev1.ConditionTrue
condition.Reason = v1.ImportingConditionReason
} else {
condition.Status = corev1.ConditionFalse
if hasImportsAvailable {
if len(importSet.Spec.ImportRules) > 0 {
condition.Reason = v1.NoRulesMatchedConditionReason
} else {
condition.Reason = v1.NoRulesDefinedConditionReason
}
} else {
condition.Reason = v1.NoExportedServicesConditionReason
}
}
newStatus.SetCondition(condition)
newStatus.ImportedServices = h.importsStatus
patch, err := h.createPatch(&v1.ImportedServiceSet{Status: *newStatus},
&v1.ImportedServiceSet{Status: importSet.DeepCopy().Status}, importStatusPatchMetadata)
if err != nil {
return err
Expand Down

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

Loading

0 comments on commit 9083414

Please sign in to comment.