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

feat(ui): added notification rule & checks last run status & error #16338

Merged
merged 5 commits into from
Dec 27, 2019
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
1. [16323](https://github.com/influxdata/influxdb/pull/16323): Add support for tasks to pkger apply functionality
1. [16324](https://github.com/influxdata/influxdb/pull/16324): Add support for tasks to pkger export functionality
1. [16226](https://github.com/influxdata/influxdb/pull/16226): Add group() to Query Builder
1. [16338](https://github.com/influxdata/influxdb/pull/16338): Add last run status to check and notification rules

### Bug Fixes

Expand Down
37 changes: 27 additions & 10 deletions http/check_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"io/ioutil"
"net/http"
"time"

"github.com/influxdata/httprouter"
"github.com/influxdata/influxdb"
Expand Down Expand Up @@ -138,9 +139,13 @@ type checkLinks struct {

type checkResponse struct {
influxdb.Check
Status string `json:"status"`
Labels []influxdb.Label `json:"labels"`
Links checkLinks `json:"links"`
Status string `json:"status"`
Labels []influxdb.Label `json:"labels"`
Links checkLinks `json:"links"`
LatestCompleted time.Time `json:"latestCompleted,omitempty"`
LatestScheduled time.Time `json:"latestScheduled,omitempty"`
LastRunStatus string `json:"LastRunStatus,omitempty"`
LastRunError string `json:"LastRunError,omitempty"`
}

type postCheckRequest struct {
Expand All @@ -159,13 +164,21 @@ func (resp checkResponse) MarshalJSON() ([]byte, error) {
}

b2, err := json.Marshal(struct {
Labels []influxdb.Label `json:"labels"`
Links checkLinks `json:"links"`
Status string `json:"status"`
Labels []influxdb.Label `json:"labels"`
Links checkLinks `json:"links"`
Status string `json:"status"`
LatestCompleted time.Time `json:"latestCompleted,omitempty"`
LatestScheduled time.Time `json:"latestScheduled,omitempty"`
LastRunStatus string `json:"lastRunStatus,omitempty"`
LastRunError string `json:"lastRunError,omitempty"`
}{
Links: resp.Links,
Labels: resp.Labels,
Status: resp.Status,
Links: resp.Links,
Labels: resp.Labels,
Status: resp.Status,
LatestCompleted: resp.LatestCompleted,
LatestScheduled: resp.LatestScheduled,
LastRunStatus: resp.LastRunStatus,
LastRunError: resp.LastRunError,
})
if err != nil {
return nil, err
Expand Down Expand Up @@ -198,7 +211,11 @@ func (h *CheckHandler) newCheckResponse(ctx context.Context, chk influxdb.Check,
Owners: fmt.Sprintf("/api/v2/checks/%s/owners", chk.GetID()),
Query: fmt.Sprintf("/api/v2/checks/%s/query", chk.GetID()),
},
Labels: []influxdb.Label{},
Labels: []influxdb.Label{},
LatestCompleted: task.LatestCompleted,
LatestScheduled: task.LatestScheduled,
LastRunStatus: task.LastRunStatus,
LastRunError: task.LastRunError,
}

for _, l := range labels {
Expand Down
24 changes: 18 additions & 6 deletions http/check_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,9 @@ func TestService_handleGetChecks(t *testing.T) {
}
}
],
"status": "active"
"status": "active",
"latestCompleted": "0001-01-01T00:00:00Z",
"latestScheduled": "0001-01-01T00:00:00Z"
},
{
"links": {
Expand Down Expand Up @@ -230,7 +232,9 @@ func TestService_handleGetChecks(t *testing.T) {
}
}
],
"status": "active"
"status": "active",
"latestCompleted": "0001-01-01T00:00:00Z",
"latestScheduled": "0001-01-01T00:00:00Z"
}
]
}
Expand Down Expand Up @@ -520,7 +524,9 @@ func TestService_handleGetCheck(t *testing.T) {
"type": "deadman",
"orgID": "020f755c3c082000",
"name": "hello",
"status": "active"
"status": "active",
"latestCompleted": "0001-01-01T00:00:00Z",
"latestScheduled": "0001-01-01T00:00:00Z"
}
`,
},
Expand Down Expand Up @@ -703,7 +709,9 @@ func TestService_handlePostCheck(t *testing.T) {
"every": "5m",
"level": "WARN",
"labels": [],
"status": "active"
"status": "active",
"latestCompleted": "0001-01-01T00:00:00Z",
"latestScheduled": "0001-01-01T00:00:00Z"
}
`,
},
Expand Down Expand Up @@ -949,7 +957,9 @@ func TestService_handlePatchCheck(t *testing.T) {
"statusMessageTemplate": "",
"tags": null,
"type": "deadman",
"labels": []
"labels": [],
"latestCompleted": "0001-01-01T00:00:00Z",
"latestScheduled": "0001-01-01T00:00:00Z"
}
`,
},
Expand Down Expand Up @@ -1130,7 +1140,9 @@ func TestService_handleUpdateCheck(t *testing.T) {
"statusMessageTemplate": "",
"tags": null,
"type": "deadman",
"labels": []
"labels": [],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like there's some spacing issue here?

"latestCompleted": "0001-01-01T00:00:00Z",
"latestScheduled": "0001-01-01T00:00:00Z"
}
`,
},
Expand Down
39 changes: 28 additions & 11 deletions http/notification_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/json"
"fmt"
"net/http"
"time"

