Skip to content

Commit

Permalink
apis: Add detail subcondition type to DetailedCondition
Browse files Browse the repository at this point in the history
Adds a details subcodition array to the DetailedCondition allowing
for more information to be exposed to users via an HTTPProxy
Conditions struct. Things like fqdn, included paths or headers
can be written to child proxies allowing users to understand
what has been included to them from a parent resource.

Updates #2495

Signed-off-by: Steve Sloka <slokas@vmware.com>
  • Loading branch information
stevesloka committed Nov 17, 2020
1 parent 8fbbac6 commit 4f785d4
Show file tree
Hide file tree
Showing 6 changed files with 444 additions and 0 deletions.
5 changes: 5 additions & 0 deletions apis/projectcontour/v1/detailedconditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ type DetailedCondition struct {
// An empty slice here indicates no warnings.
// +optional
Warnings []SubCondition `json:"warnings,omitempty"`
// Details contains a slice of relevant detail subconditions for this object.
//
// Subconditions expose detailed information about the object.
// +optional
Details []SubCondition `json:"infos,omitempty"`
}

const ValidConditionType string = "Valid"
26 changes: 26 additions & 0 deletions apis/projectcontour/v1/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,19 @@ func (dc *DetailedCondition) AddError(errorType, reason, message string) {
})
}

// AddDetail adds an info-level Subcondition to the DetailedCondition.
// If a SubCondition with the given detailType exists, will overwrite the details.
func (dc *DetailedCondition) AddDetail(detailType, reason, message string) {
message = truncateLongMessage(message)

dc.Details = append(dc.Details, SubCondition{
Type: detailType,
Status: ConditionTrue,
Message: message,
Reason: reason,
})
}

// AddErrorf adds an error-level Subcondition to the DetailedCondition, using
// fmt.Sprintf on the formatmsg and args params.
// If a SubCondition with the given errorType exists, will overwrite the details.
Expand All @@ -130,6 +143,19 @@ func (dc *DetailedCondition) GetError(errorType string) (SubCondition, bool) {
return dc.Errors[i], true
}

// GetDetail gets a detail of the given detailType.
// Similar to a hash lookup, will return true in the second value if a match is
// found, and false otherwise.
func (dc *DetailedCondition) GetDetail(detailType string) (SubCondition, bool) {
i := getIndex(detailType, dc.Details)

if i == -1 {
return SubCondition{}, false
}

return dc.Details[i], true
}

// AddWarning adds an warning-level Subcondition to the DetailedCondition.
// If a SubCondition with the given warnType exists, will overwrite the details.
// Note that adding warnings does not update the DetailedCondition Reason or Message.
Expand Down
204 changes: 204 additions & 0 deletions apis/projectcontour/v1/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,169 @@ func TestAddWarningConditions(t *testing.T) {
}
}

