Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port warning #560

Merged
merged 3 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions api/v1/runtimecomponent_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,7 @@ const (
StatusConditionTypeReconciled StatusConditionType = "Reconciled"
StatusConditionTypeResourcesReady StatusConditionType = "ResourcesReady"
StatusConditionTypeReady StatusConditionType = "Ready"
StatusConditionTypeWarning StatusConditionType = "Warning"

// Status Endpoint Scopes
StatusEndpointScopeExternal StatusEndpointScope = "External"
Expand All @@ -462,6 +463,9 @@ type StatusVersions struct {
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status",priority=0,description="Status of the component ready condition"
// +kubebuilder:printcolumn:name="ReadyReason",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].reason",priority=1,description="Reason for the failure of component ready condition"
// +kubebuilder:printcolumn:name="ReadyMessage",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].message",priority=1,description="Failure message from component ready condition"
// +kubebuilder:printcolumn:name="Warning",type="string",JSONPath=".status.conditions[?(@.type=='Warning')].status",priority=0,description="Status of the component warning condition"
// +kubebuilder:printcolumn:name="WarningReason",type="string",JSONPath=".status.conditions[?(@.type=='Warning')].reason",priority=1,description="Reason for the failure of component warning condition"
// +kubebuilder:printcolumn:name="WarningMessage",type="string",JSONPath=".status.conditions[?(@.type=='Warning')].message",priority=1,description="Failure message from component warning condition"
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",priority=0,description="Age of the resource"
// +operator-sdk:csv:customresourcedefinitions:displayName="RuntimeComponent",resources={{Deployment,v1},{Service,v1},{StatefulSet,v1},{Route,v1},{HorizontalPodAutoscaler,v1},{ServiceAccount,v1},{Secret,v1},{NetworkPolicy,v1}}

Expand Down Expand Up @@ -1140,6 +1144,22 @@ func (s *RuntimeComponentStatus) SetCondition(c common.StatusCondition) {
}
}

func (s *RuntimeComponentStatus) UnsetCondition(c common.StatusCondition) {
for i := range s.Conditions {
if s.Conditions[i].GetType() == c.GetType() {
// Found the condition to remove
if i+1 == len(s.Conditions) {
// the match is the last element, can just shorten by one
s.Conditions = s.Conditions[:i]
} else {
// there are more elements after the match.
s.Conditions = append(s.Conditions[:i], s.Conditions[i+1])
}
return
}
}
}

func (s *RuntimeComponentStatus) GetReferences() common.StatusReferences {
if s.References == nil {
s.References = make(common.StatusReferences)
Expand All @@ -1166,6 +1186,8 @@ func convertToCommonStatusConditionType(c StatusConditionType) common.StatusCond
return common.StatusConditionTypeResourcesReady
case StatusConditionTypeReady:
return common.StatusConditionTypeReady
case StatusConditionTypeWarning:
return common.StatusConditionTypeWarning
default:
panic(c)
}
Expand All @@ -1179,6 +1201,8 @@ func convertFromCommonStatusConditionType(c common.StatusConditionType) StatusCo
return StatusConditionTypeResourcesReady
case common.StatusConditionTypeReady:
return StatusConditionTypeReady
case common.StatusConditionTypeWarning:
return StatusConditionTypeWarning
default:
panic(c)
}
Expand Down
4 changes: 4 additions & 0 deletions api/v1beta2/runtimecomponent_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,10 @@ func (s *RuntimeComponentStatus) GetCondition(t common.StatusConditionType) comm
}
return nil
}
func (s *RuntimeComponentStatus) UnsetCondition(c common.StatusCondition) {
// Intentional dummy
return
}