"github.com/influxdata/httprouter"
"github.com/influxdata/influxdb"
Expand Down Expand Up @@ -146,9 +147,13 @@ type notificationRuleLinks struct {

type notificationRuleResponse struct {
influxdb.NotificationRule
Labels []influxdb.Label `json:"labels"`
Links notificationRuleLinks `json:"links"`
Status string `json:"status"`
Labels []influxdb.Label `json:"labels"`
Links notificationRuleLinks `json:"links"`
Status string `json:"status"`
LatestCompleted time.Time `json:"latestCompleted,omitempty"`
LatestScheduled time.Time `json:"latestScheduled,omitempty"`
LastRunStatus string `json:"LastRunStatus,omitempty"`
LastRunError string `json:"LastRunError,omitempty"`
}

func (resp notificationRuleResponse) MarshalJSON() ([]byte, error) {
Expand All @@ -158,13 +163,21 @@ func (resp notificationRuleResponse) MarshalJSON() ([]byte, error) {
}

b2, err := json.Marshal(struct {
Labels []influxdb.Label `json:"labels"`
Links notificationRuleLinks `json:"links"`
Status string `json:"status"`
Labels []influxdb.Label `json:"labels"`
Links notificationRuleLinks `json:"links"`
Status string `json:"status"`
LatestCompleted time.Time `json:"latestCompleted,omitempty"`
LatestScheduled time.Time `json:"latestScheduled,omitempty"`
LastRunStatus string `json:"lastRunStatus,omitempty"`
LastRunError string `json:"lastRunError,omitempty"`
}{
Links: resp.Links,
Labels: resp.Labels,
Status: resp.Status,
Links: resp.Links,
Labels: resp.Labels,
Status: resp.Status,
LatestCompleted: resp.LatestCompleted,
LatestScheduled: resp.LatestScheduled,
LastRunStatus: resp.LastRunStatus,
LastRunError: resp.LastRunError,
})
if err != nil {
return nil, err
Expand Down Expand Up @@ -195,8 +208,12 @@ func (h *NotificationRuleHandler) newNotificationRuleResponse(ctx context.Contex
Owners: fmt.Sprintf("/api/v2/notificationRules/%s/owners", nr.GetID()),
Query: fmt.Sprintf("/api/v2/notificationRules/%s/query", nr.GetID()),
},
Labels: []influxdb.Label{},
Status: t.Status,
Labels: []influxdb.Label{},
Status: t.Status,
LatestCompleted: t.LatestCompleted,
LatestScheduled: t.LatestScheduled,
LastRunStatus: t.LastRunStatus,
LastRunError: t.LastRunError,
}

for _, l := range labels {
Expand Down
12 changes: 9 additions & 3 deletions http/notification_rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,9 @@ func Test_newNotificationRuleResponses(t *testing.T) {
],
"type": "slack",
"updatedAt": "0001-01-01T00:00:00Z",
"status": "active"
"status": "active",
"latestCompleted": "0001-01-01T00:00:00Z",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spacing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hoorayimhelping go won't allow for weird formatting. This may look strange but it's kosher in the actual files

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i know gfmt controls spacing, but those things can get weird sometimes, it's always good to confirm and not just trust the machines

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for sure. It's all good

"latestScheduled": "0001-01-01T00:00:00Z"
},
{
"createdAt": "0001-01-01T00:00:00Z",
Expand All @@ -170,7 +172,9 @@ func Test_newNotificationRuleResponses(t *testing.T) {
"runbookLink": "",
"type": "pagerduty",
"updatedAt": "0001-01-01T00:00:00Z",
"status": "active"
"status": "active",
"latestCompleted": "0001-01-01T00:00:00Z",
"latestScheduled": "0001-01-01T00:00:00Z"
}
]
}`,
Expand Down Expand Up @@ -287,7 +291,9 @@ func Test_newNotificationRuleResponse(t *testing.T) {
}
],
"type": "slack",
"updatedAt": "0001-01-01T00:00:00Z"
"updatedAt": "0001-01-01T00:00:00Z",
"latestCompleted": "0001-01-01T00:00:00Z",
"latestScheduled": "0001-01-01T00:00:00Z"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spacing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

}`,
},
}
Expand Down
30 changes: 30 additions & 0 deletions http/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10214,6 +10214,21 @@ components:
statusMessageTemplate:
description: The template used to generate and write a status message.
type: string
latestCompleted:
description: Timestamp of latest scheduled, completed run, RFC3339.
type: string
format: date-time
readOnly: true
lastRunStatus:
readOnly: true
type: string
enum:
- failed
- success
- canceled
lastRunError:
readOnly: true
type: string
labels:
$ref: "#/components/schemas/Labels"
links:
Expand Down Expand Up @@ -10390,6 +10405,21 @@ components:
- statusRules
- endpointID
properties:
latestCompleted:
description: Timestamp of latest scheduled, completed run, RFC3339.
type: string
format: date-time
readOnly: true
lastRunStatus:
readOnly: true
type: string
enum:
- failed
- success
- canceled
lastRunError:
readOnly: true
type: string
id:
readOnly: true
type: string
Expand Down
19 changes: 19 additions & 0 deletions ui/cypress/e2e/checks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ describe('Checks', () => {
cy.getByTestID('add-threshold-condition-WARN').click()
cy.getByTestID('save-cell--button').click()
cy.getByTestID('check-card').should('have.length', 1)
cy.getByTestID('notification-error').should('not.exist')
})

