Skip to content
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
84 changes: 82 additions & 2 deletions dynatrace/api/app/dynatrace/sitereliabilityguardian/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,8 @@
{
"customValidatorId": "builtin:universal-tag-validator",
"skipAsyncValidation": false,
"type": "CUSTOM_VALIDATOR_REF"
"type": "CUSTOM_VALIDATOR_REF",
"validatorUrl": "builtin:universal-tag-validator"
},
{
"maxLength": 500,
Expand Down Expand Up @@ -373,6 +374,27 @@
"subType": "code",
"type": "text"
},
"links": {
"description": "Fields for adding relevant links to this objective.",
"displayName": "Links",
"documentation": "",
"items": {
"description": "",
"displayName": "",
"documentation": "",
"type": {
"$ref": "#/types/ObjectiveLink"
}
},
"maxObjects": 5,
"metadata": {
"addItemButton": "Add link"
},
"minObjects": 0,
"modificationPolicy": "DEFAULT",
"nullable": false,
"type": "list"
},
"name": {
"constraints": [
{
Expand Down Expand Up @@ -466,6 +488,64 @@
"version": "0",
"versionInfo": ""
},
"ObjectiveLink": {
"description": "",
"displayName": "Objective Link",
"documentation": "",
"properties": {
"label": {
"constraints": [
{
"maxLength": 200,
"minLength": 1,
"type": "LENGTH"
}
],
"description": "Short description for the link.",
"displayName": "Display text",
"documentation": "",
"maxObjects": 1,
"modificationPolicy": "DEFAULT",
"nullable": true,
"type": "text"
},
"url": {
"constraints": [
{
"maxLength": 4096,
"type": "LENGTH"
},
{
"pattern": "^https://.*$",
"type": "PATTERN"
},
{
"customMessage": "Not a valid URI",
"pattern": "^(([^\\s:/?#]+?):){1}((//)?([^\\s/?#]+?)){1}([^\\s?#]*?)(\\?([^\\s#]*?))?(#([^\\s]*?))?$",
"type": "PATTERN"
},
{
"customMessage": "Not a valid http(s) URL",
"pattern": "^https?://.*$",
"type": "PATTERN"
}
],
"default": "",
"description": "HTTPS link associated with this objective.",
"displayName": "URL",
"documentation": "",
"maxObjects": 1,
"modificationPolicy": "DEFAULT",
"nullable": false,
"subType": "url",
"type": "text"
}
},
"summaryPattern": "{label}",
"type": "object",
"version": "0",
"versionInfo": ""
},
"Segment": {
"description": "",
"displayName": "Segment",
Expand Down Expand Up @@ -613,5 +693,5 @@
"versionInfo": ""
}
},
"version": "1.8"
"version": "1.9"
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
"github.com/dynatrace-oss/terraform-provider-dynatrace/dynatrace/settings/services/settings20"
)

const SchemaVersion = "1.8"
const SchemaVersion = "1.9"
const SchemaID = "app:dynatrace.site.reliability.guardian:guardians"

