Skip to content

Commit

Permalink
feat: use datadog v2 api for downtime creation
Browse files Browse the repository at this point in the history
  • Loading branch information
ReuDa committed Mar 28, 2024
1 parent f52dc21 commit 81eafc2
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 55 deletions.
54 changes: 31 additions & 23 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# Changelog

## v1.8.6 (Next release)

- Update dependencies
- Use datadog API V2 for downtime creation

## v1.8.5

- Update dependencies


## v1.8.4

- update dependencies
Expand All @@ -29,7 +32,7 @@
## v1.8.0

- Updated to use the new `steadybit/event-kit-api` version `1.3.0`
- Requires Platform `>= 1.0.94`
- Requires Platform `>= 1.0.94`

## v1.7.10

Expand All @@ -54,60 +57,65 @@

## v1.7.4

- Add DateHappened to submitted DataDog events
- Correctly select StepExecution for event creation
- Add DateHappened to submitted DataDog events
- Correctly select StepExecution for event creation

## v1.7.3

- Add linux package build
- Add linux package build

## v1.7.2

- Added service tag to Datadog events
- Added service tag to Datadog events

## v1.7.1

- Added DEBUG logging for monitor discovery
- Added DEBUG logging for monitor discovery

## v1.7.0

- Links to Datadogs monitors are now using the timeframe of the experiment execution.
- "Monitor Status Check" has a new parameter `Status Check Mode`. Supported values are `All the time` (default) and `At least once`.
- New Action to create a Downtime for a monitor during an experiment execution.
- Details about step executions are sent to Datadog as events.
- Links to Datadogs monitors are now using the timeframe of the experiment execution.
- "Monitor Status Check" has a new parameter `Status Check Mode`. Supported values are `All the time` (default)
and `At least once`.
- New Action to create a Downtime for a monitor during an experiment execution.
- Details about step executions are sent to Datadog as events.

## v1.6.0

- Monitor shouldn't have a blast radius
- Run as non-root user
- Update dependencies
- Monitor shouldn't have a blast radius
- Run as non-root user
- Update dependencies

## v1.5.0

- Print build information on extension startup.
- Print build information on extension startup.

## v1.4.0

- Support creation of a TLS server through the environment variables `STEADYBIT_EXTENSION_TLS_SERVER_CERT` and `STEADYBIT_EXTENSION_TLS_SERVER_KEY`. Both environment variables must refer to files containing the certificate and key in PEM format.
- Support mutual TLS through the environment variable `STEADYBIT_EXTENSION_TLS_CLIENT_CAS`. The environment must refer to a comma-separated list of files containing allowed clients' CA certificates in PEM format.
- Support creation of a TLS server through the environment variables `STEADYBIT_EXTENSION_TLS_SERVER_CERT`
and `STEADYBIT_EXTENSION_TLS_SERVER_KEY`. Both environment variables must refer to files containing the certificate
and key in PEM format.
- Support mutual TLS through the environment variable `STEADYBIT_EXTENSION_TLS_CLIENT_CAS`. The environment must refer
to a comma-separated list of files containing allowed clients' CA certificates in PEM format.

## v1.3.0

- Support for the `STEADYBIT_LOG_FORMAT` env variable. When set to `json`, extensions will log JSON lines to stderr.
- Support for the `STEADYBIT_LOG_FORMAT` env variable. When set to `json`, extensions will log JSON lines to stderr.

## v1.2.1

- Also observe the events `experiment.execution.failed`, `experiment.execution.canceled` and `experiment.execution.errored` to report all relevant event types to Datadog.
- Also observe the events `experiment.execution.failed`, `experiment.execution.canceled`
and `experiment.execution.errored` to report all relevant event types to Datadog.

## v1.2.0

- Reports events to Datadog to mark the start and end of experiments.
- Reports events to Datadog to mark the start and end of experiments.

## v1.1.0

- Correctly mark duration parameter for status check action as required.
- Add monitor status widgets to the execution view.
- Correctly mark duration parameter for status check action as required.
- Add monitor status widgets to the execution view.

## v1.0.0