it('should allow created checks to be selected and routed to the edit page', () => {
Expand All @@ -95,5 +96,23 @@ describe('Checks', () => {
})
})
})

it('can toggle a check to on / off', () => {
cy.get('.cf-resource-card__disabled').should('not.exist')
cy.getByTestID('check-card--slide-toggle').click()
cy.getByTestID('notification-error').should('not.exist')
cy.get('.cf-resource-card__disabled').should('exist')
cy.getByTestID('check-card--slide-toggle').click()
cy.getByTestID('notification-error').should('not.exist')
cy.get('.cf-resource-card__disabled').should('not.exist')
})

it('can display the last run status', () => {
cy.getByTestID('last-run-status--icon').should('exist')
cy.getByTestID('last-run-status--icon').trigger('mouseover')
cy.getByTestID('popover--dialog')
.should('exist')
.contains('Last Run Status:')
})
})
})
12 changes: 12 additions & 0 deletions ui/src/alerting/actions/checks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,18 @@ export const saveCheckFromTimeMachine = () => async (
}
}

export const updateCheck = (check: Partial<Check>) => async (
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was previously removed and caused a breaking change. It has been added back here with the intention of refactoring this implementation with a different ticket

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this still cause a breaking change? can you link the relevant tickets please?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, when I had originally submitted the comment I hadn't had the chance to write up the issue. Here's the breaking change PR:

#16333
but it seems like the changes made to updateCheck weren’t updated here:
https://github.com/influxdata/influxdb/blob/master/ui/src/alerting/components/CheckCard.tsx#L17

and here's the issue that is intended on resolving it :

#16339

dispatch: Dispatch<Action | NotificationAction>
) => {
const resp = await api.putCheck({checkID: check.id, data: check as Check})
if (resp.status === 200) {
dispatch(setCheck(resp.data))
} else {
throw new Error(resp.data.message)
}
dispatch(setCheck(resp.data))
}