func Service(credentials *rest.Credentials) settings.CRUDService[*sitereliabilityguardian.Settings] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,13 @@ func (me *Objectives) UnmarshalHCL(decoder hcl.Decoder) error {

type Objective struct {
AutoAdaptiveThresholdEnabled *bool `json:"autoAdaptiveThresholdEnabled,omitempty"` // Enable auto adaptive threshold
ComparisonOperator ComparisonOperator `json:"comparisonOperator"` // Possible Values: `GREATER_THAN_OR_EQUAL`, `LESS_THAN_OR_EQUAL`
ComparisonOperator ComparisonOperator `json:"comparisonOperator"` // Comparison operator. Possible values: `GREATER_THAN_OR_EQUAL`, `LESS_THAN_OR_EQUAL`
Description *string `json:"description,omitempty"`
DisplayUnit *DisplayUnit `json:"displayUnit,omitempty"` // Display Unit
DqlQuery *string `json:"dqlQuery,omitempty"` // DQL query
Links ObjectiveLinks `json:"links,omitempty"` // Fields for adding relevant links to this objective.
Name string `json:"name"` // Objective name
ObjectiveType ObjectiveType `json:"objectiveType"` // Possible Values: `DQL`, `REFERENCE_SLO`
ObjectiveType ObjectiveType `json:"objectiveType"` // Objective type. Possible values: `DQL`, `REFERENCE_SLO`
ReferenceSlo *string `json:"referenceSlo,omitempty"` // Please enter the metric key of your desired SLO. SLO metric keys have to start with 'func:slo.'
Segments Segments `json:"segments,omitempty"`
Target *float64 `json:"target,omitempty"`
Expand All @@ -70,7 +71,7 @@ func (me *Objective) Schema() map[string]*schema.Schema {
},
"comparison_operator": {
Type: schema.TypeString,
Description: "Possible Values: `GREATER_THAN_OR_EQUAL`, `LESS_THAN_OR_EQUAL`",
Description: "Comparison operator. Possible values: `GREATER_THAN_OR_EQUAL`, `LESS_THAN_OR_EQUAL`",
Required: true,
},
"description": {
Expand All @@ -91,14 +92,22 @@ func (me *Objective) Schema() map[string]*schema.Schema {
Description: "DQL query",
Optional: true, // precondition
},
"links": {
Type: schema.TypeList,
Description: "Fields for adding relevant links to this objective.",
Optional: true, // minobjects == 0
Elem: &schema.Resource{Schema: new(ObjectiveLinks).Schema()},
MinItems: 1,
MaxItems: 1,
},
"name": {
Type: schema.TypeString,
Description: "Objective name",
Required: true,
},
"objective_type": {
Type: schema.TypeString,
Description: "Possible Values: `DQL`, `REFERENCE_SLO`",
Description: "Objective type. Possible values: `DQL`, `REFERENCE_SLO`",
Required: true,
},
"reference_slo": {
Expand Down Expand Up @@ -134,6 +143,7 @@ func (me *Objective) MarshalHCL(properties hcl.Properties) error {
"description": me.Description,
"display_unit": me.DisplayUnit,
"dql_query": me.DqlQuery,
"links": me.Links,
"name": me.Name,
"objective_type": me.ObjectiveType,
"reference_slo": me.ReferenceSlo,
Expand All @@ -147,12 +157,21 @@ func (me *Objective) HandlePreconditions() error {
if (me.AutoAdaptiveThresholdEnabled == nil) && (string(me.ObjectiveType) == "DQL") {
me.AutoAdaptiveThresholdEnabled = opt.NewBool(false)
}
if (me.DisplayUnit != nil) && (string(me.ObjectiveType) != "DQL") {
return fmt.Errorf("'display_unit' must not be specified if 'objective_type' is set to '%v'", me.ObjectiveType)
}
if (me.DqlQuery == nil) && (string(me.ObjectiveType) == "DQL") {
return fmt.Errorf("'dql_query' must be specified if 'objective_type' is set to '%v'", me.ObjectiveType)
}
if (me.DqlQuery != nil) && (string(me.ObjectiveType) != "DQL") {
return fmt.Errorf("'dql_query' must not be specified if 'objective_type' is set to '%v'", me.ObjectiveType)
}
if (me.ReferenceSlo == nil) && (string(me.ObjectiveType) == "REFERENCE_SLO") {
return fmt.Errorf("'reference_slo' must be specified if 'objective_type' is set to '%v'", me.ObjectiveType)
}
if (me.ReferenceSlo != nil) && (string(me.ObjectiveType) != "REFERENCE_SLO") {
return fmt.Errorf("'reference_slo' must not be specified if 'objective_type' is set to '%v'", me.ObjectiveType)
}
return nil
}

Expand All @@ -163,6 +182,7 @@ func (me *Objective) UnmarshalHCL(decoder hcl.Decoder) error {
"description": &me.Description,
"display_unit": &me.DisplayUnit,
"dql_query": &me.DqlQuery,
"links": &me.Links,
"name": &me.Name,
"objective_type": &me.ObjectiveType,
"reference_slo": &me.ReferenceSlo,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* @license
* Copyright 2026 Dynatrace LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package sitereliabilityguardian

import (
"github.com/dynatrace-oss/terraform-provider-dynatrace/terraform/hcl"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

type ObjectiveLinks []*ObjectiveLink

func (me *ObjectiveLinks) Schema() map[string]*schema.Schema {
return map[string]*schema.Schema{
"link": {
Type: schema.TypeList,
Required: true,
MinItems: 1,
MaxItems: 5,
Description: "",
Elem: &schema.Resource{Schema: new(ObjectiveLink).Schema()},
},
}
}

func (me ObjectiveLinks) MarshalHCL(properties hcl.Properties) error {
return properties.EncodeSlice("link", me)
}

func (me *ObjectiveLinks) UnmarshalHCL(decoder hcl.Decoder) error {
return decoder.DecodeSlice("link", me)
}

type ObjectiveLink struct {
Label *string `json:"label,omitempty"` // Short description for the link.
Url string `json:"url"` // HTTPS link associated with this objective.
}

func (me *ObjectiveLink) Schema() map[string]*schema.Schema {
return map[string]*schema.Schema{
"label": {
Type: schema.TypeString,
Description: "Short description for the link.",
Optional: true, // nullable
},
"url": {
Type: schema.TypeString,
Description: "HTTPS link associated with this objective.",
Required: true,
},
}
}

func (me *ObjectiveLink) MarshalHCL(properties hcl.Properties) error {
return properties.EncodeAll(map[string]any{
"label": me.Label,
"url": me.Url,
})
}

func (me *ObjectiveLink) UnmarshalHCL(decoder hcl.Decoder) error {
return decoder.DecodeAll(map[string]any{
"label": &me.Label,
"url": &me.Url,
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (

type Settings struct {
Description *string `json:"description,omitempty"` // Description
EventKind *EventKind `json:"eventKind,omitempty"` // If set to null/'BIZ_EVENT' validation events stored as bizevents in Grail. If set to 'SDLC_EVENT' validation events stored as SDLC events
EventKind *EventKind `json:"eventKind,omitempty"` // If set to null/'BIZ_EVENT' validation events stored as bizevents in Grail. If set to 'SDLC_EVENT' validation events stored as SDLC events. Possible values: `BIZ_EVENT`, `SDLC_EVENT`
Name string `json:"name"` // Name
Objectives Objectives `json:"objectives"` // Objectives
Tags []string `json:"tags,omitempty"` // Define key/value pairs that further describe this guardian.
Expand All @@ -40,7 +40,7 @@ func (me *Settings) Schema() map[string]*schema.Schema {
},
"event_kind": {
Type: schema.TypeString,
Description: "If set to null/'BIZ_EVENT' validation events stored as bizevents in Grail. If set to 'SDLC_EVENT' validation events stored as SDLC events",
Description: "If set to null/'BIZ_EVENT' validation events stored as bizevents in Grail. If set to 'SDLC_EVENT' validation events stored as SDLC events. Possible values: `BIZ_EVENT`, `SDLC_EVENT`",
Optional: true, // nullable
},
"name": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
resource "dynatrace_site_reliability_guardian" "#name#" {
name = "#name#"
tags = [ "stage:staging" ]
event_kind = "BIZ_EVENT"
objectives {
objective {
name = "Error rate"
comparison_operator = "LESS_THAN_OR_EQUAL"
dql_query =<<-EOT
fetch logs
| fieldsAdd errors = toLong(loglevel == "ERROR")
| summarize errorRate = sum(errors)/count() * 100
EOT
objective_type = "DQL"
target = 8
warning = 6
links {
link {
url = "https://www.dynatrace.com"
label = "Dynatrace"
}
}
}
objective {
name = "Count bizevents"
comparison_operator = "GREATER_THAN_OR_EQUAL"
dql_query =<<-EOT
fetch bizevents
| summarize count()
EOT
objective_type = "DQL"
target = 50
warning = 55
}
}
}
Loading