// SetCondition ...
func (s *RuntimeComponentStatus) SetCondition(c common.StatusCondition) {
Expand Down
14 changes: 14 additions & 0 deletions bundle/manifests/rc.app.stacks_runtimecomponents.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,20 @@ spec:
name: ReadyMessage
priority: 1
type: string
- description: Status of the component warning condition
jsonPath: .status.conditions[?(@.type=='Warning')].status
name: Warning
type: string
- description: Reason for the failure of component warning condition
jsonPath: .status.conditions[?(@.type=='Warning')].reason
name: WarningReason
priority: 1
type: string
- description: Failure message from component warning condition
jsonPath: .status.conditions[?(@.type=='Warning')].message
name: WarningMessage
priority: 1
type: string
- description: Age of the resource
jsonPath: .metadata.creationTimestamp
name: Age
Expand Down
2 changes: 2 additions & 0 deletions common/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ type BaseComponentStatus interface {
GetConditions() []StatusCondition
GetCondition(StatusConditionType) StatusCondition
SetCondition(StatusCondition)
UnsetCondition(StatusCondition)
NewCondition(StatusConditionType) StatusCondition

GetStatusEndpoint(string) StatusEndpoint
Expand All @@ -89,6 +90,7 @@ const (
StatusConditionTypeReconciled StatusConditionType = "Reconciled"
StatusConditionTypeResourcesReady StatusConditionType = "ResourcesReady"
StatusConditionTypeReady StatusConditionType = "Ready"
StatusConditionTypeWarning StatusConditionType = "Warning"

// Status Condition Type Messages
StatusConditionTypeReadyMessage string = "Application is reconciled and resources are ready."
Expand Down
14 changes: 14 additions & 0 deletions config/crd/bases/rc.app.stacks_runtimecomponents.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,20 @@ spec:
name: ReadyMessage
priority: 1
type: string
- description: Status of the component warning condition
jsonPath: .status.conditions[?(@.type=='Warning')].status
name: Warning
type: string
- description: Reason for the failure of component warning condition
jsonPath: .status.conditions[?(@.type=='Warning')].reason
name: WarningReason
priority: 1
type: string
- description: Failure message from component warning condition
jsonPath: .status.conditions[?(@.type=='Warning')].message
name: WarningMessage
priority: 1
type: string
- description: Age of the resource
jsonPath: .metadata.creationTimestamp
name: Age
Expand Down
14 changes: 14 additions & 0 deletions internal/deploy/kubectl/runtime-component-crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,20 @@ spec:
name: ReadyMessage
priority: 1
type: string
- description: Status of the component warning condition
jsonPath: .status.conditions[?(@.type=='Warning')].status
name: Warning
type: string
- description: Reason for the failure of component warning condition
jsonPath: .status.conditions[?(@.type=='Warning')].reason
name: WarningReason
priority: 1
type: string
- description: Failure message from component warning condition
jsonPath: .status.conditions[?(@.type=='Warning')].message
name: WarningMessage
priority: 1
type: string
- description: Age of the resource
jsonPath: .metadata.creationTimestamp
name: Age
Expand Down
14 changes: 14 additions & 0 deletions internal/deploy/kustomize/daily/base/runtime-component-crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,20 @@ spec:
name: ReadyMessage
priority: 1
type: string
- description: Status of the component warning condition
jsonPath: .status.conditions[?(@.type=='Warning')].status
name: Warning
type: string
- description: Reason for the failure of component warning condition
jsonPath: .status.conditions[?(@.type=='Warning')].reason
name: WarningReason
priority: 1
type: string
- description: Failure message from component warning condition
jsonPath: .status.conditions[?(@.type=='Warning')].message
name: WarningMessage
priority: 1
type: string
- description: Age of the resource
jsonPath: .metadata.creationTimestamp
name: Age
Expand Down
27 changes: 27 additions & 0 deletions utils/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,29 @@ func (r *ReconcilerBase) GetOpConfigMap(name string, ns string) (*corev1.ConfigM
return configMap, nil
}

func addStatusWarnings(ba common.BaseComponent) {

s := ba.GetStatus()

mtls := ba.GetManageTLS()
svc := ba.GetService()
if (mtls == nil || *mtls == true) && svc != nil && svc.GetPort() == 9080 {
status := corev1.ConditionTrue
msg := "ManageTLS is true but port is set to 9080"
statusCondition := s.NewCondition(common.StatusConditionTypeWarning)
statusCondition.SetReason("")
statusCondition.SetMessage(msg)
statusCondition.SetStatus(status)
s.SetCondition(statusCondition)
} else {
// The warning condition may previously have been set, but is now not needed.
// Removing the warning is clearer than have a warning condition set to 'false'
statusCondition := s.NewCondition(common.StatusConditionTypeWarning)
s.UnsetCondition(statusCondition)
}

}

// ManageError ...
func (r *ReconcilerBase) ManageError(issue error, conditionType common.StatusConditionType, ba common.BaseComponent) (reconcile.Result, error) {
s := ba.GetStatus()
Expand All @@ -191,6 +214,8 @@ func (r *ReconcilerBase) ManageError(issue error, conditionType common.StatusCon
newCondition.SetStatus(corev1.ConditionFalse)
s.SetCondition(newCondition)

addStatusWarnings(ba)

if conditionType != common.StatusConditionTypeResourcesReady {
//Check Application status (reconciliation & resource status & endpoint status)
r.CheckApplicationStatus(ba)
Expand Down Expand Up @@ -247,6 +272,8 @@ func (r *ReconcilerBase) ManageSuccess(conditionType common.StatusConditionType,
statusCondition.SetStatus(corev1.ConditionTrue)
s.SetCondition(statusCondition)

addStatusWarnings(ba)

//Check application status (reconciliation & resource status & endpoint status)
readyStatus := r.CheckApplicationStatus(ba)

Expand Down
42 changes: 42 additions & 0 deletions utils/reconciler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,48 @@ func TestGetRouteTLSValues(t *testing.T) {
testGetRouteTLSValues(t)
}

func TestAddStatusWarnings(t *testing.T) {
testData := []Test{}
tr := true
fl := false
svc := appstacksv1.RuntimeComponentService{Port: 9080}
spec := appstacksv1.RuntimeComponentSpec{Service: &svc}
comp := createRuntimeComponent(name, namespace, spec)

// manageTLS is implicitly true, service port 9080
addStatusWarnings(comp)
status := comp.GetStatus()
c := status.GetConditions()
testData = append(testData, Test{test: "serviceport=9080, condition type should be warning", actual: c[0].GetType(), expected: common.StatusConditionTypeWarning})

// manageTLS is implicitly true, Service is nil
comp.Spec.Service = nil
addStatusWarnings(comp)
testData = append(testData, Test{test: "service=nil, length of conditions should be zero", actual: len(comp.GetStatus().GetConditions()), expected: 0})

// manageTLS is explicitly true, service is nil
comp.Spec.ManageTLS = &tr
addStatusWarnings(comp)
testData = append(testData, Test{test: "manageTLS=true, service=nil, length of conditions should be zero", actual: len(comp.GetStatus().GetConditions()), expected: 0})

// manageTLS is explicitly true, service port is 9080
comp.Spec.Service = &svc
addStatusWarnings(comp)
testData = append(testData, Test{test: "mangeTLS=true, serviceport=9080, condition type should be warning", actual: comp.GetStatus().GetConditions()[0].GetType(), expected: common.StatusConditionTypeWarning})

// manageTLS is explicitly false, service port is 9080
comp.Spec.ManageTLS = &fl
addStatusWarnings(comp)
testData = append(testData, Test{test: "mangeTLS=false, serviceport=9080, length of conditions should be zero", actual: len(comp.GetStatus().GetConditions()), expected: 0})

// manageTLS is explicitly false, service port is 9443
svc.Port = 9443
addStatusWarnings(comp)
testData = append(testData, Test{test: "mangeTLS=false, serviceport=9443, length of conditions should be zero", actual: len(comp.GetStatus().GetConditions()), expected: 0})

verifyTests(testData, t)
}

func createFakeDiscoveryClient() discovery.DiscoveryInterface {
fakeDiscoveryClient := &fakediscovery.FakeDiscovery{Fake: &coretesting.Fake{}}
fakeDiscoveryClient.Resources = []*metav1.APIResourceList{
Expand Down
24 changes: 0 additions & 24 deletions utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
"github.com/application-stacks/runtime-component-operator/common"
prometheusv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"

appstacksv1 "github.com/application-stacks/runtime-component-operator/api/v1"
routev1 "github.com/openshift/api/route/v1"
appsv1 "k8s.io/api/apps/v1"
autoscalingv1 "k8s.io/api/autoscaling/v1"
Expand Down Expand Up @@ -1217,29 +1216,6 @@ func CustomizeServiceMonitor(sm *prometheusv1.ServiceMonitor, ba common.BaseComp

}

// GetCondition ...
func GetCondition(conditionType appstacksv1.StatusConditionType, status *appstacksv1.RuntimeComponentStatus) *appstacksv1.StatusCondition {
for i := range status.Conditions {
if status.Conditions[i].Type == conditionType {
return &status.Conditions[i]
}
}

return nil
}

// SetCondition ...
func SetCondition(condition appstacksv1.StatusCondition, status *appstacksv1.RuntimeComponentStatus) {
for i := range status.Conditions {
if status.Conditions[i].Type == condition.Type {
status.Conditions[i] = condition
return
}
}

status.Conditions = append(status.Conditions, condition)
}

// GetWatchNamespaces returns a slice of namespaces the operator should watch based on WATCH_NAMESPSCE value
// WATCH_NAMESPSCE value could be empty for watching the whole cluster or a comma-separated list of namespaces
func GetWatchNamespaces() ([]string, error) {
Expand Down
34 changes: 0 additions & 34 deletions utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -675,40 +675,6 @@ func TestCustomizeServiceMonitor(t *testing.T) {
verifyTests(testSM, t)
}

func TestGetCondition(t *testing.T) {
logger := zap.New()
logf.SetLogger(logger)
status := &appstacksv1.RuntimeComponentStatus{
Conditions: []appstacksv1.StatusCondition{
{
Status: corev1.ConditionTrue,
Type: appstacksv1.StatusConditionTypeReconciled,
},
},
}
conditionType := appstacksv1.StatusConditionTypeReconciled
cond := GetCondition(conditionType, status)
testGC := []Test{{"Set status condition", status.Conditions[0].Status, cond.Status}}
verifyTests(testGC, t)
}

func TestSetCondition(t *testing.T) {
logger := zap.New()
logf.SetLogger(logger)
status := &appstacksv1.RuntimeComponentStatus{
Conditions: []appstacksv1.StatusCondition{
{Type: appstacksv1.StatusConditionTypeReconciled},
},
}
condition := appstacksv1.StatusCondition{
Status: corev1.ConditionTrue,
Type: appstacksv1.StatusConditionTypeReconciled,
}
SetCondition(condition, status)
testSC := []Test{{"Set status condition", condition.Status, status.Conditions[0].Status}}
verifyTests(testSC, t)
}

func TestGetWatchNamespaces(t *testing.T) {
// Set the logger to development mode for verbose logs
logger := zap.New()
Expand Down