const updateCheckFromTimeMachine = async (check: Check) => {
// todo: refactor after https://github.com/influxdata/influxdb/issues/16317
const getCheckResponse = await api.getCheck({checkID: check.id})
Expand Down
7 changes: 7 additions & 0 deletions ui/src/alerting/components/CheckCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {withRouter, WithRouterProps} from 'react-router'
import {SlideToggle, ComponentSize, ResourceCard} from '@influxdata/clockface'
import CheckCardContext from 'src/alerting/components/CheckCardContext'
import InlineLabels from 'src/shared/components/inlineLabels/InlineLabels'
import LastRunTaskStatus from 'src/shared/components/lastRunTaskStatus/LastRunTaskStatus'

// Constants
import {DEFAULT_CHECK_NAME} from 'src/alerting/constants'
Expand Down Expand Up @@ -170,7 +171,13 @@ const CheckCard: FunctionComponent<Props> = ({
/>
}
metaData={[
<>Last completed at {check.latestCompleted}</>,
<>{relativeTimestampFormatter(check.updatedAt, 'Last updated ')}</>,
<LastRunTaskStatus
key={2}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added the key here to resolve linter errors

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this a react warning or a lint error? if react is generating a warning then that's the issue we should address. if lint is mistakenly saying we need a key, we should comment an override here, because it's adding meaning to the code to get around a tool issue. do you understand the difference? a real react warning about a list item not having a key is something we should fix, a mistaken lint error trying to head off that warning is something we should comment about, but not change our code to make go away.

if it's an actual react warning, we should give this a more unique name, if possible. react says to only use the item's list index as a last resort

When you don’t have stable IDs for rendered items, you may use the item index as a key as a last resort:

We don’t recommend using indexes for keys if the order of items may change. This can negatively impact performance and may cause issues with component state.

https://reactjs.org/docs/lists-and-keys.html#keys

same comment and any changes that need to happen apply to RuleCard's key change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was a lint error - i imagine stemming from the way clockface handles metaData being passed dom nodes

lastRunError={check.lastRunError}
lastRunStatus={check.lastRunStatus}
/>,
]}
/>
)
Expand Down
7 changes: 7 additions & 0 deletions ui/src/alerting/components/notifications/RuleCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {withRouter, WithRouterProps} from 'react-router'
import {SlideToggle, ComponentSize, ResourceCard} from '@influxdata/clockface'
import NotificationRuleCardContext from 'src/alerting/components/notifications/RuleCardContext'
import InlineLabels from 'src/shared/components/inlineLabels/InlineLabels'
import LastRunTaskStatus from 'src/shared/components/lastRunTaskStatus/LastRunTaskStatus'

// Constants
import {DEFAULT_NOTIFICATION_RULE_NAME} from 'src/alerting/constants'
Expand Down Expand Up @@ -165,7 +166,13 @@ const RuleCard: FC<Props> = ({
/>
}
metaData={[
<>Last completed at {rule.latestCompleted}</>,
<>{relativeTimestampFormatter(rule.updatedAt, 'Last updated ')}</>,
<LastRunTaskStatus
key={2}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added key prop here to resolve linter errors

lastRunError={rule.lastRunError}
lastRunStatus={rule.lastRunStatus}
/>,
]}
/>
)
Expand Down
Loading