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

[CECO-1860][DatadogGenericResource](refactor 2) Add monitor support #1641

Closed
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
3 changes: 2 additions & 1 deletion api/datadoghq/v1alpha1/datadoggenericresource_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type SupportedResourcesType string

// When adding a new type, make sure to update the kubebuilder validation enum marker
const (
Monitor SupportedResourcesType = "monitor"
Notebook SupportedResourcesType = "notebook"
SyntheticsAPITest SupportedResourcesType = "synthetics_api_test"
SyntheticsBrowserTest SupportedResourcesType = "synthetics_browser_test"
Expand All @@ -22,7 +23,7 @@ const (
// +k8s:openapi-gen=true
type DatadogGenericResourceSpec struct {
// Type is the type of the API object
// +kubebuilder:validation:Enum=notebook;synthetics_api_test;synthetics_browser_test
// +kubebuilder:validation:Enum=monitor;notebook;synthetics_api_test;synthetics_browser_test
Type SupportedResourcesType `json:"type"`
// JsonSpec is the specification of the API object
JsonSpec string `json:"jsonSpec"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
)

var allowedCustomResourcesEnumMap = map[SupportedResourcesType]string{
Monitor: "",
Notebook: "",
SyntheticsAPITest: "",
SyntheticsBrowserTest: "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ spec:
type:
description: Type is the type of the API object
enum:
- monitor
- notebook
- synthetics_api_test
- synthetics_browser_test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"type": {
"description": "Type is the type of the API object",
"enum": [
"monitor",
"notebook",
"synthetics_api_test",
"synthetics_browser_test"
Expand Down
21 changes: 10 additions & 11 deletions internal/controller/datadoggenericresource/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,23 @@ type Reconciler struct {
client client.Client
datadogSyntheticsClient *datadogV1.SyntheticsApi
datadogNotebooksClient *datadogV1.NotebooksApi
// TODO: add other clients
datadogAuth context.Context
scheme *runtime.Scheme
log logr.Logger
recorder record.EventRecorder
datadogMonitorsClient *datadogV1.MonitorsApi
datadogAuth context.Context
scheme *runtime.Scheme
log logr.Logger
recorder record.EventRecorder
}

func NewReconciler(client client.Client, ddClient datadogclient.DatadogGenericClient, scheme *runtime.Scheme, log logr.Logger, recorder record.EventRecorder) *Reconciler {
return &Reconciler{
client: client,
datadogSyntheticsClient: ddClient.SyntheticsClient,
datadogNotebooksClient: ddClient.NotebooksClient,
// TODO: add other clients
// datadogOtherClient: ddClient.OtherClient,
datadogAuth: ddClient.Auth,
scheme: scheme,
log: log,
recorder: recorder,
datadogMonitorsClient: ddClient.MonitorsClient,
datadogAuth: ddClient.Auth,
scheme: scheme,
log: log,
recorder: recorder,
}
}

Expand Down
84 changes: 84 additions & 0 deletions internal/controller/datadoggenericresource/monitors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package datadoggenericresource

import (
"context"

"github.com/DataDog/datadog-api-client-go/v2/api/datadogV1"
"github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1"
"github.com/go-logr/logr"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type MonitorHandler struct{}
type MonitorCRUDClient struct {
client *datadogV1.MonitorsApi
}

func (c *MonitorCRUDClient) createResource(auth context.Context, unmarshaledSpec any) (any, error) {
v := unmarshaledSpec.(*datadogV1.Monitor)
monitor, _, err := c.client.CreateMonitor(auth, *v)
return monitor, err
}

func (c *MonitorCRUDClient) getResource(auth context.Context, resourceStringID string) error {
monitorID, err := resourceStringToInt64ID(resourceStringID)
if err != nil {
return err
}
_, _, err = c.client.GetMonitor(auth, monitorID)
if err != nil {
return translateClientError(err, "error getting monitor")
}
return nil
}

func (c *MonitorCRUDClient) updateResource(auth context.Context, resourceStringID string, unmarshaledSpec any) (any, error) {
monitorID, err := resourceStringToInt64ID(resourceStringID)
if err != nil {
return nil, err
}
v := unmarshaledSpec.(*datadogV1.MonitorUpdateRequest)
monitor, _, err := c.client.UpdateMonitor(auth, monitorID, *v)
return monitor, err
}

func (c *MonitorCRUDClient) deleteResource(auth context.Context, resourceStringID string) error {
monitorID, err := resourceStringToInt64ID(resourceStringID)
if err != nil {
return err
}
if _, _, err = c.client.DeleteMonitor(auth, monitorID); err != nil {
return translateClientError(err, "error deleting monitor")
}
return nil
}

func (h *MonitorHandler) createResourcefunc(r *Reconciler, logger logr.Logger, instance *v1alpha1.DatadogGenericResource, status *v1alpha1.DatadogGenericResourceStatus, now metav1.Time, hash string) error {
resource, err := CreateResource(r.datadogAuth, &MonitorCRUDClient{client: r.datadogMonitorsClient}, instance)
if err != nil {
logger.Error(err, "error creating monitor")
updateErrStatus(status, now, v1alpha1.DatadogSyncStatusCreateError, "CreatingCustomResource", err)
return err
}
createdMonitor := resource.(datadogV1.Monitor)
logger.Info("created a new monitor", "monitor Id", createdMonitor.GetId())
status.Id = resourceInt64ToStringID(createdMonitor.GetId())
createdTime := metav1.NewTime(*createdMonitor.Created)
status.Created = &createdTime
status.LastForceSyncTime = &createdTime
status.Creator = *createdMonitor.GetCreator().Handle
status.SyncStatus = v1alpha1.DatadogSyncStatusOK
status.CurrentHash = hash
return nil
}

func (h *MonitorHandler) getResourcefunc(r *Reconciler, instance *v1alpha1.DatadogGenericResource) error {
return GetResource(r.datadogAuth, &MonitorCRUDClient{client: r.datadogMonitorsClient}, instance)
}
func (h *MonitorHandler) updateResourcefunc(r *Reconciler, instance *v1alpha1.DatadogGenericResource) error {
_, err := UpdateResource(r.datadogAuth, &MonitorCRUDClient{client: r.datadogMonitorsClient}, instance)
return err
}
func (h *MonitorHandler) deleteResourcefunc(r *Reconciler, instance *v1alpha1.DatadogGenericResource) error {
return DeleteResource(r.datadogAuth, &MonitorCRUDClient{client: r.datadogMonitorsClient}, instance)
}
6 changes: 6 additions & 0 deletions internal/controller/datadoggenericresource/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ func apiCreateAndUpdateStatus(r *Reconciler, logger logr.Logger, instance *v1alp

func getHandler(resourceType v1alpha1.SupportedResourcesType) ResourceHandler {
switch resourceType {
case v1alpha1.Monitor:
return &MonitorHandler{}
case v1alpha1.Notebook:
return &NotebookHandler{}
case v1alpha1.SyntheticsAPITest, v1alpha1.SyntheticsBrowserTest:
Expand All @@ -75,6 +77,8 @@ func createUnmarshaler(instance *v1alpha1.DatadogGenericResource) any {
resourceSpec := instance.Spec.JsonSpec
var result any
switch resourceType {
case v1alpha1.Monitor:
result = &datadogV1.Monitor{}
case v1alpha1.Notebook:
result = &datadogV1.NotebookCreateRequest{}
case v1alpha1.SyntheticsAPITest:
Expand Down Expand Up @@ -106,6 +110,8 @@ func updateUnmarshaler(instance *v1alpha1.DatadogGenericResource) any {
resourceSpec := instance.Spec.JsonSpec
var result any
switch resourceType {
case v1alpha1.Monitor:
result = &datadogV1.MonitorUpdateRequest{}
case v1alpha1.Notebook:
result = &datadogV1.NotebookUpdateRequest{}
case v1alpha1.SyntheticsAPITest:
Expand Down
12 changes: 9 additions & 3 deletions pkg/datadogclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ func InitDatadogDashboardClient(logger logr.Logger, creds config.Creds) (Datadog
type DatadogGenericClient struct {
SyntheticsClient *datadogV1.SyntheticsApi
NotebooksClient *datadogV1.NotebooksApi
// TODO: other clients depending on the resource
Auth context.Context
MonitorsClient *datadogV1.MonitorsApi
Auth context.Context
}

// InitDatadogGenericClient initializes the Datadog Generic API Client and establishes credentials.
Expand All @@ -112,13 +112,19 @@ func InitDatadogGenericClient(logger logr.Logger, creds config.Creds) (DatadogGe
apiClient := datadogapi.NewAPIClient(configV1)
syntheticsClient := datadogV1.NewSyntheticsApi(apiClient)
notebooksClient := datadogV1.NewNotebooksApi(apiClient)
monitorsClient := datadogV1.NewMonitorsApi(apiClient)

authV1, err := setupAuth(logger, creds)
if err != nil {
return DatadogGenericClient{}, err
}

return DatadogGenericClient{SyntheticsClient: syntheticsClient, NotebooksClient: notebooksClient, Auth: authV1}, nil
return DatadogGenericClient{
SyntheticsClient: syntheticsClient,
NotebooksClient: notebooksClient,
MonitorsClient: monitorsClient,
Auth: authV1,
}, nil
}

func setupAuth(logger logr.Logger, creds config.Creds) (context.Context, error) {
Expand Down