- Initial release
- Initial release
9 changes: 5 additions & 4 deletions config/specification.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"context"
"github.com/DataDog/datadog-api-client-go/v2/api/datadog"
"github.com/DataDog/datadog-api-client-go/v2/api/datadogV1"
"github.com/DataDog/datadog-api-client-go/v2/api/datadogV2"
"net/http"
)

Expand Down Expand Up @@ -71,13 +72,13 @@ func (s *Specification) GetMonitor(ctx context.Context, monitorId int64, params
return api.GetMonitor(s.WrapContextWithDatadogContextValues(ctx), monitorId, params)
}

func (s *Specification) CreateDowntime(ctx context.Context, downtimeBody datadogV1.Downtime) (datadogV1.Downtime, *http.Response, error) {
api := datadogV1.NewDowntimesApi(s.createApiClient())
func (s *Specification) CreateDowntime(ctx context.Context, downtimeBody datadogV2.DowntimeCreateRequest) (datadogV2.DowntimeResponse, *http.Response, error) {
api := datadogV2.NewDowntimesApi(s.createApiClient())
return api.CreateDowntime(s.WrapContextWithDatadogContextValues(ctx), downtimeBody)
}

func (s *Specification) CancelDowntime(ctx context.Context, downtimeId int64) (*http.Response, error) {
api := datadogV1.NewDowntimesApi(s.createApiClient())
func (s *Specification) CancelDowntime(ctx context.Context, downtimeId string) (*http.Response, error) {
api := datadogV2.NewDowntimesApi(s.createApiClient())
return api.CancelDowntime(s.WrapContextWithDatadogContextValues(ctx), downtimeId)
}

Expand Down
47 changes: 30 additions & 17 deletions extmonitor/monitor_downtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"context"
"fmt"
"github.com/DataDog/datadog-api-client-go/v2/api/datadog"
"github.com/DataDog/datadog-api-client-go/v2/api/datadogV1"
"github.com/DataDog/datadog-api-client-go/v2/api/datadogV2"
"github.com/steadybit/action-kit/go/action_kit_api/v2"
"github.com/steadybit/action-kit/go/action_kit_sdk"
"github.com/steadybit/extension-datadog/config"
Expand All @@ -31,7 +31,7 @@ type MonitorDowntimeState struct {
MonitorId int64
End time.Time
Notify bool
DowntimeId *int64
DowntimeId *string
ExperimentUri *string
ExecutionUri *string
}
Expand Down Expand Up @@ -118,14 +118,14 @@ func (m *MonitorDowntimeAction) Stop(ctx context.Context, state *MonitorDowntime
}

type MonitorDowntimeApi interface {
CreateDowntime(ctx context.Context, downtimeBody datadogV1.Downtime) (datadogV1.Downtime, *http.Response, error)
CancelDowntime(ctx context.Context, downtimeId int64) (*http.Response, error)
CreateDowntime(ctx context.Context, downtimeBody datadogV2.DowntimeCreateRequest) (datadogV2.DowntimeResponse, *http.Response, error)
CancelDowntime(ctx context.Context, downtimeId string) (*http.Response, error)
}

func MonitorDowntimeStart(ctx context.Context, state *MonitorDowntimeState, api MonitorDowntimeApi) (*action_kit_api.StartResult, error) {
var notifyEndType []datadogV1.NotifyEndType
var notifyEndType []datadogV2.DowntimeNotifyEndStateActions
if state.Notify {
notifyEndType = []datadogV1.NotifyEndType{datadogV1.NOTIFYENDTYPE_CANCELED, datadogV1.NOTIFYENDTYPE_EXPIRED}
notifyEndType = []datadogV2.DowntimeNotifyEndStateActions{datadogV2.DOWNTIMENOTIFYENDSTATEACTIONS_CANCELED, datadogV2.DOWNTIMENOTIFYENDSTATEACTIONS_EXPIRED}
}

message := "Created by ![Steadybit](https://downloads.steadybit.com/logo-extension-datadog.jpg)"
Expand All @@ -136,25 +136,38 @@ func MonitorDowntimeStart(ctx context.Context, state *MonitorDowntimeState, api
message = message + fmt.Sprintf("\n\n[Open Execution](%s)", *state.ExecutionUri)
}

downtimeRequest := datadogV1.Downtime{
MonitorId: *datadog.NewNullableInt64(&state.MonitorId),
Message: *datadog.NewNullableString(extutil.Ptr(message)),
End: *datadog.NewNullableInt64(extutil.Ptr(state.End.Unix())),
MuteFirstRecoveryNotification: extutil.Ptr(true),
NotifyEndTypes: notifyEndType,
Scope: []string{"*"},
downtimeRequest := datadogV2.DowntimeCreateRequest{
Data: datadogV2.DowntimeCreateRequestData{
Type: datadogV2.DOWNTIMERESOURCETYPE_DOWNTIME,
Attributes: datadogV2.DowntimeCreateRequestAttributes{
MonitorIdentifier: datadogV2.DowntimeMonitorIdentifier{
DowntimeMonitorIdentifierId: &datadogV2.DowntimeMonitorIdentifierId{
MonitorId: state.MonitorId,
},
},
Message: *datadog.NewNullableString(extutil.Ptr(message)),
Schedule: &datadogV2.DowntimeScheduleCreateRequest{
DowntimeScheduleOneTimeCreateUpdateRequest: &datadogV2.DowntimeScheduleOneTimeCreateUpdateRequest{
End: *datadog.NewNullableTime(extutil.Ptr(state.End)),
},
},
MuteFirstRecoveryNotification: extutil.Ptr(true),
NotifyEndTypes: notifyEndType,
Scope: "*",
},
},
}

downtime, resp, err := api.CreateDowntime(ctx, downtimeRequest)
if err != nil {
return nil, extension_kit.ToError(fmt.Sprintf("Failed to create Downtime for monitor %d. Full response: %v", state.MonitorId, resp), err)
}

state.DowntimeId = extutil.Ptr(downtime.GetId())
state.DowntimeId = downtime.Data.Id

return &action_kit_api.StartResult{
Messages: &action_kit_api.Messages{
action_kit_api.Message{Level: extutil.Ptr(action_kit_api.Info), Message: fmt.Sprintf("Downtime started. (monitor %d, downtime %d)", state.MonitorId, *state.DowntimeId)},
action_kit_api.Message{Level: extutil.Ptr(action_kit_api.Info), Message: fmt.Sprintf("Downtime started. (monitor %d, downtime %s)", state.MonitorId, *state.DowntimeId)},
},
}, nil
}
Expand All @@ -166,12 +179,12 @@ func MonitorDowntimeStop(ctx context.Context, state *MonitorDowntimeState, api M

resp, err := api.CancelDowntime(ctx, *state.DowntimeId)
if err != nil {
return nil, extension_kit.ToError(fmt.Sprintf("Failed to cancel Downtime (monitor %d, downtime %d). Full response: %v", state.MonitorId, *state.DowntimeId, resp), err)
return nil, extension_kit.ToError(fmt.Sprintf("Failed to cancel Downtime (monitor %d, downtime %s). Full response: %v", state.MonitorId, *state.DowntimeId, resp), err)
}

return &action_kit_api.StopResult{
Messages: &action_kit_api.Messages{
action_kit_api.Message{Level: extutil.Ptr(action_kit_api.Info), Message: fmt.Sprintf("Downtime canceled. (monitor %d, downtime %d)", state.MonitorId, *state.DowntimeId)},
action_kit_api.Message{Level: extutil.Ptr(action_kit_api.Info), Message: fmt.Sprintf("Downtime canceled. (monitor %d, downtime %s)", state.MonitorId, *state.DowntimeId)},
},
}, nil
}
18 changes: 10 additions & 8 deletions extmonitor/monitor_downtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package extmonitor

import (
"context"
"github.com/DataDog/datadog-api-client-go/v2/api/datadogV1"
"github.com/DataDog/datadog-api-client-go/v2/api/datadogV2"
"github.com/steadybit/action-kit/go/action_kit_api/v2"
"github.com/steadybit/extension-kit/extutil"
"github.com/stretchr/testify/mock"
Expand All @@ -16,12 +16,12 @@ type datadogDowntimeClientMock struct {
mock.Mock
}

func (m *datadogDowntimeClientMock) CreateDowntime(ctx context.Context, downtimeBody datadogV1.Downtime) (datadogV1.Downtime, *http.Response, error) {
func (m *datadogDowntimeClientMock) CreateDowntime(ctx context.Context, downtimeBody datadogV2.DowntimeCreateRequest) (datadogV2.DowntimeResponse, *http.Response, error) {
args := m.Called(ctx, downtimeBody)
return args.Get(0).(datadogV1.Downtime), args.Get(1).(*http.Response), args.Error(2)
return args.Get(0).(datadogV2.DowntimeResponse), args.Get(1).(*http.Response), args.Error(2)
}

func (m *datadogDowntimeClientMock) CancelDowntime(ctx context.Context, downtimeId int64) (*http.Response, error) {
func (m *datadogDowntimeClientMock) CancelDowntime(ctx context.Context, downtimeId string) (*http.Response, error) {
args := m.Called(ctx, downtimeId)
return args.Get(0).(*http.Response), args.Error(1)
}
Expand Down Expand Up @@ -62,8 +62,10 @@ func TestMonitorDowntimePrepareExtractsState(t *testing.T) {
func TestMonitorDowntimeStartSuccess(t *testing.T) {
// Given
mockedApi := new(datadogDowntimeClientMock)
mockedApi.On("CreateDowntime", mock.Anything, mock.Anything, mock.Anything).Return(datadogV1.Downtime{
Id: extutil.Ptr(int64(4711)),
mockedApi.On("CreateDowntime", mock.Anything, mock.Anything, mock.Anything).Return(datadogV2.DowntimeResponse{
Data: &datadogV2.DowntimeResponseData{
Id: extutil.Ptr("4711"),
},
}, extutil.Ptr(http.Response{
StatusCode: 200,
}), nil).Once()
Expand All @@ -82,7 +84,7 @@ func TestMonitorDowntimeStartSuccess(t *testing.T) {
// Then
require.Nil(t, err)
require.Nil(t, result.State)
require.Equal(t, int64(4711), *state.DowntimeId)
require.Equal(t, "4711", *state.DowntimeId)
require.Equal(t, "Downtime started. (monitor 1234, downtime 4711)", (*result.Messages)[0].Message)
}

Expand All @@ -98,7 +100,7 @@ func TestMonitorDowntimeStopSuccess(t *testing.T) {
state.MonitorId = 1234
state.End = time.Now().Add(time.Minute)
state.Notify = true
state.DowntimeId = extutil.Ptr(int64(4711))
state.DowntimeId = extutil.Ptr("4711")

// When
result, err := MonitorDowntimeStop(context.Background(), &state, mockedApi)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module github.com/steadybit/extension-datadog
go 1.21.0

require (
github.com/DataDog/datadog-api-client-go/v2 v2.20.0
github.com/DataDog/datadog-api-client-go/v2 v2.24.0
github.com/KimMachineGun/automemlimit v0.5.0
github.com/google/uuid v1.6.0
github.com/kelseyhightower/envconfig v1.4.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
github.com/DataDog/datadog-api-client-go/v2 v2.20.0 h1:80T+UuTh+28qODc2vw+HxzMoIu0dYBT7/RCHXxdYpJE=
github.com/DataDog/datadog-api-client-go/v2 v2.20.0/go.mod h1:oD5Lx8Li3oPRa/BSBenkn4i48z+91gwYORF/+6ph71g=
github.com/DataDog/datadog-api-client-go/v2 v2.24.0 h1:7G+eyezFM8gHq5dOHcrQcGVxrXnwPqX2yYHxsLiq3iM=
github.com/DataDog/datadog-api-client-go/v2 v2.24.0/go.mod h1:QKOu6vscsh87fMY1lHfLEmNSunyXImj8BUaUWJXOehc=
github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ=
github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
github.com/KimMachineGun/automemlimit v0.5.0 h1:BeOe+BbJc8L5chL3OwzVYjVzyvPALdd5wxVVOWuUZmQ=
Expand Down

0 comments on commit 81eafc2

Please sign in to comment.