func TestAddDetailConditions(t *testing.T) {

tests := map[string]struct {
dc *DetailedCondition
subconditions []subConditionDetails
want *DetailedCondition
}{
"basic detail add": {
dc: &DetailedCondition{},
subconditions: []subConditionDetails{
{
condType: "SimpleTest",
reason: "TestReason",
message: "We had a straightforward warning",
},
},
want: &DetailedCondition{
Details: []SubCondition{
{
Type: "SimpleTest",
Reason: "TestReason",
Message: "We had a straightforward warning",
Status: ConditionTrue,
},
},
},
},
"multiple reason, multiple type": {
dc: &DetailedCondition{},
subconditions: []subConditionDetails{
{
condType: "SimpleTest",
reason: "TestReason",
message: "We had a straightforward warning",
},
{
condType: "SecondTest",
reason: "TestReason2",
message: "We had an extra straightforward warning",
},
},
want: &DetailedCondition{
Details: []SubCondition{
{
Type: "SimpleTest",
Reason: "TestReason",
Message: "We had a straightforward warning",
Status: ConditionTrue,
},
{
Type: "SecondTest",
Reason: "TestReason2",
Message: "We had an extra straightforward warning",
Status: ConditionTrue,
},
},
},
},
"same reason, multiple type": {
dc: &DetailedCondition{},
subconditions: []subConditionDetails{
{
condType: "SimpleTest",
reason: "TestReason",
message: "We had a straightforward warning",
},
{
condType: "SecondTest",
reason: "TestReason",
message: "We had an extra straightforward warning",
},
},
want: &DetailedCondition{
Details: []SubCondition{
{
Type: "SimpleTest",
Reason: "TestReason",
Message: "We had a straightforward warning",
Status: ConditionTrue,
},
{
Type: "SecondTest",
Reason: "TestReason",
Message: "We had an extra straightforward warning",
Status: ConditionTrue,
},
},
},
},
"same reason, same type": {
dc: &DetailedCondition{},
subconditions: []subConditionDetails{
{
condType: "SimpleTest",
reason: "TestReason",
message: "We had a straightforward warning",
},
{
condType: "SimpleTest",
reason: "TestReason",
message: "We had an extra straightforward warning",
},
},
want: &DetailedCondition{
Details: []SubCondition{
{
Type: "SimpleTest",
Reason: "TestReason",
Message: "We had a straightforward warning",
Status: ConditionTrue,
},
{
Type: "SimpleTest",
Reason: "TestReason",
Message: "We had an extra straightforward warning",
Status: ConditionTrue,
},
},
},
},
"multiple different reason, same type": {
dc: &DetailedCondition{},
subconditions: []subConditionDetails{
{
condType: "SimpleTest",
reason: "TestReason",
message: "We had a straightforward warning",
},
{
condType: "SimpleTest",
reason: "TestReason2",
message: "We had an extra straightforward warning",
},
},
want: &DetailedCondition{
Details: []SubCondition{
{
Type: "SimpleTest",
Reason: "TestReason",
Message: "We had a straightforward warning",
Status: ConditionTrue,
},
{
Type: "SimpleTest",
Reason: "TestReason2",
Message: "We had an extra straightforward warning",
Status: ConditionTrue,
},
},
},
},
}

for name, tc := range tests {

for _, cond := range tc.subconditions {
tc.dc.AddDetail(cond.condType, cond.reason, cond.message)
}

assert.Equalf(t, tc.want, tc.dc, "Add error condition failed in test %s", name)
}
}

func TestGetConditionFor(t *testing.T) {
tests := map[string]struct {
status HTTPProxyStatus
Expand Down Expand Up @@ -624,6 +787,47 @@ func TestGetWarning(t *testing.T) {
assert.Equal(t, SubCondition{}, emptySubCond)

}

func TestGetDetail(t *testing.T) {

dcWithErrors := &DetailedCondition{
Details: []SubCondition{
{
Type: "SimpleTest1",
Reason: "SimpleReason",
Message: "We had a simple warning 1",
Status: ConditionTrue,
},
{
Type: "SimpleTest2",
Reason: "SimpleReason",
Message: "We had a simple warning 2",
Status: ConditionTrue,
},
},
}

firstSubCond := SubCondition{
Type: "SimpleTest1",
Reason: "SimpleReason",
Message: "We had a simple warning 1",
Status: ConditionTrue,
}

gotSubCond, ok := dcWithErrors.GetDetail("SimpleTest1")
assert.True(t, ok)
assert.Equal(t, firstSubCond, gotSubCond)

nonExistentCond, ok := dcWithErrors.GetDetail("nonexistent")
assert.False(t, ok)
assert.Equal(t, SubCondition{}, nonExistentCond)

dcEmpty := &DetailedCondition{}
emptySubCond, ok := dcEmpty.GetDetail("SimpleTest1")
assert.False(t, ok)
assert.Equal(t, SubCondition{}, emptySubCond)
}

func TestTruncateLongMessage(t *testing.T) {

shortmessage := "This is a message shorter than the max length"
Expand Down
5 changes: 5 additions & 0 deletions apis/projectcontour/v1/zz_generated.deepcopy.go

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

Loading

0 comments on commit 4f785d4

Please sign in to comment.