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

Add snooze rules resource #218

Merged
merged 5 commits into from
Apr 3, 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
2 changes: 1 addition & 1 deletion .go-version
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
1.93.2
1.94.0

2 changes: 1 addition & 1 deletion DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ Documentation files in `docs` are generated by combining:
Any edits to documentation files should be made in the `templates` directory or the .go files. Then you can use the following steps to generate the files in the docs directory:

1. Download `tfplugindocs` from https://github.com/hashicorp/terraform-plugin-docs/releases and make it available on your `PATH`
2. Run `$ make docs` or `$ tfplugindocs` from the root of this directory
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Running tfplugindocs directly doesn't work anymore because tfplugindocs builds the provider with the registry.terraform.io prefix, but then calls the terraform binary which is now open-tofu that looks for plugins with the prefix of registry.opentofu.org.

2. Run `$ make docs` from the root of this directory

Note that there is a github action that will prevent merging if the `docs` files checked in do not match the generated ones.
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Currently always builds for amd64
#PLATFORM_ARCH=$(shell uname -m | tr '[:upper:]' '[:lower:]')
PLATFORM_ARCH=amd64
PLATFORM_ARCH=$(shell uname -m | tr '[:upper:]' '[:lower:]' | sed 's/x86_64/amd64/')
PLATFORM_NAME=$(shell uname -s | tr '[:upper:]' '[:lower:]')
VERSION_TAG=$(shell cat .go-version)

Expand Down Expand Up @@ -30,8 +29,9 @@ fmt:
go fmt

.PHONY: docs
docs:
tfplugindocs
docs: build
$(MAKE) -C tfplugindocs_working generate-schema
tfplugindocs generate --providers-schema tfplugindocs_working/schema.json
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now we generate the schema separately from generating the docs to allow us bypass the tfplugindocs auto compiling the provider.


.PHONY: install-golangci-lint
install-golangci-lint:
Expand Down
206 changes: 206 additions & 0 deletions client/snooze_rules.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
package client

import (
"context"
"encoding/json"
"fmt"
"net/http"
)

type SnoozeRuleWithID struct {
SnoozeRule
ID string `json:"id"`
}

type SnoozeRule struct {
Title string `json:"title"`
Scope Scope `json:"scope"`
Schedule Schedule `json:"schedule"`
}

type Scope struct {
Basic *BasicTargeting `json:"basic,omitempty"`
}

type BasicTargeting struct {
ScopeFilters []ScopeFilter `json:"scope_filters"`
}

type ScopeFilter struct {
AlertIDs []string `json:"alert_ids"`
LabelPredicate *Predicate `json:"label_predicate"`
}

type Predicate struct {
Operator string `json:"operator"`
Labels []ResourceLabel `json:"labels"`
}

type ResourceLabel struct {
Key string `json:"key"`
Value string `json:"value"`
}

type Schedule struct {
OneTime *OneTimeSchedule `json:"one_time,omitempty"`
Recurring *RecurringSchedule `json:"recurring,omitempty"`
}

type OneTimeSchedule struct {
Timezone string `json:"timezone"`
StartDateTime string `json:"start_date_time"`
EndDateTime string `json:"end_date_time,omitempty"`
}

type RecurringSchedule struct {
Timezone string `json:"timezone"`
StartDate string `json:"start_date"`
EndDate string `json:"end_date,omitempty"`
Schedules []Reoccurrence `json:"schedules"`
}

type Reoccurrence struct {
Name string `json:"name"`
StartTime string `json:"start_time"`
DurationMillis int64 `json:"duration_millis"`
Cadence Cadence `json:"cadence"`
}

type Cadence struct {
DaysOfWeek string `json:"days_of_week"`
}

func getSnoozeRuleURL(project string, id string) string {
base := fmt.Sprintf("projects/%v/snooze_rules", project)
if id != "" {
return fmt.Sprintf("%v/%v", base, id)
}
return base
}

func getSnoozeRuleValidateURL(project string) string {
return fmt.Sprintf("projects/%v/snooze_rules_validate", project)
}

func (c *Client) CreateSnoozeRule(
ctx context.Context,
projectName string,
snoozeRule SnoozeRule) (SnoozeRuleWithID, error) {

var (
respRule SnoozeRuleWithID
resp Envelope
)

bytes, err := json.Marshal(snoozeRule)
if err != nil {
return respRule, err
}

url := getSnoozeRuleURL(projectName, "")

err = c.CallAPI(ctx, "POST", url, Envelope{Data: bytes}, &resp)
if err != nil {
return respRule, err
}

err = json.Unmarshal(resp.Data, &respRule)
if err != nil {
return respRule, err
}
return respRule, err
}

func (c *Client) UpdateSnoozeRule(
ctx context.Context,
projectName string,
id string,
snoozeRule SnoozeRule,
) (SnoozeRuleWithID, error) {
var (
respRule SnoozeRuleWithID
resp Envelope
)

bytes, err := json.Marshal(snoozeRule)
if err != nil {
return respRule, err
}

url := getSnoozeRuleURL(projectName, id)

err = c.CallAPI(ctx, "PUT", url, Envelope{Data: bytes}, &resp)
if err != nil {
return respRule, err
}

err = json.Unmarshal(resp.Data, &respRule)
if err != nil {
return respRule, err
}

return respRule, err
}

func (c *Client) GetSnoozeRule(ctx context.Context, projectName string, conditionID string) (*SnoozeRuleWithID, error) {
var (
respRule SnoozeRuleWithID
resp Envelope
)

url := getSnoozeRuleURL(projectName, conditionID)
err := c.CallAPI(ctx, "GET", url, nil, &resp)
if err != nil {
return nil, err
}

err = json.Unmarshal(resp.Data, &respRule)
if err != nil {
return nil, err
}
return &respRule, err
}

func (c *Client) DeleteSnoozeRule(ctx context.Context, projectName string, conditionID string) error {
url := getSnoozeRuleURL(projectName, conditionID)

err := c.CallAPI(ctx, "DELETE", url, nil, nil)
if err != nil {
apiClientError, ok := err.(APIResponseCarrier)
if !ok || apiClientError.GetStatusCode() != http.StatusNoContent {
return err
}
}
return nil
}

func (c *Client) ValidateSnoozeRule(ctx context.Context, projectName string, snoozeRule SnoozeRule) (bool, string, error) {
var (
resp Envelope
)

bytes, err := json.Marshal(snoozeRule)
if err != nil {
return false, "", err
}

url := getSnoozeRuleValidateURL(projectName)

err = c.CallAPI(ctx, "POST", url, Envelope{Data: bytes}, &resp)
if err != nil {
return false, "", err
}

type ValidationResponse struct {
IsValid bool `json:"is_valid"`
ValidationError string `json:"validation_error"`
}
var validationResponse ValidationResponse

err = json.Unmarshal(resp.Data, &validationResponse)
if err != nil {
return false, "", err
}

return validationResponse.IsValid, validationResponse.ValidationError, nil
}
Loading
Loading