diff --git a/client/api.go b/client/api.go
index df3c3735..7c76c902 100644
--- a/client/api.go
+++ b/client/api.go
@@ -494,6 +494,37 @@ func (c *Client) GetMonitor(ctx context.Context, id string) (*meta.Monitor, erro
return c.Meta.GetMonitor(ctx, id)
}
+func (c *Client) CreateMonitorV2(ctx context.Context, workspaceId string, input *meta.MonitorV2Input) (*meta.MonitorV2, error) {
+ if !c.Flags[flagObs2110] {
+ c.obs2110.Lock()
+ defer c.obs2110.Unlock()
+ }
+ if c.Config.ManagingObjectID != nil {
+ input.ManagedById = c.Config.ManagingObjectID
+ }
+ return c.Meta.CreateMonitorV2(ctx, workspaceId, input)
+}
+
+func (c *Client) UpdateMonitorV2(ctx context.Context, id string, input *meta.MonitorV2Input) (*meta.MonitorV2, error) {
+ if !c.Flags[flagObs2110] {
+ c.obs2110.Lock()
+ defer c.obs2110.Unlock()
+ }
+ return c.Meta.UpdateMonitorV2(ctx, id, input)
+}
+
+func (c *Client) DeleteMonitorV2(ctx context.Context, id string) error {
+ if !c.Flags[flagObs2110] {
+ c.obs2110.Lock()
+ defer c.obs2110.Unlock()
+ }
+ return c.Meta.DeleteMonitorV2(ctx, id)
+}
+
+func (c *Client) GetMonitorV2(ctx context.Context, id string) (*meta.MonitorV2, error) {
+ return c.Meta.GetMonitorV2(ctx, id)
+}
+
// CreateMonitorActionAttachment creates a monitor action attachment
func (c *Client) CreateMonitorActionAttachment(ctx context.Context, input *meta.MonitorActionAttachmentInput) (*meta.MonitorActionAttachment, error) {
if !c.Flags[flagObs2110] {
diff --git a/client/internal/meta/operation/monitorv2.graphql b/client/internal/meta/operation/monitorv2.graphql
new file mode 100644
index 00000000..87d55f59
--- /dev/null
+++ b/client/internal/meta/operation/monitorv2.graphql
@@ -0,0 +1,280 @@
+# definitions of monitor v2 data
+
+fragment MonitorV2Comparison on MonitorV2Comparison {
+ compareFn
+ # @genqlient(flatten: true)
+ compareValue {
+ ...PrimitiveValue
+ }
+}
+
+fragment MonitorV2ColumnPath on MonitorV2ColumnPath {
+ name
+ path
+}
+
+fragment MonitorV2LinkColumnMeta on MonitorV2LinkColumnMeta {
+ # @genqlient(flatten: true)
+ srcFields {
+ ...MonitorV2ColumnPath
+ }
+ dstFields
+ targetDataset
+}
+
+fragment MonitorV2LinkColumn on MonitorV2LinkColumn {
+ name
+ # @genqlient(flatten: true)
+ meta {
+ ...MonitorV2LinkColumnMeta
+ }
+}
+
+fragment MonitorV2Column on MonitorV2Column {
+ # @genqlient(flatten: true)
+ linkColumn {
+ ...MonitorV2LinkColumn
+ }
+ # @genqlient(flatten: true)
+ columnPath {
+ ...MonitorV2ColumnPath
+ }
+}
+
+fragment MonitorV2ColumnComparison on MonitorV2ColumnComparison {
+ # @genqlient(flatten: true)
+ column {
+ ...MonitorV2Column
+ }
+ # @genqlient(flatten: true)
+ compareValues {
+ ...MonitorV2Comparison
+ }
+}
+
+fragment MonitorV2CountRule on MonitorV2CountRule {
+ # @genqlient(flatten: true)
+ compareValues {
+ ...MonitorV2Comparison
+ }
+ # @genqlient(flatten: true)
+ compareGroups {
+ ...MonitorV2ColumnComparison
+ }
+}
+
+fragment MonitorV2ThresholdRule on MonitorV2ThresholdRule {
+ # @genqlient(flatten: true)
+ compareValues {
+ ...MonitorV2Comparison
+ }
+ valueColumnName
+ aggregation
+ # @genqlient(flatten: true)
+ compareGroups {
+ ...MonitorV2ColumnComparison
+ }
+}
+
+fragment MonitorV2PromoteRule on MonitorV2PromoteRule {
+ # @genqlient(flatten: true)
+ compareColumns {
+ ...MonitorV2ColumnComparison
+ }
+}
+
+fragment MonitorV2Rule on MonitorV2Rule {
+ level
+ # @genqlient(flatten: true)
+ count {
+ ...MonitorV2CountRule
+ }
+ # @genqlient(flatten: true)
+ threshold {
+ ...MonitorV2ThresholdRule
+ }
+ # @genqlient(flatten: true)
+ promote {
+ ...MonitorV2PromoteRule
+ }
+}
+
+fragment MonitorV2Definition on MonitorV2Definition{
+ inputQuery {
+ outputStage
+ # @genqlient(flatten: true)
+ stages {
+ ...StageQuery
+ }
+ }
+ # @genqlient(flatten: true)
+ rules {
+ ...MonitorV2Rule
+ }
+ lookbackTime
+ dataStabilizationDelay
+ # @genqlient(flatten: true)
+ groupings {
+ ...MonitorV2Column
+ }
+ # @genqlient(flatten: true)
+ scheduling {
+ ...MonitorV2Scheduling
+ }
+}
+
+fragment MonitorV2IntervalSchedule on MonitorV2IntervalSchedule {
+ interval
+ randomize
+}
+
+fragment MonitorV2TransformSchedule on MonitorV2TransformSchedule {
+ freshnessGoal
+}
+
+fragment MonitorV2Scheduling on MonitorV2Scheduling {
+ # @genqlient(flatten: true)
+ interval {
+ ...MonitorV2IntervalSchedule
+ }
+ # @genqlient(flatten: true)
+ transform {
+ ...MonitorV2TransformSchedule
+ }
+}
+
+# @genqlient(for: "MonitorV2Input.comment", omitempty: true)
+# @genqlient(for: "MonitorV2Input.iconUrl", omitempty: true)
+# @genqlient(for: "MonitorV2Input.description", omitempty: true)
+# @genqlient(for: "MonitorV2Input.managedById", omitempty: true)
+# @genqlient(for: "MonitorV2Input.folderId", omitempty: true)
+# @genqlient(for: "MonitorV2DefinitionInput.dataStabilizationDelay", omitempty: true)
+# @genqlient(for: "MonitorV2RuleInput.count", omitempty: true)
+# @genqlient(for: "MonitorV2RuleInput.threshold", omitempty: true)
+# @genqlient(for: "MonitorV2RuleInput.promote", omitempty: true)
+# @genqlient(for: "MonitorV2ColumnInput.linkColumn", omitempty: true)
+# @genqlient(for: "MonitorV2ColumnInput.columnPath", omitempty: true)
+# @genqlient(for: "MonitorV2LinkColumnInput.meta", omitempty: true)
+# @genqlient(for: "MonitorV2ColumnPathInput.path", omitempty: true)
+# @genqlient(for: "InputDefinitionInput.stageID", omitempty: true)
+# @genqlient(for: "InputDefinitionInput.stageId", omitempty: true)
+# @genqlient(for: "StageQueryInput.stageID", omitempty: true)
+# @genqlient(for: "StageQueryInput.stageId", omitempty: true)
+# @genqlient(for: "StageQueryInput.id", omitempty: true)
+# @genqlient(for: "PrimitiveValueInput.bool", omitempty: true)
+# @genqlient(for: "PrimitiveValueInput.float64", omitempty: true)
+# @genqlient(for: "PrimitiveValueInput.int64", omitempty: true)
+# @genqlient(for: "PrimitiveValueInput.string", omitempty: true)
+# @genqlient(for: "PrimitiveValueInput.timestamp", omitempty: true)
+# @genqlient(for: "PrimitiveValueInput.duration", omitempty: true)
+fragment MonitorV2 on MonitorV2 {
+ id
+ workspaceId
+ createdBy
+ createdDate
+ name
+ iconUrl
+ description
+ managedById
+ folderId
+ comment
+ rollupStatus
+ ruleKind
+ # @genqlient(flatten: true)
+ definition {
+ ...MonitorV2Definition
+ }
+}
+
+# definitions of monitorv2 CRUD ops
+
+# @genqlient(for: "MonitorV2Input.comment", omitempty: true)
+# @genqlient(for: "MonitorV2Input.iconUrl", omitempty: true)
+# @genqlient(for: "MonitorV2Input.description", omitempty: true)
+# @genqlient(for: "MonitorV2Input.managedById", omitempty: true)
+# @genqlient(for: "MonitorV2Input.folderId", omitempty: true)
+# @genqlient(for: "MonitorV2DefinitionInput.dataStabilizationDelay", omitempty: true)
+# @genqlient(for: "MonitorV2RuleInput.count", omitempty: true)
+# @genqlient(for: "MonitorV2RuleInput.threshold", omitempty: true)
+# @genqlient(for: "MonitorV2RuleInput.promote", omitempty: true)
+# @genqlient(for: "MonitorV2ColumnInput.linkColumn", omitempty: true)
+# @genqlient(for: "MonitorV2ColumnInput.columnPath", omitempty: true)
+# @genqlient(for: "MonitorV2LinkColumnInput.meta", omitempty: true)
+# @genqlient(for: "MonitorV2ColumnPathInput.path", omitempty: true)
+# @genqlient(for: "InputDefinitionInput.stageID", omitempty: true)
+# @genqlient(for: "InputDefinitionInput.stageId", omitempty: true)
+# @genqlient(for: "StageQueryInput.stageID", omitempty: true)
+# @genqlient(for: "StageQueryInput.stageId", omitempty: true)
+# @genqlient(for: "StageQueryInput.id", omitempty: true)
+# @genqlient(for: "PrimitiveValueInput.bool", omitempty: true)
+# @genqlient(for: "PrimitiveValueInput.float64", omitempty: true)
+# @genqlient(for: "PrimitiveValueInput.int64", omitempty: true)
+# @genqlient(for: "PrimitiveValueInput.string", omitempty: true)
+# @genqlient(for: "PrimitiveValueInput.timestamp", omitempty: true)
+# @genqlient(for: "PrimitiveValueInput.duration", omitempty: true)
+mutation createMonitorV2(
+ $workspaceId: ObjectId!,
+ $input: MonitorV2Input!
+) {
+ # @genqlient(flatten: true)
+ monitorV2: createMonitorV2(workspaceId:$workspaceId, input:$input) {
+ ...MonitorV2
+ }
+}
+
+# @genqlient(for: "MonitorV2Input.comment", omitempty: true)
+# @genqlient(for: "MonitorV2Input.iconUrl", omitempty: true)
+# @genqlient(for: "MonitorV2Input.description", omitempty: true)
+# @genqlient(for: "MonitorV2Input.managedById", omitempty: true)
+# @genqlient(for: "MonitorV2Input.folderId", omitempty: true)
+# @genqlient(for: "MonitorV2DefinitionInput.dataStabilizationDelay", omitempty: true)
+# @genqlient(for: "MonitorV2RuleInput.count", omitempty: true)
+# @genqlient(for: "MonitorV2RuleInput.threshold", omitempty: true)
+# @genqlient(for: "MonitorV2RuleInput.promote", omitempty: true)
+# @genqlient(for: "MonitorV2ColumnInput.linkColumn", omitempty: true)
+# @genqlient(for: "MonitorV2ColumnInput.columnPath", omitempty: true)
+# @genqlient(for: "MonitorV2LinkColumnInput.meta", omitempty: true)
+# @genqlient(for: "MonitorV2ColumnPathInput.path", omitempty: true)
+# @genqlient(for: "InputDefinitionInput.stageID", omitempty: true)
+# @genqlient(for: "InputDefinitionInput.stageId", omitempty: true)
+# @genqlient(for: "StageQueryInput.stageID", omitempty: true)
+# @genqlient(for: "StageQueryInput.stageId", omitempty: true)
+# @genqlient(for: "StageQueryInput.id", omitempty: true)
+# @genqlient(for: "PrimitiveValueInput.bool", omitempty: true)
+# @genqlient(for: "PrimitiveValueInput.float64", omitempty: true)
+# @genqlient(for: "PrimitiveValueInput.int64", omitempty: true)
+# @genqlient(for: "PrimitiveValueInput.string", omitempty: true)
+# @genqlient(for: "PrimitiveValueInput.timestamp", omitempty: true)
+# @genqlient(for: "PrimitiveValueInput.duration", omitempty: true)
+mutation updateMonitorV2(
+ $id: ObjectId!,
+ $input: MonitorV2Input!
+) {
+ # @genqlient(flatten: true)
+ monitorV2: updateMonitorV2(id:$id, input:$input) {
+ ...MonitorV2
+ }
+}
+
+query getMonitorV2($id: ObjectId!) {
+ # @genqlient(flatten: true)
+ monitorV2: monitorV2(id: $id) {
+ ...MonitorV2
+ }
+}
+
+mutation deleteMonitorV2($id: ObjectId!) {
+ # @genqlient(flatten: true)
+ resultStatus: deleteMonitorV2(id: $id) {
+ ...ResultStatus
+ }
+}
+
+query lookupMonitorV2($workspaceId: ObjectId, $folderId: ObjectId, $nameExact: String, $nameSubstring: String) {
+ monitorV2s: searchMonitorV2(workspaceId: $workspaceId, folderId: $folderId, nameExact: $nameExact, nameSubstring: $nameSubstring) {
+ # @genqlient(flatten: true)
+ results {
+ ...MonitorV2
+ }
+ }
+}
\ No newline at end of file
diff --git a/client/internal/meta/schema/monitorv2.graphql b/client/internal/meta/schema/monitorv2.graphql
index 8d056e4f..8a252953 100644
--- a/client/internal/meta/schema/monitorv2.graphql
+++ b/client/internal/meta/schema/monitorv2.graphql
@@ -449,6 +449,7 @@ type MonitorV2Column @goModel(model: "observe/meta/metatypes.MonitorV2Column") {
Column path is any non-link typed column along with an optional path which the user wants to group by.
"""
columnPath: MonitorV2ColumnPath
+
}
input MonitorV2ColumnInput @goModel(model: "observe/meta/metatypes.MonitorV2ColumnInput") {
@@ -568,6 +569,7 @@ type MonitorV2CountRule @goModel(model: "observe/meta/metatypes.MonitorV2CountRu
(one rule for < 80 and one rule for > 90).
"""
compareValues: [MonitorV2Comparison!]!
+
"""
CompareGroups is a list of comparisons made against the columns which the monitor is grouped by.
This gives the option to add extra dimension to the existing rule by specifying which column of
@@ -620,6 +622,7 @@ input MonitorV2ThresholdRuleInput @goModel(model: "observe/meta/metatypes.Monito
# The monitor will promote each event in the raw input dataset into an alert. In order to uniquely identify
+
# and deduplicate these alerts, the groupings will help deduplicate the rows in the dataset:
# - Event Dataset: Rows can be deduplicated using the `groupings` field of the MonitorV2Definition.
# - Interval Dataset: Rows can be deduplicated using the `groupings` field of the MonitorV2Definition.
diff --git a/client/meta/genqlient.generated.go b/client/meta/genqlient.generated.go
index 3566c19b..7e21ea0b 100644
--- a/client/meta/genqlient.generated.go
+++ b/client/meta/genqlient.generated.go
@@ -4332,6 +4332,665 @@ func (v *MonitorRuleThresholdInput) GetThresholdAggFunction() *ThresholdAggFunct
// GetExpressionSummary returns MonitorRuleThresholdInput.ExpressionSummary, and is useful for accessing the field via an interface.
func (v *MonitorRuleThresholdInput) GetExpressionSummary() *string { return v.ExpressionSummary }
+// MonitorV2 includes the GraphQL fields of MonitorV2 requested by the fragment MonitorV2.
+type MonitorV2 struct {
+ Id string `json:"id"`
+ WorkspaceId string `json:"workspaceId"`
+ CreatedBy types.UserIdScalar `json:"createdBy"`
+ CreatedDate types.TimeScalar `json:"createdDate"`
+ Name string `json:"name"`
+ IconUrl *string `json:"iconUrl"`
+ Description *string `json:"description"`
+ ManagedById *string `json:"managedById"`
+ FolderId string `json:"folderId"`
+ // A longer description of the monitor.
+ // This can include details like how to resolve the issue, links to runbooks, etc.
+ Comment *string `json:"comment"`
+ RollupStatus MonitorV2RollupStatus `json:"rollupStatus"`
+ // Describes the type of each of the rules in the definition (they must all be the same type).
+ RuleKind MonitorV2RuleKind `json:"ruleKind"`
+ Definition MonitorV2Definition `json:"definition"`
+}
+
+// GetId returns MonitorV2.Id, and is useful for accessing the field via an interface.
+func (v *MonitorV2) GetId() string { return v.Id }
+
+// GetWorkspaceId returns MonitorV2.WorkspaceId, and is useful for accessing the field via an interface.
+func (v *MonitorV2) GetWorkspaceId() string { return v.WorkspaceId }
+
+// GetCreatedBy returns MonitorV2.CreatedBy, and is useful for accessing the field via an interface.
+func (v *MonitorV2) GetCreatedBy() types.UserIdScalar { return v.CreatedBy }
+
+// GetCreatedDate returns MonitorV2.CreatedDate, and is useful for accessing the field via an interface.
+func (v *MonitorV2) GetCreatedDate() types.TimeScalar { return v.CreatedDate }
+
+// GetName returns MonitorV2.Name, and is useful for accessing the field via an interface.
+func (v *MonitorV2) GetName() string { return v.Name }
+
+// GetIconUrl returns MonitorV2.IconUrl, and is useful for accessing the field via an interface.
+func (v *MonitorV2) GetIconUrl() *string { return v.IconUrl }
+
+// GetDescription returns MonitorV2.Description, and is useful for accessing the field via an interface.
+func (v *MonitorV2) GetDescription() *string { return v.Description }
+
+// GetManagedById returns MonitorV2.ManagedById, and is useful for accessing the field via an interface.
+func (v *MonitorV2) GetManagedById() *string { return v.ManagedById }
+
+// GetFolderId returns MonitorV2.FolderId, and is useful for accessing the field via an interface.
+func (v *MonitorV2) GetFolderId() string { return v.FolderId }
+
+// GetComment returns MonitorV2.Comment, and is useful for accessing the field via an interface.
+func (v *MonitorV2) GetComment() *string { return v.Comment }
+
+// GetRollupStatus returns MonitorV2.RollupStatus, and is useful for accessing the field via an interface.
+func (v *MonitorV2) GetRollupStatus() MonitorV2RollupStatus { return v.RollupStatus }
+
+// GetRuleKind returns MonitorV2.RuleKind, and is useful for accessing the field via an interface.
+func (v *MonitorV2) GetRuleKind() MonitorV2RuleKind { return v.RuleKind }
+
+// GetDefinition returns MonitorV2.Definition, and is useful for accessing the field via an interface.
+func (v *MonitorV2) GetDefinition() MonitorV2Definition { return v.Definition }
+
+type MonitorV2AlarmLevel string
+
+const (
+ MonitorV2AlarmLevelCritical MonitorV2AlarmLevel = "Critical"
+ MonitorV2AlarmLevelError MonitorV2AlarmLevel = "Error"
+ MonitorV2AlarmLevelInformational MonitorV2AlarmLevel = "Informational"
+ MonitorV2AlarmLevelNone MonitorV2AlarmLevel = "None"
+ MonitorV2AlarmLevelWarning MonitorV2AlarmLevel = "Warning"
+)
+
+// MonitorV2Column includes the GraphQL fields of MonitorV2Column requested by the fragment MonitorV2Column.
+type MonitorV2Column struct {
+ // Link Column is for link typed column which the user wants to group by.
+ LinkColumn *MonitorV2LinkColumn `json:"linkColumn"`
+ // Column path is any non-link typed column along with an optional path which the user wants to group by.
+ ColumnPath *MonitorV2ColumnPath `json:"columnPath"`
+}
+
+// GetLinkColumn returns MonitorV2Column.LinkColumn, and is useful for accessing the field via an interface.
+func (v *MonitorV2Column) GetLinkColumn() *MonitorV2LinkColumn { return v.LinkColumn }
+
+// GetColumnPath returns MonitorV2Column.ColumnPath, and is useful for accessing the field via an interface.
+func (v *MonitorV2Column) GetColumnPath() *MonitorV2ColumnPath { return v.ColumnPath }
+
+// MonitorV2ColumnComparison includes the GraphQL fields of MonitorV2ColumnComparison requested by the fragment MonitorV2ColumnComparison.
+type MonitorV2ColumnComparison struct {
+ // The column user wants to compare against using the values inside compareValues.
+ Column MonitorV2Column `json:"column"`
+ // CompareValues is a list of comparisons that provide an implicit AND where all comparisons must match.
+ // This gives the option to specify one value for a threshold behavior (trigger if > 80) but also allows
+ // for ranges of validity. If you want to trigger inside a range, give two compares here (like > 80 and < 90).
+ // If you want to trigger outside a valid range, use two rules with a single compare to get the implied OR
+ // (one rule for < 80 and one rule for > 90).
+ CompareValues []MonitorV2Comparison `json:"compareValues"`
+}
+
+// GetColumn returns MonitorV2ColumnComparison.Column, and is useful for accessing the field via an interface.
+func (v *MonitorV2ColumnComparison) GetColumn() MonitorV2Column { return v.Column }
+
+// GetCompareValues returns MonitorV2ColumnComparison.CompareValues, and is useful for accessing the field via an interface.
+func (v *MonitorV2ColumnComparison) GetCompareValues() []MonitorV2Comparison { return v.CompareValues }
+
+type MonitorV2ColumnComparisonInput struct {
+ CompareValues []MonitorV2ComparisonInput `json:"compareValues"`
+ Column MonitorV2ColumnInput `json:"column"`
+}
+
+// GetCompareValues returns MonitorV2ColumnComparisonInput.CompareValues, and is useful for accessing the field via an interface.
+func (v *MonitorV2ColumnComparisonInput) GetCompareValues() []MonitorV2ComparisonInput {
+ return v.CompareValues
+}
+
+// GetColumn returns MonitorV2ColumnComparisonInput.Column, and is useful for accessing the field via an interface.
+func (v *MonitorV2ColumnComparisonInput) GetColumn() MonitorV2ColumnInput { return v.Column }
+
+type MonitorV2ColumnInput struct {
+ LinkColumn *MonitorV2LinkColumnInput `json:"linkColumn,omitempty"`
+ ColumnPath *MonitorV2ColumnPathInput `json:"columnPath,omitempty"`
+}
+
+// GetLinkColumn returns MonitorV2ColumnInput.LinkColumn, and is useful for accessing the field via an interface.
+func (v *MonitorV2ColumnInput) GetLinkColumn() *MonitorV2LinkColumnInput { return v.LinkColumn }
+
+// GetColumnPath returns MonitorV2ColumnInput.ColumnPath, and is useful for accessing the field via an interface.
+func (v *MonitorV2ColumnInput) GetColumnPath() *MonitorV2ColumnPathInput { return v.ColumnPath }
+
+// MonitorV2ColumnPath includes the GraphQL fields of MonitorV2ColumnPath requested by the fragment MonitorV2ColumnPath.
+type MonitorV2ColumnPath struct {
+ Name string `json:"name"`
+ Path *string `json:"path"`
+}
+
+// GetName returns MonitorV2ColumnPath.Name, and is useful for accessing the field via an interface.
+func (v *MonitorV2ColumnPath) GetName() string { return v.Name }
+
+// GetPath returns MonitorV2ColumnPath.Path, and is useful for accessing the field via an interface.
+func (v *MonitorV2ColumnPath) GetPath() *string { return v.Path }
+
+type MonitorV2ColumnPathInput struct {
+ Name string `json:"name"`
+ Path *string `json:"path,omitempty"`
+}
+
+// GetName returns MonitorV2ColumnPathInput.Name, and is useful for accessing the field via an interface.
+func (v *MonitorV2ColumnPathInput) GetName() string { return v.Name }
+
+// GetPath returns MonitorV2ColumnPathInput.Path, and is useful for accessing the field via an interface.
+func (v *MonitorV2ColumnPathInput) GetPath() *string { return v.Path }
+
+// MonitorV2Comparison includes the GraphQL fields of MonitorV2Comparison requested by the fragment MonitorV2Comparison.
+type MonitorV2Comparison struct {
+ CompareFn MonitorV2ComparisonFunction `json:"compareFn"`
+ // compareValue is the right-side value for comparisons that use it (like x > 10, this is 10).
+ CompareValue PrimitiveValue `json:"compareValue"`
+}
+
+// GetCompareFn returns MonitorV2Comparison.CompareFn, and is useful for accessing the field via an interface.
+func (v *MonitorV2Comparison) GetCompareFn() MonitorV2ComparisonFunction { return v.CompareFn }
+
+// GetCompareValue returns MonitorV2Comparison.CompareValue, and is useful for accessing the field via an interface.
+func (v *MonitorV2Comparison) GetCompareValue() PrimitiveValue { return v.CompareValue }
+
+type MonitorV2ComparisonFunction string
+
+const (
+ MonitorV2ComparisonFunctionEqual MonitorV2ComparisonFunction = "Equal"
+ MonitorV2ComparisonFunctionGreater MonitorV2ComparisonFunction = "Greater"
+ MonitorV2ComparisonFunctionGreaterorequal MonitorV2ComparisonFunction = "GreaterOrEqual"
+ MonitorV2ComparisonFunctionLess MonitorV2ComparisonFunction = "Less"
+ MonitorV2ComparisonFunctionLessorequal MonitorV2ComparisonFunction = "LessOrEqual"
+ MonitorV2ComparisonFunctionNotequal MonitorV2ComparisonFunction = "NotEqual"
+)
+
+type MonitorV2ComparisonInput struct {
+ CompareFn MonitorV2ComparisonFunction `json:"compareFn"`
+ CompareValue PrimitiveValueInput `json:"compareValue"`
+}
+
+// GetCompareFn returns MonitorV2ComparisonInput.CompareFn, and is useful for accessing the field via an interface.
+func (v *MonitorV2ComparisonInput) GetCompareFn() MonitorV2ComparisonFunction { return v.CompareFn }
+
+// GetCompareValue returns MonitorV2ComparisonInput.CompareValue, and is useful for accessing the field via an interface.
+func (v *MonitorV2ComparisonInput) GetCompareValue() PrimitiveValueInput { return v.CompareValue }
+
+// MonitorV2CountRule includes the GraphQL fields of MonitorV2CountRule requested by the fragment MonitorV2CountRule.
+type MonitorV2CountRule struct {
+ // CompareValues is a list of comparisons that provide an implicit AND where all comparisons must match.
+ // This gives the option to specify
+ // one value for a threshold behavior (trigger if > 80) but also allows for ranges of validity. If you want
+ // to trigger inside a range, give two compares here (like > 80 and < 90). If you want to trigger
+ // outside a valid range, use two rules with a single compare to get the implied OR
+ // (one rule for < 80 and one rule for > 90).
+ CompareValues []MonitorV2Comparison `json:"compareValues"`
+ // CompareGroups is a list of comparisons made against the columns which the monitor is grouped by.
+ // This gives the option to add extra dimension to the existing rule by specifying which column of
+ // the group the user looks forward to being alerted by. For example, this allows for rule expression
+ // like (Count > 80 and Group = "Good Group") which would trigger a critical alert.
+ CompareGroups []MonitorV2ColumnComparison `json:"compareGroups"`
+}
+
+// GetCompareValues returns MonitorV2CountRule.CompareValues, and is useful for accessing the field via an interface.
+func (v *MonitorV2CountRule) GetCompareValues() []MonitorV2Comparison { return v.CompareValues }
+
+// GetCompareGroups returns MonitorV2CountRule.CompareGroups, and is useful for accessing the field via an interface.
+func (v *MonitorV2CountRule) GetCompareGroups() []MonitorV2ColumnComparison { return v.CompareGroups }
+
+type MonitorV2CountRuleInput struct {
+ CompareValues []MonitorV2ComparisonInput `json:"compareValues"`
+ CompareGroups []MonitorV2ColumnComparisonInput `json:"compareGroups"`
+}
+
+// GetCompareValues returns MonitorV2CountRuleInput.CompareValues, and is useful for accessing the field via an interface.
+func (v *MonitorV2CountRuleInput) GetCompareValues() []MonitorV2ComparisonInput {
+ return v.CompareValues
+}
+
+// GetCompareGroups returns MonitorV2CountRuleInput.CompareGroups, and is useful for accessing the field via an interface.
+func (v *MonitorV2CountRuleInput) GetCompareGroups() []MonitorV2ColumnComparisonInput {
+ return v.CompareGroups
+}
+
+// MonitorV2Definition includes the GraphQL fields of MonitorV2Definition requested by the fragment MonitorV2Definition.
+type MonitorV2Definition struct {
+ // InputQuery is the MultiStageQuery that defines the input feed of data for this monitor. It will include the
+ // original dataset(s) and other transform information that the user selected to create "Create Monitor".
+ InputQuery MonitorV2DefinitionInputQueryMultiStageQuery `json:"inputQuery"`
+ // Rules are one or more instances of a MonitorV2Rule, which all must be of the same MonitorRuleKind
+ // as specified in `ruleKind`.
+ // Rules should be constructed logically such that a state transition from null->Warning implies a
+ // transition from null->Informational as well.
+ Rules []MonitorV2Rule `json:"rules"`
+ // LookbackTime optionally describes a duration that must be satisifed by this monitor. It applies to all rules,
+ // but is only applicable to rule kinds that utilize it.
+ LookbackTime *types.DurationScalar `json:"lookbackTime"`
+ // DataStabilizationDelay expresses the minimum time that should elapse before data is considered "good enough"
+ // to evaluate. Choosing a delay really depends on the expectations of latency of data and whether data is expected
+ // to arrive later than other data and thus would change previously evaluated results. Another way to think of this
+ // value is defining where the "Ragged Right Edge" starts relative to the clock.
+ DataStabilizationDelay *types.DurationScalar `json:"dataStabilizationDelay"`
+ // Groupings describes the groups that logically separate events/rows/etc from each other.
+ // When the input monitor dataset is of type resource and the monitor strategy is of type promote, this field should
+ // either be left empty to be mutated with the primary keys of the resource dataset or it should only contain the
+ // primary keys of the dataset.
+ Groupings []MonitorV2Column `json:"groupings"`
+ // Scheduling controls how often the monitor is evaluated. The default behavior when you do
+ // not specify this field is a real-time transform monitor with a default freshness goal that
+ // you cannot control.
+ Scheduling *MonitorV2Scheduling `json:"scheduling"`
+}
+
+// GetInputQuery returns MonitorV2Definition.InputQuery, and is useful for accessing the field via an interface.
+func (v *MonitorV2Definition) GetInputQuery() MonitorV2DefinitionInputQueryMultiStageQuery {
+ return v.InputQuery
+}
+
+// GetRules returns MonitorV2Definition.Rules, and is useful for accessing the field via an interface.
+func (v *MonitorV2Definition) GetRules() []MonitorV2Rule { return v.Rules }
+
+// GetLookbackTime returns MonitorV2Definition.LookbackTime, and is useful for accessing the field via an interface.
+func (v *MonitorV2Definition) GetLookbackTime() *types.DurationScalar { return v.LookbackTime }
+
+// GetDataStabilizationDelay returns MonitorV2Definition.DataStabilizationDelay, and is useful for accessing the field via an interface.
+func (v *MonitorV2Definition) GetDataStabilizationDelay() *types.DurationScalar {
+ return v.DataStabilizationDelay
+}
+
+// GetGroupings returns MonitorV2Definition.Groupings, and is useful for accessing the field via an interface.
+func (v *MonitorV2Definition) GetGroupings() []MonitorV2Column { return v.Groupings }
+
+// GetScheduling returns MonitorV2Definition.Scheduling, and is useful for accessing the field via an interface.
+func (v *MonitorV2Definition) GetScheduling() *MonitorV2Scheduling { return v.Scheduling }
+
+type MonitorV2DefinitionInput struct {
+ InputQuery MultiStageQueryInput `json:"inputQuery"`
+ Rules []MonitorV2RuleInput `json:"rules"`
+ LookbackTime *types.DurationScalar `json:"lookbackTime"`
+ DataStabilizationDelay *types.DurationScalar `json:"dataStabilizationDelay,omitempty"`
+ Groupings []MonitorV2ColumnInput `json:"groupings"`
+ Scheduling *MonitorV2SchedulingInput `json:"scheduling"`
+}
+
+// GetInputQuery returns MonitorV2DefinitionInput.InputQuery, and is useful for accessing the field via an interface.
+func (v *MonitorV2DefinitionInput) GetInputQuery() MultiStageQueryInput { return v.InputQuery }
+
+// GetRules returns MonitorV2DefinitionInput.Rules, and is useful for accessing the field via an interface.
+func (v *MonitorV2DefinitionInput) GetRules() []MonitorV2RuleInput { return v.Rules }
+
+// GetLookbackTime returns MonitorV2DefinitionInput.LookbackTime, and is useful for accessing the field via an interface.
+func (v *MonitorV2DefinitionInput) GetLookbackTime() *types.DurationScalar { return v.LookbackTime }
+
+// GetDataStabilizationDelay returns MonitorV2DefinitionInput.DataStabilizationDelay, and is useful for accessing the field via an interface.
+func (v *MonitorV2DefinitionInput) GetDataStabilizationDelay() *types.DurationScalar {
+ return v.DataStabilizationDelay
+}
+
+// GetGroupings returns MonitorV2DefinitionInput.Groupings, and is useful for accessing the field via an interface.
+func (v *MonitorV2DefinitionInput) GetGroupings() []MonitorV2ColumnInput { return v.Groupings }
+
+// GetScheduling returns MonitorV2DefinitionInput.Scheduling, and is useful for accessing the field via an interface.
+func (v *MonitorV2DefinitionInput) GetScheduling() *MonitorV2SchedulingInput { return v.Scheduling }
+
+// MonitorV2DefinitionInputQueryMultiStageQuery includes the requested fields of the GraphQL type MultiStageQuery.
+type MonitorV2DefinitionInputQueryMultiStageQuery struct {
+ OutputStage string `json:"outputStage"`
+ Stages []StageQuery `json:"stages"`
+}
+
+// GetOutputStage returns MonitorV2DefinitionInputQueryMultiStageQuery.OutputStage, and is useful for accessing the field via an interface.
+func (v *MonitorV2DefinitionInputQueryMultiStageQuery) GetOutputStage() string { return v.OutputStage }
+
+// GetStages returns MonitorV2DefinitionInputQueryMultiStageQuery.Stages, and is useful for accessing the field via an interface.
+func (v *MonitorV2DefinitionInputQueryMultiStageQuery) GetStages() []StageQuery { return v.Stages }
+
+type MonitorV2Input struct {
+ Comment *string `json:"comment,omitempty"`
+ Definition MonitorV2DefinitionInput `json:"definition"`
+ RuleKind MonitorV2RuleKind `json:"ruleKind"`
+ Name string `json:"name"`
+ IconUrl *string `json:"iconUrl,omitempty"`
+ Description *string `json:"description,omitempty"`
+ ManagedById *string `json:"managedById,omitempty"`
+ FolderId *string `json:"folderId,omitempty"`
+}
+
+// GetComment returns MonitorV2Input.Comment, and is useful for accessing the field via an interface.
+func (v *MonitorV2Input) GetComment() *string { return v.Comment }
+
+// GetDefinition returns MonitorV2Input.Definition, and is useful for accessing the field via an interface.
+func (v *MonitorV2Input) GetDefinition() MonitorV2DefinitionInput { return v.Definition }
+
+// GetRuleKind returns MonitorV2Input.RuleKind, and is useful for accessing the field via an interface.
+func (v *MonitorV2Input) GetRuleKind() MonitorV2RuleKind { return v.RuleKind }
+
+// GetName returns MonitorV2Input.Name, and is useful for accessing the field via an interface.
+func (v *MonitorV2Input) GetName() string { return v.Name }
+
+// GetIconUrl returns MonitorV2Input.IconUrl, and is useful for accessing the field via an interface.
+func (v *MonitorV2Input) GetIconUrl() *string { return v.IconUrl }
+
+// GetDescription returns MonitorV2Input.Description, and is useful for accessing the field via an interface.
+func (v *MonitorV2Input) GetDescription() *string { return v.Description }
+
+// GetManagedById returns MonitorV2Input.ManagedById, and is useful for accessing the field via an interface.
+func (v *MonitorV2Input) GetManagedById() *string { return v.ManagedById }
+
+// GetFolderId returns MonitorV2Input.FolderId, and is useful for accessing the field via an interface.
+func (v *MonitorV2Input) GetFolderId() *string { return v.FolderId }
+
+// MonitorV2IntervalSchedule includes the GraphQL fields of MonitorV2IntervalSchedule requested by the fragment MonitorV2IntervalSchedule.
+type MonitorV2IntervalSchedule struct {
+ // Interval is how often the monitor should attempt to run. This interval describes when the
+ // monitor enters the queue, but is not a guarantee of execution. Monitors are best-effort
+ // and also may be subject to QoS or rate limiting in the future.
+ Interval types.DurationScalar `json:"interval"`
+ // Randomize is a maximum +/- to apply to the interval to avoid things like harmonics and
+ // work stacking up in parallel. If interval is "10m" and randomize is "30s", then a random
+ // interval between 9m30s and 10m30s will be selected each run.
+ Randomize types.DurationScalar `json:"randomize"`
+}
+
+// GetInterval returns MonitorV2IntervalSchedule.Interval, and is useful for accessing the field via an interface.
+func (v *MonitorV2IntervalSchedule) GetInterval() types.DurationScalar { return v.Interval }
+
+// GetRandomize returns MonitorV2IntervalSchedule.Randomize, and is useful for accessing the field via an interface.
+func (v *MonitorV2IntervalSchedule) GetRandomize() types.DurationScalar { return v.Randomize }
+
+type MonitorV2IntervalScheduleInput struct {
+ Interval types.DurationScalar `json:"interval"`
+ Randomize types.DurationScalar `json:"randomize"`
+}
+
+// GetInterval returns MonitorV2IntervalScheduleInput.Interval, and is useful for accessing the field via an interface.
+func (v *MonitorV2IntervalScheduleInput) GetInterval() types.DurationScalar { return v.Interval }
+
+// GetRandomize returns MonitorV2IntervalScheduleInput.Randomize, and is useful for accessing the field via an interface.
+func (v *MonitorV2IntervalScheduleInput) GetRandomize() types.DurationScalar { return v.Randomize }
+
+// MonitorV2LinkColumn includes the GraphQL fields of MonitorV2LinkColumn requested by the fragment MonitorV2LinkColumn.
+type MonitorV2LinkColumn struct {
+ Name string `json:"name"`
+ // Any context surrounding the link column as part of the MonitorV2Alarm will be described here. This column
+ // will include the source dataset's and the target dataset's columns linked together to create the current
+ // link column.
+ Meta *MonitorV2LinkColumnMeta `json:"meta"`
+}
+
+// GetName returns MonitorV2LinkColumn.Name, and is useful for accessing the field via an interface.
+func (v *MonitorV2LinkColumn) GetName() string { return v.Name }
+
+// GetMeta returns MonitorV2LinkColumn.Meta, and is useful for accessing the field via an interface.
+func (v *MonitorV2LinkColumn) GetMeta() *MonitorV2LinkColumnMeta { return v.Meta }
+
+type MonitorV2LinkColumnInput struct {
+ Name string `json:"name"`
+ Meta *MonitorV2LinkColumnMetaInput `json:"meta,omitempty"`
+}
+
+// GetName returns MonitorV2LinkColumnInput.Name, and is useful for accessing the field via an interface.
+func (v *MonitorV2LinkColumnInput) GetName() string { return v.Name }
+
+// GetMeta returns MonitorV2LinkColumnInput.Meta, and is useful for accessing the field via an interface.
+func (v *MonitorV2LinkColumnInput) GetMeta() *MonitorV2LinkColumnMetaInput { return v.Meta }
+
+// MonitorV2LinkColumnMeta includes the GraphQL fields of MonitorV2LinkColumnMeta requested by the fragment MonitorV2LinkColumnMeta.
+type MonitorV2LinkColumnMeta struct {
+ // List of source fields used to link against the primary keys of the target dataset.
+ // Frontend only needs to provide the input for this field when it wants a preview of the template fields.
+ SrcFields []MonitorV2ColumnPath `json:"srcFields"`
+ // List of destination fields (a.k.a. primary keys) of the target dataset being linked against.
+ // Frontend only needs to provide the input for this field when it wants a preview of the template fields.
+ DstFields []string `json:"dstFields"`
+ // The target dataset is the resource dataset id which the link came from. If the link was created from a stage in
+ // the shape of a resource from the worksheet, this field will be empty as there's no resource dataset to point to.
+ // Frontend only needs to provide the input for this field when it wants a preview of the template fields.
+ TargetDataset *types.Int64Scalar `json:"targetDataset"`
+}
+
+// GetSrcFields returns MonitorV2LinkColumnMeta.SrcFields, and is useful for accessing the field via an interface.
+func (v *MonitorV2LinkColumnMeta) GetSrcFields() []MonitorV2ColumnPath { return v.SrcFields }
+
+// GetDstFields returns MonitorV2LinkColumnMeta.DstFields, and is useful for accessing the field via an interface.
+func (v *MonitorV2LinkColumnMeta) GetDstFields() []string { return v.DstFields }
+
+// GetTargetDataset returns MonitorV2LinkColumnMeta.TargetDataset, and is useful for accessing the field via an interface.
+func (v *MonitorV2LinkColumnMeta) GetTargetDataset() *types.Int64Scalar { return v.TargetDataset }
+
+type MonitorV2LinkColumnMetaInput struct {
+ SrcFields []MonitorV2ColumnPathInput `json:"srcFields"`
+ DstFields []string `json:"dstFields"`
+ TargetDataset *types.Int64Scalar `json:"targetDataset"`
+}
+
+// GetSrcFields returns MonitorV2LinkColumnMetaInput.SrcFields, and is useful for accessing the field via an interface.
+func (v *MonitorV2LinkColumnMetaInput) GetSrcFields() []MonitorV2ColumnPathInput { return v.SrcFields }
+
+// GetDstFields returns MonitorV2LinkColumnMetaInput.DstFields, and is useful for accessing the field via an interface.
+func (v *MonitorV2LinkColumnMetaInput) GetDstFields() []string { return v.DstFields }
+
+// GetTargetDataset returns MonitorV2LinkColumnMetaInput.TargetDataset, and is useful for accessing the field via an interface.
+func (v *MonitorV2LinkColumnMetaInput) GetTargetDataset() *types.Int64Scalar { return v.TargetDataset }
+
+// MonitorV2PromoteRule includes the GraphQL fields of MonitorV2PromoteRule requested by the fragment MonitorV2PromoteRule.
+type MonitorV2PromoteRule struct {
+ // If this field has been specified, it means there are values in the columns that we want to assign severity by.
+ // When multiple column comparisons are specified within one promote rule, it will act as an AND condition. When defined
+ // through separate promote rules, it will be treated as an OR condition.
+ // If the field is left as an empty array by the frontend, all the rows of the dataset will be considered as an alert.
+ // For example, if the field is left empty and the level of the MonitorV2Rule is set at critical, all the rows of the dataset
+ // will be treated as a critical alert.
+ CompareColumns []MonitorV2ColumnComparison `json:"compareColumns"`
+}
+
+// GetCompareColumns returns MonitorV2PromoteRule.CompareColumns, and is useful for accessing the field via an interface.
+func (v *MonitorV2PromoteRule) GetCompareColumns() []MonitorV2ColumnComparison {
+ return v.CompareColumns
+}
+
+type MonitorV2PromoteRuleInput struct {
+ CompareColumns []MonitorV2ColumnComparisonInput `json:"compareColumns"`
+}
+
+// GetCompareColumns returns MonitorV2PromoteRuleInput.CompareColumns, and is useful for accessing the field via an interface.
+func (v *MonitorV2PromoteRuleInput) GetCompareColumns() []MonitorV2ColumnComparisonInput {
+ return v.CompareColumns
+}
+
+// MonitorV2RollupStatus is a convenience indicator of how to perceive the state of the monitor.
+// This value is derived entirely using existing data in other fields, but
+// encapsultes those inspections into a single priority-based status.
+// Some status indicators are not exclusive with others so, for example, a monitor that is "Triggering"
+// may also be "Degraded" because of underlying warnings.
+// This priority-sorted rollup is just to let the user prioritize and sort things in the UI in an order
+// we define as most sensible. This ordering can be changed as needed.
+// In descending order of priority, the values are:
+// - Inactive: The monitor is not running because it is disabled or because the system has deactivated it due to chronic failures.
+// - Failed: The last attempt to run the monitor had fatal errors (it cannot trigger).
+// - Triggering: The last evaluation had still-active alarms, or new one-shot alarms.
+// - Degraded: The last evaluation had warnings, but evaluation completed and no alarms were detected.
+// - Running: The default state. If no other status is indicated, the monitor is running.
+type MonitorV2RollupStatus string
+
+const (
+ MonitorV2RollupStatusDegraded MonitorV2RollupStatus = "Degraded"
+ MonitorV2RollupStatusFailed MonitorV2RollupStatus = "Failed"
+ MonitorV2RollupStatusInactive MonitorV2RollupStatus = "Inactive"
+ MonitorV2RollupStatusRunning MonitorV2RollupStatus = "Running"
+ MonitorV2RollupStatusTriggering MonitorV2RollupStatus = "Triggering"
+)
+
+// MonitorV2Rule includes the GraphQL fields of MonitorV2Rule requested by the fragment MonitorV2Rule.
+type MonitorV2Rule struct {
+ // Level is the severity level to assign to a rule's conditions being matched.
+ Level MonitorV2AlarmLevel `json:"level"`
+ Count *MonitorV2CountRule `json:"count"`
+ Threshold *MonitorV2ThresholdRule `json:"threshold"`
+ Promote *MonitorV2PromoteRule `json:"promote"`
+}
+
+// GetLevel returns MonitorV2Rule.Level, and is useful for accessing the field via an interface.
+func (v *MonitorV2Rule) GetLevel() MonitorV2AlarmLevel { return v.Level }
+
+// GetCount returns MonitorV2Rule.Count, and is useful for accessing the field via an interface.
+func (v *MonitorV2Rule) GetCount() *MonitorV2CountRule { return v.Count }
+
+// GetThreshold returns MonitorV2Rule.Threshold, and is useful for accessing the field via an interface.
+func (v *MonitorV2Rule) GetThreshold() *MonitorV2ThresholdRule { return v.Threshold }
+
+// GetPromote returns MonitorV2Rule.Promote, and is useful for accessing the field via an interface.
+func (v *MonitorV2Rule) GetPromote() *MonitorV2PromoteRule { return v.Promote }
+
+type MonitorV2RuleInput struct {
+ Level MonitorV2AlarmLevel `json:"level"`
+ Count *MonitorV2CountRuleInput `json:"count,omitempty"`
+ Threshold *MonitorV2ThresholdRuleInput `json:"threshold,omitempty"`
+ Promote *MonitorV2PromoteRuleInput `json:"promote,omitempty"`
+}
+
+// GetLevel returns MonitorV2RuleInput.Level, and is useful for accessing the field via an interface.
+func (v *MonitorV2RuleInput) GetLevel() MonitorV2AlarmLevel { return v.Level }
+
+// GetCount returns MonitorV2RuleInput.Count, and is useful for accessing the field via an interface.
+func (v *MonitorV2RuleInput) GetCount() *MonitorV2CountRuleInput { return v.Count }
+
+// GetThreshold returns MonitorV2RuleInput.Threshold, and is useful for accessing the field via an interface.
+func (v *MonitorV2RuleInput) GetThreshold() *MonitorV2ThresholdRuleInput { return v.Threshold }
+
+// GetPromote returns MonitorV2RuleInput.Promote, and is useful for accessing the field via an interface.
+func (v *MonitorV2RuleInput) GetPromote() *MonitorV2PromoteRuleInput { return v.Promote }
+
+// MonitorV2RuleKind describes the strategy used to inspect the input query.
+// - Count is used when what you care to inspect is the number of rows/instances
+// in the query result.
+// - Threshold is when you want to inspect a numerical value within the query
+// results, not the presence of the rows themselves.
+type MonitorV2RuleKind string
+
+const (
+ MonitorV2RuleKindCount MonitorV2RuleKind = "Count"
+ MonitorV2RuleKindPromote MonitorV2RuleKind = "Promote"
+ MonitorV2RuleKindThreshold MonitorV2RuleKind = "Threshold"
+)
+
+// MonitorV2Scheduling includes the GraphQL fields of MonitorV2Scheduling requested by the fragment MonitorV2Scheduling.
+type MonitorV2Scheduling struct {
+ // Interval should be used to run explicit ad-hoc queries.
+ Interval *MonitorV2IntervalSchedule `json:"interval"`
+ // Transform should be used to defer scheduling to the transformer and evaluate when data becomes
+ // available.
+ Transform *MonitorV2TransformSchedule `json:"transform"`
+}
+
+// GetInterval returns MonitorV2Scheduling.Interval, and is useful for accessing the field via an interface.
+func (v *MonitorV2Scheduling) GetInterval() *MonitorV2IntervalSchedule { return v.Interval }
+
+// GetTransform returns MonitorV2Scheduling.Transform, and is useful for accessing the field via an interface.
+func (v *MonitorV2Scheduling) GetTransform() *MonitorV2TransformSchedule { return v.Transform }
+
+type MonitorV2SchedulingInput struct {
+ Interval *MonitorV2IntervalScheduleInput `json:"interval"`
+ Transform *MonitorV2TransformScheduleInput `json:"transform"`
+}
+
+// GetInterval returns MonitorV2SchedulingInput.Interval, and is useful for accessing the field via an interface.
+func (v *MonitorV2SchedulingInput) GetInterval() *MonitorV2IntervalScheduleInput { return v.Interval }
+
+// GetTransform returns MonitorV2SchedulingInput.Transform, and is useful for accessing the field via an interface.
+func (v *MonitorV2SchedulingInput) GetTransform() *MonitorV2TransformScheduleInput {
+ return v.Transform
+}
+
+// MonitorV2ThresholdRule includes the GraphQL fields of MonitorV2ThresholdRule requested by the fragment MonitorV2ThresholdRule.
+type MonitorV2ThresholdRule struct {
+ // CompareValues is a list of comparisons that provide an implicit AND where all comparisons must match.
+ // This gives the option to specify one value for a threshold behavior (trigger if > 80) but also allows
+ // for ranges of validity. If you want to trigger inside a range, give two compares here (like > 80 and < 90).
+ // If you want to trigger outside a valid range, use two rules with a single compare to get the implied OR
+ // (one rule for < 80 and one rule for > 90).
+ CompareValues []MonitorV2Comparison `json:"compareValues"`
+ // ValueColumnName indicates which of the columns in the input query has the value to apply to the aggregation.
+ ValueColumnName string `json:"valueColumnName"`
+ Aggregation MonitorV2ValueAggregation `json:"aggregation"`
+ // CompareGroups is a list of comparisons made against the columns which the monitor is grouped by.
+ // This gives the option to add extra dimension to the existing rule by specifying which column of
+ // the group the user looks forward to being alerted by. For example, this allows for rule expression
+ // like (Threshold > 80 and Group = "Good Group") which would trigger a critical alert.
+ CompareGroups []MonitorV2ColumnComparison `json:"compareGroups"`
+}
+
+// GetCompareValues returns MonitorV2ThresholdRule.CompareValues, and is useful for accessing the field via an interface.
+func (v *MonitorV2ThresholdRule) GetCompareValues() []MonitorV2Comparison { return v.CompareValues }
+
+// GetValueColumnName returns MonitorV2ThresholdRule.ValueColumnName, and is useful for accessing the field via an interface.
+func (v *MonitorV2ThresholdRule) GetValueColumnName() string { return v.ValueColumnName }
+
+// GetAggregation returns MonitorV2ThresholdRule.Aggregation, and is useful for accessing the field via an interface.
+func (v *MonitorV2ThresholdRule) GetAggregation() MonitorV2ValueAggregation { return v.Aggregation }
+
+// GetCompareGroups returns MonitorV2ThresholdRule.CompareGroups, and is useful for accessing the field via an interface.
+func (v *MonitorV2ThresholdRule) GetCompareGroups() []MonitorV2ColumnComparison {
+ return v.CompareGroups
+}
+
+type MonitorV2ThresholdRuleInput struct {
+ CompareValues []MonitorV2ComparisonInput `json:"compareValues"`
+ ValueColumnName string `json:"valueColumnName"`
+ Aggregation MonitorV2ValueAggregation `json:"aggregation"`
+ CompareGroups []MonitorV2ColumnComparisonInput `json:"compareGroups"`
+}
+
+// GetCompareValues returns MonitorV2ThresholdRuleInput.CompareValues, and is useful for accessing the field via an interface.
+func (v *MonitorV2ThresholdRuleInput) GetCompareValues() []MonitorV2ComparisonInput {
+ return v.CompareValues
+}
+
+// GetValueColumnName returns MonitorV2ThresholdRuleInput.ValueColumnName, and is useful for accessing the field via an interface.
+func (v *MonitorV2ThresholdRuleInput) GetValueColumnName() string { return v.ValueColumnName }
+
+// GetAggregation returns MonitorV2ThresholdRuleInput.Aggregation, and is useful for accessing the field via an interface.
+func (v *MonitorV2ThresholdRuleInput) GetAggregation() MonitorV2ValueAggregation {
+ return v.Aggregation
+}
+
+// GetCompareGroups returns MonitorV2ThresholdRuleInput.CompareGroups, and is useful for accessing the field via an interface.
+func (v *MonitorV2ThresholdRuleInput) GetCompareGroups() []MonitorV2ColumnComparisonInput {
+ return v.CompareGroups
+}
+
+// MonitorV2TransformSchedule includes the GraphQL fields of MonitorV2TransformSchedule requested by the fragment MonitorV2TransformSchedule.
+type MonitorV2TransformSchedule struct {
+ FreshnessGoal types.DurationScalar `json:"freshnessGoal"`
+}
+
+// GetFreshnessGoal returns MonitorV2TransformSchedule.FreshnessGoal, and is useful for accessing the field via an interface.
+func (v *MonitorV2TransformSchedule) GetFreshnessGoal() types.DurationScalar { return v.FreshnessGoal }
+
+type MonitorV2TransformScheduleInput struct {
+ FreshnessGoal types.DurationScalar `json:"freshnessGoal"`
+}
+
+// GetFreshnessGoal returns MonitorV2TransformScheduleInput.FreshnessGoal, and is useful for accessing the field via an interface.
+func (v *MonitorV2TransformScheduleInput) GetFreshnessGoal() types.DurationScalar {
+ return v.FreshnessGoal
+}
+
+// MonitorV2ValueAggregation describes the numerical/value aggregations for the Value
+// monitor type. These types map to your typical query aggregators except count, which is its own
+// monitor type since it acts on rows, not on values.
+// - AllOf: This is like "all values > 80" (which is like saying min(value) > 80)
+// - AnyOf: This is like "any value > 80" (which is like saying max(value) > 80)
+// - SumOf: This sums all values over the lookback and makes that the value to compare
+// - AvgOf: This averages all values over the lookback and makes that the value to compare
+type MonitorV2ValueAggregation string
+
+const (
+ MonitorV2ValueAggregationAllof MonitorV2ValueAggregation = "AllOf"
+ MonitorV2ValueAggregationAnyof MonitorV2ValueAggregation = "AnyOf"
+ MonitorV2ValueAggregationAvgof MonitorV2ValueAggregation = "AvgOf"
+ MonitorV2ValueAggregationSumof MonitorV2ValueAggregation = "SumOf"
+)
+
type MultiStageQueryInput struct {
OutputStage string `json:"outputStage"`
Stages []StageQueryInput `json:"stages"`
@@ -7380,6 +8039,18 @@ func (v *__createMonitorInput) GetWorkspaceId() string { return v.WorkspaceId }
// GetMonitor returns __createMonitorInput.Monitor, and is useful for accessing the field via an interface.
func (v *__createMonitorInput) GetMonitor() MonitorInput { return v.Monitor }
+// __createMonitorV2Input is used internally by genqlient
+type __createMonitorV2Input struct {
+ WorkspaceId string `json:"workspaceId"`
+ Input MonitorV2Input `json:"input"`
+}
+
+// GetWorkspaceId returns __createMonitorV2Input.WorkspaceId, and is useful for accessing the field via an interface.
+func (v *__createMonitorV2Input) GetWorkspaceId() string { return v.WorkspaceId }
+
+// GetInput returns __createMonitorV2Input.Input, and is useful for accessing the field via an interface.
+func (v *__createMonitorV2Input) GetInput() MonitorV2Input { return v.Input }
+
// __createOrUpdateBookmarkGroupInput is used internally by genqlient
type __createOrUpdateBookmarkGroupInput struct {
Id *string `json:"id"`
@@ -7636,6 +8307,14 @@ type __deleteMonitorInput struct {
// GetId returns __deleteMonitorInput.Id, and is useful for accessing the field via an interface.
func (v *__deleteMonitorInput) GetId() string { return v.Id }
+// __deleteMonitorV2Input is used internally by genqlient
+type __deleteMonitorV2Input struct {
+ Id string `json:"id"`
+}
+
+// GetId returns __deleteMonitorV2Input.Id, and is useful for accessing the field via an interface.
+func (v *__deleteMonitorV2Input) GetId() string { return v.Id }
+
// __deletePollerInput is used internally by genqlient
type __deletePollerInput struct {
Id string `json:"id"`
@@ -7888,6 +8567,14 @@ type __getMonitorInput struct {
// GetId returns __getMonitorInput.Id, and is useful for accessing the field via an interface.
func (v *__getMonitorInput) GetId() string { return v.Id }
+// __getMonitorV2Input is used internally by genqlient
+type __getMonitorV2Input struct {
+ Id string `json:"id"`
+}
+
+// GetId returns __getMonitorV2Input.Id, and is useful for accessing the field via an interface.
+func (v *__getMonitorV2Input) GetId() string { return v.Id }
+
// __getPollerInput is used internally by genqlient
type __getPollerInput struct {
Id string `json:"id"`
@@ -8040,6 +8727,26 @@ func (v *__lookupMonitorInput) GetWorkspaceId() string { return v.WorkspaceId }
// GetName returns __lookupMonitorInput.Name, and is useful for accessing the field via an interface.
func (v *__lookupMonitorInput) GetName() string { return v.Name }
+// __lookupMonitorV2Input is used internally by genqlient
+type __lookupMonitorV2Input struct {
+ WorkspaceId *string `json:"workspaceId"`
+ FolderId *string `json:"folderId"`
+ NameExact *string `json:"nameExact"`
+ NameSubstring *string `json:"nameSubstring"`
+}
+
+// GetWorkspaceId returns __lookupMonitorV2Input.WorkspaceId, and is useful for accessing the field via an interface.
+func (v *__lookupMonitorV2Input) GetWorkspaceId() *string { return v.WorkspaceId }
+
+// GetFolderId returns __lookupMonitorV2Input.FolderId, and is useful for accessing the field via an interface.
+func (v *__lookupMonitorV2Input) GetFolderId() *string { return v.FolderId }
+
+// GetNameExact returns __lookupMonitorV2Input.NameExact, and is useful for accessing the field via an interface.
+func (v *__lookupMonitorV2Input) GetNameExact() *string { return v.NameExact }
+
+// GetNameSubstring returns __lookupMonitorV2Input.NameSubstring, and is useful for accessing the field via an interface.
+func (v *__lookupMonitorV2Input) GetNameSubstring() *string { return v.NameSubstring }
+
// __lookupSnowflakeOutboundShareInput is used internally by genqlient
type __lookupSnowflakeOutboundShareInput struct {
Name string `json:"name"`
@@ -8382,6 +9089,18 @@ func (v *__updateMonitorInput) GetId() string { return v.Id }
// GetMonitor returns __updateMonitorInput.Monitor, and is useful for accessing the field via an interface.
func (v *__updateMonitorInput) GetMonitor() MonitorInput { return v.Monitor }
+// __updateMonitorV2Input is used internally by genqlient
+type __updateMonitorV2Input struct {
+ Id string `json:"id"`
+ Input MonitorV2Input `json:"input"`
+}
+
+// GetId returns __updateMonitorV2Input.Id, and is useful for accessing the field via an interface.
+func (v *__updateMonitorV2Input) GetId() string { return v.Id }
+
+// GetInput returns __updateMonitorV2Input.Input, and is useful for accessing the field via an interface.
+func (v *__updateMonitorV2Input) GetInput() MonitorV2Input { return v.Input }
+
// __updatePollerInput is used internally by genqlient
type __updatePollerInput struct {
Id string `json:"id"`
@@ -8764,6 +9483,14 @@ func (v *createMonitorResponse) GetMonitor() *createMonitorMonitorMonitorUpdateR
return v.Monitor
}
+// createMonitorV2Response is returned by createMonitorV2 on success.
+type createMonitorV2Response struct {
+ MonitorV2 MonitorV2 `json:"monitorV2"`
+}
+
+// GetMonitorV2 returns createMonitorV2Response.MonitorV2, and is useful for accessing the field via an interface.
+func (v *createMonitorV2Response) GetMonitorV2() MonitorV2 { return v.MonitorV2 }
+
// createOrUpdateBookmarkGroupResponse is returned by createOrUpdateBookmarkGroup on success.
type createOrUpdateBookmarkGroupResponse struct {
BookmarkGroup BookmarkGroup `json:"bookmarkGroup"`
@@ -9024,6 +9751,14 @@ type deleteMonitorResponse struct {
// GetResultStatus returns deleteMonitorResponse.ResultStatus, and is useful for accessing the field via an interface.
func (v *deleteMonitorResponse) GetResultStatus() ResultStatus { return v.ResultStatus }
+// deleteMonitorV2Response is returned by deleteMonitorV2 on success.
+type deleteMonitorV2Response struct {
+ ResultStatus ResultStatus `json:"resultStatus"`
+}
+
+// GetResultStatus returns deleteMonitorV2Response.ResultStatus, and is useful for accessing the field via an interface.
+func (v *deleteMonitorV2Response) GetResultStatus() ResultStatus { return v.ResultStatus }
+
// deletePollerResponse is returned by deletePoller on success.
type deletePollerResponse struct {
ResultStatus ResultStatus `json:"resultStatus"`
@@ -9511,6 +10246,14 @@ type getMonitorResponse struct {
// GetMonitor returns getMonitorResponse.Monitor, and is useful for accessing the field via an interface.
func (v *getMonitorResponse) GetMonitor() Monitor { return v.Monitor }
+// getMonitorV2Response is returned by getMonitorV2 on success.
+type getMonitorV2Response struct {
+ MonitorV2 MonitorV2 `json:"monitorV2"`
+}
+
+// GetMonitorV2 returns getMonitorV2Response.MonitorV2, and is useful for accessing the field via an interface.
+func (v *getMonitorV2Response) GetMonitorV2() MonitorV2 { return v.MonitorV2 }
+
// getPollerResponse is returned by getPoller on success.
type getPollerResponse struct {
Poller Poller `json:"poller"`
@@ -9745,6 +10488,24 @@ type lookupMonitorResponse struct {
// GetMonitor returns lookupMonitorResponse.Monitor, and is useful for accessing the field via an interface.
func (v *lookupMonitorResponse) GetMonitor() *lookupMonitorMonitorProject { return v.Monitor }
+// lookupMonitorV2MonitorV2sMonitorV2SearchResult includes the requested fields of the GraphQL type MonitorV2SearchResult.
+type lookupMonitorV2MonitorV2sMonitorV2SearchResult struct {
+ Results []MonitorV2 `json:"results"`
+}
+
+// GetResults returns lookupMonitorV2MonitorV2sMonitorV2SearchResult.Results, and is useful for accessing the field via an interface.
+func (v *lookupMonitorV2MonitorV2sMonitorV2SearchResult) GetResults() []MonitorV2 { return v.Results }
+
+// lookupMonitorV2Response is returned by lookupMonitorV2 on success.
+type lookupMonitorV2Response struct {
+ MonitorV2s lookupMonitorV2MonitorV2sMonitorV2SearchResult `json:"monitorV2s"`
+}
+
+// GetMonitorV2s returns lookupMonitorV2Response.MonitorV2s, and is useful for accessing the field via an interface.
+func (v *lookupMonitorV2Response) GetMonitorV2s() lookupMonitorV2MonitorV2sMonitorV2SearchResult {
+ return v.MonitorV2s
+}
+
// lookupSnowflakeOutboundShareResponse is returned by lookupSnowflakeOutboundShare on success.
type lookupSnowflakeOutboundShareResponse struct {
Shares lookupSnowflakeOutboundShareSharesSnowflakeOutboundShareSearchResult `json:"shares"`
@@ -10243,6 +11004,14 @@ func (v *updateMonitorResponse) GetMonitor() *updateMonitorMonitorMonitorUpdateR
return v.Monitor
}
+// updateMonitorV2Response is returned by updateMonitorV2 on success.
+type updateMonitorV2Response struct {
+ MonitorV2 MonitorV2 `json:"monitorV2"`
+}
+
+// GetMonitorV2 returns updateMonitorV2Response.MonitorV2, and is useful for accessing the field via an interface.
+func (v *updateMonitorV2Response) GetMonitorV2() MonitorV2 { return v.MonitorV2 }
+
// updatePollerResponse is returned by updatePoller on success.
type updatePollerResponse struct {
Poller Poller `json:"poller"`
@@ -11319,25 +12088,208 @@ func createMonitorActionAttachment(
return &data, err
}
-// The query or mutation executed by createOrUpdateBookmark.
-const createOrUpdateBookmark_Operation = `
-mutation createOrUpdateBookmark ($id: ObjectId, $bookmark: BookmarkInput!) {
- bookmark: createOrUpdateBookmark(id: $id, bookmark: $bookmark) {
- ... Bookmark
+// The query or mutation executed by createMonitorV2.
+const createMonitorV2_Operation = `
+mutation createMonitorV2 ($workspaceId: ObjectId!, $input: MonitorV2Input!) {
+ monitorV2: createMonitorV2(workspaceId: $workspaceId, input: $input) {
+ ... MonitorV2
}
}
-fragment Bookmark on Bookmark {
+fragment MonitorV2 on MonitorV2 {
id
+ workspaceId
+ createdBy
+ createdDate
name
iconUrl
- targetId
- targetIdKind
- groupId
- bookmarkKind
-}
-`
-
-func createOrUpdateBookmark(
+ description
+ managedById
+ folderId
+ comment
+ rollupStatus
+ ruleKind
+ definition {
+ ... MonitorV2Definition
+ }
+}
+fragment MonitorV2Definition on MonitorV2Definition {
+ inputQuery {
+ outputStage
+ stages {
+ ... StageQuery
+ }
+ }
+ rules {
+ ... MonitorV2Rule
+ }
+ lookbackTime
+ dataStabilizationDelay
+ groupings {
+ ... MonitorV2Column
+ }
+ scheduling {
+ ... MonitorV2Scheduling
+ }
+}
+fragment StageQuery on StageQuery {
+ id
+ pipeline
+ params
+ layout
+ input {
+ inputName
+ inputRole
+ datasetId
+ datasetPath
+ stageId
+ }
+}
+fragment MonitorV2Rule on MonitorV2Rule {
+ level
+ count {
+ ... MonitorV2CountRule
+ }
+ threshold {
+ ... MonitorV2ThresholdRule
+ }
+ promote {
+ ... MonitorV2PromoteRule
+ }
+}
+fragment MonitorV2Column on MonitorV2Column {
+ linkColumn {
+ ... MonitorV2LinkColumn
+ }
+ columnPath {
+ ... MonitorV2ColumnPath
+ }
+}
+fragment MonitorV2Scheduling on MonitorV2Scheduling {
+ interval {
+ ... MonitorV2IntervalSchedule
+ }
+ transform {
+ ... MonitorV2TransformSchedule
+ }
+}
+fragment MonitorV2CountRule on MonitorV2CountRule {
+ compareValues {
+ ... MonitorV2Comparison
+ }
+ compareGroups {
+ ... MonitorV2ColumnComparison
+ }
+}
+fragment MonitorV2ThresholdRule on MonitorV2ThresholdRule {
+ compareValues {
+ ... MonitorV2Comparison
+ }
+ valueColumnName
+ aggregation
+ compareGroups {
+ ... MonitorV2ColumnComparison
+ }
+}
+fragment MonitorV2PromoteRule on MonitorV2PromoteRule {
+ compareColumns {
+ ... MonitorV2ColumnComparison
+ }
+}
+fragment MonitorV2LinkColumn on MonitorV2LinkColumn {
+ name
+ meta {
+ ... MonitorV2LinkColumnMeta
+ }
+}
+fragment MonitorV2ColumnPath on MonitorV2ColumnPath {
+ name
+ path
+}
+fragment MonitorV2IntervalSchedule on MonitorV2IntervalSchedule {
+ interval
+ randomize
+}
+fragment MonitorV2TransformSchedule on MonitorV2TransformSchedule {
+ freshnessGoal
+}
+fragment MonitorV2Comparison on MonitorV2Comparison {
+ compareFn
+ compareValue {
+ ... PrimitiveValue
+ }
+}
+fragment MonitorV2ColumnComparison on MonitorV2ColumnComparison {
+ column {
+ ... MonitorV2Column
+ }
+ compareValues {
+ ... MonitorV2Comparison
+ }
+}
+fragment MonitorV2LinkColumnMeta on MonitorV2LinkColumnMeta {
+ srcFields {
+ ... MonitorV2ColumnPath
+ }
+ dstFields
+ targetDataset
+}
+fragment PrimitiveValue on PrimitiveValue {
+ bool
+ float64
+ int64
+ string
+ timestamp
+ duration
+}
+`
+
+func createMonitorV2(
+ ctx context.Context,
+ client graphql.Client,
+ workspaceId string,
+ input MonitorV2Input,
+) (*createMonitorV2Response, error) {
+ req := &graphql.Request{
+ OpName: "createMonitorV2",
+ Query: createMonitorV2_Operation,
+ Variables: &__createMonitorV2Input{
+ WorkspaceId: workspaceId,
+ Input: input,
+ },
+ }
+ var err error
+
+ var data createMonitorV2Response
+ resp := &graphql.Response{Data: &data}
+
+ err = client.MakeRequest(
+ ctx,
+ req,
+ resp,
+ )
+
+ return &data, err
+}
+
+// The query or mutation executed by createOrUpdateBookmark.
+const createOrUpdateBookmark_Operation = `
+mutation createOrUpdateBookmark ($id: ObjectId, $bookmark: BookmarkInput!) {
+ bookmark: createOrUpdateBookmark(id: $id, bookmark: $bookmark) {
+ ... Bookmark
+ }
+}
+fragment Bookmark on Bookmark {
+ id
+ name
+ iconUrl
+ targetId
+ targetIdKind
+ groupId
+ bookmarkKind
+}
+`
+
+func createOrUpdateBookmark(
ctx context.Context,
client graphql.Client,
id *string,
@@ -12635,6 +13587,46 @@ func deleteMonitorActionAttachment(
return &data, err
}
+// The query or mutation executed by deleteMonitorV2.
+const deleteMonitorV2_Operation = `
+mutation deleteMonitorV2 ($id: ObjectId!) {
+ resultStatus: deleteMonitorV2(id: $id) {
+ ... ResultStatus
+ }
+}
+fragment ResultStatus on ResultStatus {
+ success
+ errorMessage
+ detailedInfo
+}
+`
+
+func deleteMonitorV2(
+ ctx context.Context,
+ client graphql.Client,
+ id string,
+) (*deleteMonitorV2Response, error) {
+ req := &graphql.Request{
+ OpName: "deleteMonitorV2",
+ Query: deleteMonitorV2_Operation,
+ Variables: &__deleteMonitorV2Input{
+ Id: id,
+ },
+ }
+ var err error
+
+ var data deleteMonitorV2Response
+ resp := &graphql.Response{Data: &data}
+
+ err = client.MakeRequest(
+ ctx,
+ req,
+ resp,
+ )
+
+ return &data, err
+}
+
// The query or mutation executed by deletePoller.
const deletePoller_Operation = `
mutation deletePoller ($id: ObjectId!) {
@@ -14394,6 +15386,187 @@ func getMonitorActionAttachment(
return &data, err
}
+// The query or mutation executed by getMonitorV2.
+const getMonitorV2_Operation = `
+query getMonitorV2 ($id: ObjectId!) {
+ monitorV2(id: $id) {
+ ... MonitorV2
+ }
+}
+fragment MonitorV2 on MonitorV2 {
+ id
+ workspaceId
+ createdBy
+ createdDate
+ name
+ iconUrl
+ description
+ managedById
+ folderId
+ comment
+ rollupStatus
+ ruleKind
+ definition {
+ ... MonitorV2Definition
+ }
+}
+fragment MonitorV2Definition on MonitorV2Definition {
+ inputQuery {
+ outputStage
+ stages {
+ ... StageQuery
+ }
+ }
+ rules {
+ ... MonitorV2Rule
+ }
+ lookbackTime
+ dataStabilizationDelay
+ groupings {
+ ... MonitorV2Column
+ }
+ scheduling {
+ ... MonitorV2Scheduling
+ }
+}
+fragment StageQuery on StageQuery {
+ id
+ pipeline
+ params
+ layout
+ input {
+ inputName
+ inputRole
+ datasetId
+ datasetPath
+ stageId
+ }
+}
+fragment MonitorV2Rule on MonitorV2Rule {
+ level
+ count {
+ ... MonitorV2CountRule
+ }
+ threshold {
+ ... MonitorV2ThresholdRule
+ }
+ promote {
+ ... MonitorV2PromoteRule
+ }
+}
+fragment MonitorV2Column on MonitorV2Column {
+ linkColumn {
+ ... MonitorV2LinkColumn
+ }
+ columnPath {
+ ... MonitorV2ColumnPath
+ }
+}
+fragment MonitorV2Scheduling on MonitorV2Scheduling {
+ interval {
+ ... MonitorV2IntervalSchedule
+ }
+ transform {
+ ... MonitorV2TransformSchedule
+ }
+}
+fragment MonitorV2CountRule on MonitorV2CountRule {
+ compareValues {
+ ... MonitorV2Comparison
+ }
+ compareGroups {
+ ... MonitorV2ColumnComparison
+ }
+}
+fragment MonitorV2ThresholdRule on MonitorV2ThresholdRule {
+ compareValues {
+ ... MonitorV2Comparison
+ }
+ valueColumnName
+ aggregation
+ compareGroups {
+ ... MonitorV2ColumnComparison
+ }
+}
+fragment MonitorV2PromoteRule on MonitorV2PromoteRule {
+ compareColumns {
+ ... MonitorV2ColumnComparison
+ }
+}
+fragment MonitorV2LinkColumn on MonitorV2LinkColumn {
+ name
+ meta {
+ ... MonitorV2LinkColumnMeta
+ }
+}
+fragment MonitorV2ColumnPath on MonitorV2ColumnPath {
+ name
+ path
+}
+fragment MonitorV2IntervalSchedule on MonitorV2IntervalSchedule {
+ interval
+ randomize
+}
+fragment MonitorV2TransformSchedule on MonitorV2TransformSchedule {
+ freshnessGoal
+}
+fragment MonitorV2Comparison on MonitorV2Comparison {
+ compareFn
+ compareValue {
+ ... PrimitiveValue
+ }
+}
+fragment MonitorV2ColumnComparison on MonitorV2ColumnComparison {
+ column {
+ ... MonitorV2Column
+ }
+ compareValues {
+ ... MonitorV2Comparison
+ }
+}
+fragment MonitorV2LinkColumnMeta on MonitorV2LinkColumnMeta {
+ srcFields {
+ ... MonitorV2ColumnPath
+ }
+ dstFields
+ targetDataset
+}
+fragment PrimitiveValue on PrimitiveValue {
+ bool
+ float64
+ int64
+ string
+ timestamp
+ duration
+}
+`
+
+func getMonitorV2(
+ ctx context.Context,
+ client graphql.Client,
+ id string,
+) (*getMonitorV2Response, error) {
+ req := &graphql.Request{
+ OpName: "getMonitorV2",
+ Query: getMonitorV2_Operation,
+ Variables: &__getMonitorV2Input{
+ Id: id,
+ },
+ }
+ var err error
+
+ var data getMonitorV2Response
+ resp := &graphql.Response{Data: &data}
+
+ err = client.MakeRequest(
+ ctx,
+ req,
+ resp,
+ )
+
+ return &data, err
+}
+
// The query or mutation executed by getPoller.
const getPoller_Operation = `
query getPoller ($id: ObjectId!) {
@@ -15595,6 +16768,195 @@ func lookupMonitor(
return &data, err
}
+// The query or mutation executed by lookupMonitorV2.
+const lookupMonitorV2_Operation = `
+query lookupMonitorV2 ($workspaceId: ObjectId, $folderId: ObjectId, $nameExact: String, $nameSubstring: String) {
+ monitorV2s: searchMonitorV2(workspaceId: $workspaceId, folderId: $folderId, nameExact: $nameExact, nameSubstring: $nameSubstring) {
+ results {
+ ... MonitorV2
+ }
+ }
+}
+fragment MonitorV2 on MonitorV2 {
+ id
+ workspaceId
+ createdBy
+ createdDate
+ name
+ iconUrl
+ description
+ managedById
+ folderId
+ comment
+ rollupStatus
+ ruleKind
+ definition {
+ ... MonitorV2Definition
+ }
+}
+fragment MonitorV2Definition on MonitorV2Definition {
+ inputQuery {
+ outputStage
+ stages {
+ ... StageQuery
+ }
+ }
+ rules {
+ ... MonitorV2Rule
+ }
+ lookbackTime
+ dataStabilizationDelay
+ groupings {
+ ... MonitorV2Column
+ }
+ scheduling {
+ ... MonitorV2Scheduling
+ }
+}
+fragment StageQuery on StageQuery {
+ id
+ pipeline
+ params
+ layout
+ input {
+ inputName
+ inputRole
+ datasetId
+ datasetPath
+ stageId
+ }
+}
+fragment MonitorV2Rule on MonitorV2Rule {
+ level
+ count {
+ ... MonitorV2CountRule
+ }
+ threshold {
+ ... MonitorV2ThresholdRule
+ }
+ promote {
+ ... MonitorV2PromoteRule
+ }
+}
+fragment MonitorV2Column on MonitorV2Column {
+ linkColumn {
+ ... MonitorV2LinkColumn
+ }
+ columnPath {
+ ... MonitorV2ColumnPath
+ }
+}
+fragment MonitorV2Scheduling on MonitorV2Scheduling {
+ interval {
+ ... MonitorV2IntervalSchedule
+ }
+ transform {
+ ... MonitorV2TransformSchedule
+ }
+}
+fragment MonitorV2CountRule on MonitorV2CountRule {
+ compareValues {
+ ... MonitorV2Comparison
+ }
+ compareGroups {
+ ... MonitorV2ColumnComparison
+ }
+}
+fragment MonitorV2ThresholdRule on MonitorV2ThresholdRule {
+ compareValues {
+ ... MonitorV2Comparison
+ }
+ valueColumnName
+ aggregation
+ compareGroups {
+ ... MonitorV2ColumnComparison
+ }
+}
+fragment MonitorV2PromoteRule on MonitorV2PromoteRule {
+ compareColumns {
+ ... MonitorV2ColumnComparison
+ }
+}
+fragment MonitorV2LinkColumn on MonitorV2LinkColumn {
+ name
+ meta {
+ ... MonitorV2LinkColumnMeta
+ }
+}
+fragment MonitorV2ColumnPath on MonitorV2ColumnPath {
+ name
+ path
+}
+fragment MonitorV2IntervalSchedule on MonitorV2IntervalSchedule {
+ interval
+ randomize
+}
+fragment MonitorV2TransformSchedule on MonitorV2TransformSchedule {
+ freshnessGoal
+}
+fragment MonitorV2Comparison on MonitorV2Comparison {
+ compareFn
+ compareValue {
+ ... PrimitiveValue
+ }
+}
+fragment MonitorV2ColumnComparison on MonitorV2ColumnComparison {
+ column {
+ ... MonitorV2Column
+ }
+ compareValues {
+ ... MonitorV2Comparison
+ }
+}
+fragment MonitorV2LinkColumnMeta on MonitorV2LinkColumnMeta {
+ srcFields {
+ ... MonitorV2ColumnPath
+ }
+ dstFields
+ targetDataset
+}
+fragment PrimitiveValue on PrimitiveValue {
+ bool
+ float64
+ int64
+ string
+ timestamp
+ duration
+}
+`
+
+func lookupMonitorV2(
+ ctx context.Context,
+ client graphql.Client,
+ workspaceId *string,
+ folderId *string,
+ nameExact *string,
+ nameSubstring *string,
+) (*lookupMonitorV2Response, error) {
+ req := &graphql.Request{
+ OpName: "lookupMonitorV2",
+ Query: lookupMonitorV2_Operation,
+ Variables: &__lookupMonitorV2Input{
+ WorkspaceId: workspaceId,
+ FolderId: folderId,
+ NameExact: nameExact,
+ NameSubstring: nameSubstring,
+ },
+ }
+ var err error
+
+ var data lookupMonitorV2Response
+ resp := &graphql.Response{Data: &data}
+
+ err = client.MakeRequest(
+ ctx,
+ req,
+ resp,
+ )
+
+ return &data, err
+}
+
// The query or mutation executed by lookupSnowflakeOutboundShare.
const lookupSnowflakeOutboundShare_Operation = `
query lookupSnowflakeOutboundShare ($name: String!, $workspaceId: ObjectId!) {
@@ -17332,6 +18694,189 @@ func updateMonitorActionAttachment(
return &data, err
}
+// The query or mutation executed by updateMonitorV2.
+const updateMonitorV2_Operation = `
+mutation updateMonitorV2 ($id: ObjectId!, $input: MonitorV2Input!) {
+ monitorV2: updateMonitorV2(id: $id, input: $input) {
+ ... MonitorV2
+ }
+}
+fragment MonitorV2 on MonitorV2 {
+ id
+ workspaceId
+ createdBy
+ createdDate
+ name
+ iconUrl
+ description
+ managedById
+ folderId
+ comment
+ rollupStatus
+ ruleKind
+ definition {
+ ... MonitorV2Definition
+ }
+}
+fragment MonitorV2Definition on MonitorV2Definition {
+ inputQuery {
+ outputStage
+ stages {
+ ... StageQuery
+ }
+ }
+ rules {
+ ... MonitorV2Rule
+ }
+ lookbackTime
+ dataStabilizationDelay
+ groupings {
+ ... MonitorV2Column
+ }
+ scheduling {
+ ... MonitorV2Scheduling
+ }
+}
+fragment StageQuery on StageQuery {
+ id
+ pipeline
+ params
+ layout
+ input {
+ inputName
+ inputRole
+ datasetId
+ datasetPath
+ stageId
+ }
+}
+fragment MonitorV2Rule on MonitorV2Rule {
+ level
+ count {
+ ... MonitorV2CountRule
+ }
+ threshold {
+ ... MonitorV2ThresholdRule
+ }
+ promote {
+ ... MonitorV2PromoteRule
+ }
+}
+fragment MonitorV2Column on MonitorV2Column {
+ linkColumn {
+ ... MonitorV2LinkColumn
+ }
+ columnPath {
+ ... MonitorV2ColumnPath
+ }
+}
+fragment MonitorV2Scheduling on MonitorV2Scheduling {
+ interval {
+ ... MonitorV2IntervalSchedule
+ }
+ transform {
+ ... MonitorV2TransformSchedule
+ }
+}
+fragment MonitorV2CountRule on MonitorV2CountRule {
+ compareValues {
+ ... MonitorV2Comparison
+ }
+ compareGroups {
+ ... MonitorV2ColumnComparison
+ }
+}
+fragment MonitorV2ThresholdRule on MonitorV2ThresholdRule {
+ compareValues {
+ ... MonitorV2Comparison
+ }
+ valueColumnName
+ aggregation
+ compareGroups {
+ ... MonitorV2ColumnComparison
+ }
+}
+fragment MonitorV2PromoteRule on MonitorV2PromoteRule {
+ compareColumns {
+ ... MonitorV2ColumnComparison
+ }
+}
+fragment MonitorV2LinkColumn on MonitorV2LinkColumn {
+ name
+ meta {
+ ... MonitorV2LinkColumnMeta
+ }
+}
+fragment MonitorV2ColumnPath on MonitorV2ColumnPath {
+ name
+ path
+}
+fragment MonitorV2IntervalSchedule on MonitorV2IntervalSchedule {
+ interval
+ randomize
+}
+fragment MonitorV2TransformSchedule on MonitorV2TransformSchedule {
+ freshnessGoal
+}
+fragment MonitorV2Comparison on MonitorV2Comparison {
+ compareFn
+ compareValue {
+ ... PrimitiveValue
+ }
+}
+fragment MonitorV2ColumnComparison on MonitorV2ColumnComparison {
+ column {
+ ... MonitorV2Column
+ }
+ compareValues {
+ ... MonitorV2Comparison
+ }
+}
+fragment MonitorV2LinkColumnMeta on MonitorV2LinkColumnMeta {
+ srcFields {
+ ... MonitorV2ColumnPath
+ }
+ dstFields
+ targetDataset
+}
+fragment PrimitiveValue on PrimitiveValue {
+ bool
+ float64
+ int64
+ string
+ timestamp
+ duration
+}
+`
+
+func updateMonitorV2(
+ ctx context.Context,
+ client graphql.Client,
+ id string,
+ input MonitorV2Input,
+) (*updateMonitorV2Response, error) {
+ req := &graphql.Request{
+ OpName: "updateMonitorV2",
+ Query: updateMonitorV2_Operation,
+ Variables: &__updateMonitorV2Input{
+ Id: id,
+ Input: input,
+ },
+ }
+ var err error
+
+ var data updateMonitorV2Response
+ resp := &graphql.Response{Data: &data}
+
+ err = client.MakeRequest(
+ ctx,
+ req,
+ resp,
+ )
+
+ return &data, err
+}
+
// The query or mutation executed by updatePoller.
const updatePoller_Operation = `
mutation updatePoller ($id: ObjectId!, $poller: PollerInput!) {
diff --git a/client/meta/helpers.go b/client/meta/helpers.go
index ba8e8dcb..e5615ff0 100644
--- a/client/meta/helpers.go
+++ b/client/meta/helpers.go
@@ -112,6 +112,35 @@ var AllBookmarkKindTypes = []BookmarkKind{
BookmarkKindMetricexplorer,
}
+var AllMonitorV2RuleKinds = []MonitorV2RuleKind{
+ MonitorV2RuleKindCount,
+ MonitorV2RuleKindPromote,
+ MonitorV2RuleKindThreshold,
+}
+
+var AllMonitorV2AlarmLevels = []MonitorV2AlarmLevel{
+ MonitorV2AlarmLevelCritical,
+ MonitorV2AlarmLevelError,
+ MonitorV2AlarmLevelInformational,
+ MonitorV2AlarmLevelNone,
+ MonitorV2AlarmLevelWarning,
+}
+
+var AllMonitorV2ValueAggregations = []MonitorV2ValueAggregation{
+ MonitorV2ValueAggregationAllof,
+ MonitorV2ValueAggregationAnyof,
+ MonitorV2ValueAggregationAvgof,
+ MonitorV2ValueAggregationSumof,
+}
+
+var AllMonitorV2RollupStatuses = []MonitorV2RollupStatus{
+ MonitorV2RollupStatusDegraded,
+ MonitorV2RollupStatusFailed,
+ MonitorV2RollupStatusInactive,
+ MonitorV2RollupStatusRunning,
+ MonitorV2RollupStatusTriggering,
+}
+
type resultStatusResponse interface {
GetResultStatus() ResultStatus
}
diff --git a/client/meta/monitorv2.go b/client/meta/monitorv2.go
new file mode 100644
index 00000000..52c40527
--- /dev/null
+++ b/client/meta/monitorv2.go
@@ -0,0 +1,46 @@
+package meta
+
+import (
+ "context"
+
+ oid "github.com/observeinc/terraform-provider-observe/client/oid"
+)
+
+type monitorV2Response interface {
+ GetMonitorV2() MonitorV2
+}
+
+func monitorV2OrError(m monitorV2Response, err error) (*MonitorV2, error) {
+ if err != nil {
+ return nil, err
+ }
+ result := m.GetMonitorV2()
+ return &result, nil
+}
+
+func (client *Client) CreateMonitorV2(ctx context.Context, workspaceId string, input *MonitorV2Input) (*MonitorV2, error) {
+ resp, err := createMonitorV2(ctx, client.Gql, workspaceId, *input)
+ return monitorV2OrError(resp, err)
+}
+
+func (client *Client) GetMonitorV2(ctx context.Context, id string) (*MonitorV2, error) {
+ resp, err := getMonitorV2(ctx, client.Gql, id)
+ return monitorV2OrError(resp, err)
+}
+
+func (client *Client) UpdateMonitorV2(ctx context.Context, id string, input *MonitorV2Input) (*MonitorV2, error) {
+ resp, err := updateMonitorV2(ctx, client.Gql, id, *input)
+ return monitorV2OrError(resp, err)
+}
+
+func (client *Client) DeleteMonitorV2(ctx context.Context, id string) error {
+ resp, err := deleteMonitorV2(ctx, client.Gql, id)
+ return resultStatusError(resp, err)
+}
+
+func (m *MonitorV2) Oid() *oid.OID {
+ return &oid.OID{
+ Id: m.Id,
+ Type: oid.TypeMonitorV2,
+ }
+}
diff --git a/client/oid/oid.go b/client/oid/oid.go
index 4185d4e1..76bc35c8 100644
--- a/client/oid/oid.go
+++ b/client/oid/oid.go
@@ -36,6 +36,7 @@ const (
TypeLayeredSettingRecord Type = "layeredsettingrecord"
TypeLink Type = "link"
TypeMonitor Type = "monitor"
+ TypeMonitorV2 Type = "monitorV2"
TypeMonitorAction Type = "monitoraction"
TypeMonitorActionAttachment Type = "monitoractionattachment"
TypePoller Type = "poller"
@@ -70,6 +71,7 @@ func (t Type) IsValid() bool {
case TypeMonitor:
case TypeMonitorAction:
case TypeMonitorActionAttachment:
+ case TypeMonitorV2:
case TypePoller:
case TypePreferredPath:
case TypeUser:
@@ -224,6 +226,10 @@ func MonitorActionOid(id string) OID {
return OID{Id: id, Type: TypeMonitorAction}
}
+func MonitorV2Oid(id string) OID {
+ return OID{Id: id, Type: TypeMonitorV2}
+}
+
func PollerOid(id string) OID {
return OID{Id: id, Type: TypePoller}
}
diff --git a/docs/resources/monitor_v2.md b/docs/resources/monitor_v2.md
new file mode 100644
index 00000000..2d7f6934
--- /dev/null
+++ b/docs/resources/monitor_v2.md
@@ -0,0 +1,468 @@
+---
+# generated by https://github.com/hashicorp/terraform-plugin-docs
+page_title: "observe_monitor_v2 Resource - terraform-provider-observe"
+subcategory: ""
+description: |-
+ NOTE: This feature is still in development. It is not meant for customer use yet.
+ Monitors provide a configurable way to alert when conditions about incoming data
+ are matched. These alerts can optionally also be forwarded to notification receivers
+ like email and webhooks using shared or single-monitor actions to configure the
+ template and destinations to configure the receiver.
+---
+# observe_monitor_v2
+
+NOTE: This feature is still in development. It is not meant for customer use yet.
+
+Monitors provide a configurable way to alert when conditions about incoming data
+are matched. These alerts can optionally also be forwarded to notification receivers
+like email and webhooks using shared or single-monitor actions to configure the
+template and destinations to configure the receiver.
+
+
+## Schema
+
+### Required
+
+- `inputs` (Map of String) The inputs map binds dataset OIDs to labels which can be referenced within
+stage pipelines.
+- `name` (String) Monitor name.
+- `rule_kind` (String) Describes the type of each of the rules in the definition (they must all be the same type).
+- `rules` (Block List, Min: 1) All rules for this monitor must be of the same MonitorRuleKind as specified in ruleKind. Rules should be constructed logically such that a state transition null->Warning implies transition from null->Informational. (see [below for nested schema](#nestedblock--rules))
+- `scheduling` (Block List, Min: 1, Max: 1) Holds information about when the monitor should evaluate. The types of scheduling (interval, transform) are exclusive, but at least one is required. (see [below for nested schema](#nestedblock--scheduling))
+- `stage` (Block List, Min: 1) A stage processes an input according to the provided pipeline. If no
+input is provided, a stage will implicitly follow on from the result of
+its predecessor. (see [below for nested schema](#nestedblock--stage))
+- `workspace_id` (String) OID of the workspace this object is contained in.
+
+### Optional
+
+- `comment` (String) A longer description of the monitor. This can include details like how to resolve the issue, links to runbooks, etc.
+- `data_stabilization_delay` (String) expresses the minimum time that should elapse before data is considered "good enough" to evaluate. Choosing a delay really depends on the expectations of latency of data and whether data is expected to arrive later than other data and thus would change previously evaluated results.
+- `description` (String) A brief description of the monitor.
+- `groupings` (Block List) Describes the groups that logically separate events/rows/etc from each other. If monitor dataset is resource type and monitor strategy is promote, this field should be either empty or only contain the primary keys of the dataset. (see [below for nested schema](#nestedblock--groupings))
+- `icon_url` (String) URL of the monitor icon.
+- `lookback_time` (String) optionally describes a duration that must be satisifed by this monitor. It applies to all rules, but is only applicable to rule kinds that utilize it.
+
+### Read-Only
+
+- `id` (String) The ID of this resource.
+
+
+### Nested Schema for `rules`
+
+Required:
+
+- `level` (String) The alarm level (Critical, Error, Informational, None, Warning).
+
+Optional:
+
+- `count` (Block List, Max: 1) The count rule to apply to incoming data. (see [below for nested schema](#nestedblock--rules--count))
+- `promote` (Block List, Max: 1) The monitor will promote each event in the raw input dataset into an alert. For now, the promote rule will ignore link columns and only care about columnWithPath.
+If multiple compareColumns are specified in one promote rule, it will act as an AND condition. When defined through separate promote rules, it will act as an OR condition. (see [below for nested schema](#nestedblock--rules--promote))
+- `threshold` (Block List, Max: 1) Gives flexibility for threshold and range-based monitors to trigger on values. To look for sustained behavior (CPU > 80 for 5 mins), specify lookbackTime. (see [below for nested schema](#nestedblock--rules--threshold))
+
+
+### Nested Schema for `rules.count`
+
+Required:
+
+- `compare_values` (Block List, Min: 1) list of comparisons that provide an implicit AND where all comparisons must match. (see [below for nested schema](#nestedblock--rules--count--compare_values))
+
+Optional:
+
+- `compare_groups` (Block List) list of comparisons made against the columns which the monitor is grouped by. (see [below for nested schema](#nestedblock--rules--count--compare_groups))
+
+
+### Nested Schema for `rules.count.compare_values`
+
+Required:
+
+- `compare_fn` (String) the type of comparison (greater, less, equal, etc.)
+
+Optional:
+
+- `value_bool` (List of Boolean) list of size <=1 consisting of a boolean value.
+- `value_duration` (List of Boolean) list of size <=1 consisting of a duration value.
+- `value_float64` (List of Number) list of size <=1 consisting of a float value.
+- `value_int64` (List of Number) list of size <=1 consisting of an integer value.
+- `value_string` (List of String) list of size <=1 consisting of a string value.
+- `value_timestamp` (List of String) list of size <=1 consisting of a timestamp value.
+
+
+
+### Nested Schema for `rules.count.compare_groups`
+
+Required:
+
+- `column` (Block List, Min: 1, Max: 1) Represents two possible column types (link column, columnPath) of an observe dataset. (see [below for nested schema](#nestedblock--rules--count--compare_groups--column))
+- `compare_values` (Block List, Min: 1) list of comparisons that provide an implicit AND where all comparisons must match. (see [below for nested schema](#nestedblock--rules--count--compare_groups--compare_values))
+
+
+### Nested Schema for `rules.count.compare_groups.column`
+
+Optional:
+
+- `column_path` (Block List, Max: 1) Specifies how the user wants to group by a specific column name or a JSON object column that has a path. (see [below for nested schema](#nestedblock--rules--count--compare_groups--column--column_path))
+- `link_column` (Block List, Max: 1) Identifies a link-type column created by connecting two different datasets' columns (primary sources & destination sources). (see [below for nested schema](#nestedblock--rules--count--compare_groups--column--link_column))
+
+
+### Nested Schema for `rules.count.compare_groups.column.column_path`
+
+Required:
+
+- `name` (String) The name of the column.
+
+Optional:
+
+- `path` (String) The path of the path, if the name refers to a column with a JSON object.
+
+
+
+### Nested Schema for `rules.count.compare_groups.column.link_column`
+
+Required:
+
+- `name` (String) The name of the link column.
+
+Optional:
+
+- `meta` (Block List, Max: 1) Contains the context surrounding the link column. (see [below for nested schema](#nestedblock--rules--count--compare_groups--column--link_column--meta))
+
+
+### Nested Schema for `rules.count.compare_groups.column.link_column.meta`
+
+Optional:
+
+- `dst_fields` (List of String) The destination fields (a.k.a. primary keys) of the target dataset being linked against.
+- `src_fields` (Block List) The source fields used to link against the primary keys of the target dataset. (see [below for nested schema](#nestedblock--rules--count--compare_groups--column--link_column--meta--src_fields))
+- `target_dataset` (Number) The resource dataset ID which the link came from. Empty if the link was created from a stage in the shape of a resource from the worksheet.
+
+
+### Nested Schema for `rules.count.compare_groups.column.link_column.meta.src_fields`
+
+Required:
+
+- `name` (String) The name of the column.
+
+Optional:
+
+- `path` (String) The path of the path, if the name refers to a column with a JSON object.
+
+
+
+
+
+
+### Nested Schema for `rules.count.compare_groups.compare_values`
+
+Required:
+
+- `compare_fn` (String) the type of comparison (greater, less, equal, etc.)
+
+Optional:
+
+- `value_bool` (List of Boolean) list of size <=1 consisting of a boolean value.
+- `value_duration` (List of Boolean) list of size <=1 consisting of a duration value.
+- `value_float64` (List of Number) list of size <=1 consisting of a float value.
+- `value_int64` (List of Number) list of size <=1 consisting of an integer value.
+- `value_string` (List of String) list of size <=1 consisting of a string value.
+- `value_timestamp` (List of String) list of size <=1 consisting of a timestamp value.
+
+
+
+
+
+### Nested Schema for `rules.promote`
+
+Optional:
+
+- `compare_columns` (Block List) Specifies the one or multiple values you'd like to compare against the column. (see [below for nested schema](#nestedblock--rules--promote--compare_columns))
+
+
+### Nested Schema for `rules.promote.compare_columns`
+
+Required:
+
+- `column` (Block List, Min: 1, Max: 1) Represents two possible column types (link column, columnPath) of an observe dataset. (see [below for nested schema](#nestedblock--rules--promote--compare_columns--column))
+- `compare_values` (Block List, Min: 1) list of comparisons that provide an implicit AND where all comparisons must match. (see [below for nested schema](#nestedblock--rules--promote--compare_columns--compare_values))
+
+
+### Nested Schema for `rules.promote.compare_columns.column`
+
+Optional:
+
+- `column_path` (Block List, Max: 1) Specifies how the user wants to group by a specific column name or a JSON object column that has a path. (see [below for nested schema](#nestedblock--rules--promote--compare_columns--column--column_path))
+- `link_column` (Block List, Max: 1) Identifies a link-type column created by connecting two different datasets' columns (primary sources & destination sources). (see [below for nested schema](#nestedblock--rules--promote--compare_columns--column--link_column))
+
+
+### Nested Schema for `rules.promote.compare_columns.column.column_path`
+
+Required:
+
+- `name` (String) The name of the column.
+
+Optional:
+
+- `path` (String) The path of the path, if the name refers to a column with a JSON object.
+
+
+
+### Nested Schema for `rules.promote.compare_columns.column.link_column`
+
+Required:
+
+- `name` (String) The name of the link column.
+
+Optional:
+
+- `meta` (Block List, Max: 1) Contains the context surrounding the link column. (see [below for nested schema](#nestedblock--rules--promote--compare_columns--column--link_column--meta))
+
+
+### Nested Schema for `rules.promote.compare_columns.column.link_column.meta`
+
+Optional:
+
+- `dst_fields` (List of String) The destination fields (a.k.a. primary keys) of the target dataset being linked against.
+- `src_fields` (Block List) The source fields used to link against the primary keys of the target dataset. (see [below for nested schema](#nestedblock--rules--promote--compare_columns--column--link_column--meta--src_fields))
+- `target_dataset` (Number) The resource dataset ID which the link came from. Empty if the link was created from a stage in the shape of a resource from the worksheet.
+
+
+### Nested Schema for `rules.promote.compare_columns.column.link_column.meta.src_fields`
+
+Required:
+
+- `name` (String) The name of the column.
+
+Optional:
+
+- `path` (String) The path of the path, if the name refers to a column with a JSON object.
+
+
+
+
+
+
+### Nested Schema for `rules.promote.compare_columns.compare_values`
+
+Required:
+
+- `compare_fn` (String) the type of comparison (greater, less, equal, etc.)
+
+Optional:
+
+- `value_bool` (List of Boolean) list of size <=1 consisting of a boolean value.
+- `value_duration` (List of Boolean) list of size <=1 consisting of a duration value.
+- `value_float64` (List of Number) list of size <=1 consisting of a float value.
+- `value_int64` (List of Number) list of size <=1 consisting of an integer value.
+- `value_string` (List of String) list of size <=1 consisting of a string value.
+- `value_timestamp` (List of String) list of size <=1 consisting of a timestamp value.
+
+
+
+
+
+### Nested Schema for `rules.threshold`
+
+Required:
+
+- `aggregation` (String) The query aggregator (AllOf, AnyOf, AvgOf, SumOf) for the value monitor type.
+- `compare_values` (Block List, Min: 1) list of comparisons that provide an implicit AND where all comparisons must match. (see [below for nested schema](#nestedblock--rules--threshold--compare_values))
+- `value_column_name` (String) Indicates which column in the input query has the value to apply the aggregation.
+
+Optional:
+
+- `compare_groups` (Block List) list of comparisons made against the columns which the monitor is grouped by. (see [below for nested schema](#nestedblock--rules--threshold--compare_groups))
+
+
+### Nested Schema for `rules.threshold.compare_values`
+
+Required:
+
+- `compare_fn` (String) the type of comparison (greater, less, equal, etc.)
+
+Optional:
+
+- `value_bool` (List of Boolean) list of size <=1 consisting of a boolean value.
+- `value_duration` (List of Boolean) list of size <=1 consisting of a duration value.
+- `value_float64` (List of Number) list of size <=1 consisting of a float value.
+- `value_int64` (List of Number) list of size <=1 consisting of an integer value.
+- `value_string` (List of String) list of size <=1 consisting of a string value.
+- `value_timestamp` (List of String) list of size <=1 consisting of a timestamp value.
+
+
+
+### Nested Schema for `rules.threshold.compare_groups`
+
+Required:
+
+- `column` (Block List, Min: 1, Max: 1) Represents two possible column types (link column, columnPath) of an observe dataset. (see [below for nested schema](#nestedblock--rules--threshold--compare_groups--column))
+- `compare_values` (Block List, Min: 1) list of comparisons that provide an implicit AND where all comparisons must match. (see [below for nested schema](#nestedblock--rules--threshold--compare_groups--compare_values))
+
+
+### Nested Schema for `rules.threshold.compare_groups.column`
+
+Optional:
+
+- `column_path` (Block List, Max: 1) Specifies how the user wants to group by a specific column name or a JSON object column that has a path. (see [below for nested schema](#nestedblock--rules--threshold--compare_groups--column--column_path))
+- `link_column` (Block List, Max: 1) Identifies a link-type column created by connecting two different datasets' columns (primary sources & destination sources). (see [below for nested schema](#nestedblock--rules--threshold--compare_groups--column--link_column))
+
+
+### Nested Schema for `rules.threshold.compare_groups.column.column_path`
+
+Required:
+
+- `name` (String) The name of the column.
+
+Optional:
+
+- `path` (String) The path of the path, if the name refers to a column with a JSON object.
+
+
+
+### Nested Schema for `rules.threshold.compare_groups.column.link_column`
+
+Required:
+
+- `name` (String) The name of the link column.
+
+Optional:
+
+- `meta` (Block List, Max: 1) Contains the context surrounding the link column. (see [below for nested schema](#nestedblock--rules--threshold--compare_groups--column--link_column--meta))
+
+
+### Nested Schema for `rules.threshold.compare_groups.column.link_column.meta`
+
+Optional:
+
+- `dst_fields` (List of String) The destination fields (a.k.a. primary keys) of the target dataset being linked against.
+- `src_fields` (Block List) The source fields used to link against the primary keys of the target dataset. (see [below for nested schema](#nestedblock--rules--threshold--compare_groups--column--link_column--meta--src_fields))
+- `target_dataset` (Number) The resource dataset ID which the link came from. Empty if the link was created from a stage in the shape of a resource from the worksheet.
+
+
+### Nested Schema for `rules.threshold.compare_groups.column.link_column.meta.src_fields`
+
+Required:
+
+- `name` (String) The name of the column.
+
+Optional:
+
+- `path` (String) The path of the path, if the name refers to a column with a JSON object.
+
+
+
+
+
+
+### Nested Schema for `rules.threshold.compare_groups.compare_values`
+
+Required:
+
+- `compare_fn` (String) the type of comparison (greater, less, equal, etc.)
+
+Optional:
+
+- `value_bool` (List of Boolean) list of size <=1 consisting of a boolean value.
+- `value_duration` (List of Boolean) list of size <=1 consisting of a duration value.
+- `value_float64` (List of Number) list of size <=1 consisting of a float value.
+- `value_int64` (List of Number) list of size <=1 consisting of an integer value.
+- `value_string` (List of String) list of size <=1 consisting of a string value.
+- `value_timestamp` (List of String) list of size <=1 consisting of a timestamp value.
+
+
+
+
+
+
+### Nested Schema for `scheduling`
+
+Optional:
+
+- `interval` (Block List, Max: 1) Should be used to run explicit ad-hoc queries. (see [below for nested schema](#nestedblock--scheduling--interval))
+- `transform` (Block List, Max: 1) Should be used to defer scheduling to the transformer and evaluate when data becomes available. (see [below for nested schema](#nestedblock--scheduling--transform))
+
+
+### Nested Schema for `scheduling.interval`
+
+Required:
+
+- `interval` (String) How often the monitor should attempt to run.
+- `randomize` (String) A maximum +/- to apply to the interval to avoid things like harmonics and work stacking up in parallel.
+
+
+
+### Nested Schema for `scheduling.transform`
+
+Required:
+
+- `freshness_goal` (String) The freshness goal.
+
+
+
+
+### Nested Schema for `stage`
+
+Optional:
+
+- `alias` (String) The stage alias is the label by which subsequent stages can refer to the
+results of this stage.
+- `input` (String) The stage input defines what input should be used as a starting point for
+the stage pipeline. It must refer to a label contained in `inputs`, or a
+previous stage `alias`. The stage input can be omitted if `inputs`
+contains a single element.
+- `output_stage` (Boolean) A boolean flag used to specify the output stage. Should be used only for
+a stage preceding the last stage. The last stage is an output stage by default.
+- `pipeline` (String) An OPAL snippet defining a transformation on the selected input.
+
+
+
+### Nested Schema for `groupings`
+
+Optional:
+
+- `column_path` (Block List, Max: 1) Specifies how the user wants to group by a specific column name or a JSON object column that has a path. (see [below for nested schema](#nestedblock--groupings--column_path))
+- `link_column` (Block List, Max: 1) Identifies a link-type column created by connecting two different datasets' columns (primary sources & destination sources). (see [below for nested schema](#nestedblock--groupings--link_column))
+
+
+### Nested Schema for `groupings.column_path`
+
+Required:
+
+- `name` (String) The name of the column.
+
+Optional:
+
+- `path` (String) The path of the path, if the name refers to a column with a JSON object.
+
+
+
+### Nested Schema for `groupings.link_column`
+
+Required:
+
+- `name` (String) The name of the link column.
+
+Optional:
+
+- `meta` (Block List, Max: 1) Contains the context surrounding the link column. (see [below for nested schema](#nestedblock--groupings--link_column--meta))
+
+
+### Nested Schema for `groupings.link_column.meta`
+
+Optional:
+
+- `dst_fields` (List of String) The destination fields (a.k.a. primary keys) of the target dataset being linked against.
+- `src_fields` (Block List) The source fields used to link against the primary keys of the target dataset. (see [below for nested schema](#nestedblock--groupings--link_column--meta--src_fields))
+- `target_dataset` (Number) The resource dataset ID which the link came from. Empty if the link was created from a stage in the shape of a resource from the worksheet.
+
+
+### Nested Schema for `groupings.link_column.meta.src_fields`
+
+Required:
+
+- `name` (String) The name of the column.
+
+Optional:
+
+- `path` (String) The path of the path, if the name refers to a column with a JSON object.
+
diff --git a/observe/descriptions/monitorv2.yaml b/observe/descriptions/monitorv2.yaml
new file mode 100644
index 00000000..b6753d56
--- /dev/null
+++ b/observe/descriptions/monitorv2.yaml
@@ -0,0 +1,105 @@
+description: |
+ NOTE: This feature is still in development. It is not meant for customer use yet.
+
+ Monitors provide a configurable way to alert when conditions about incoming data
+ are matched. These alerts can optionally also be forwarded to notification receivers
+ like email and webhooks using shared or single-monitor actions to configure the
+ template and destinations to configure the receiver.
+
+schema:
+ workspace_id: |
+ OID of the workspace this object is contained in.
+ comment: |
+ A longer description of the monitor. This can include details like how to resolve the issue, links to runbooks, etc.
+ rule_kind: |
+ Describes the type of each of the rules in the definition (they must all be the same type).
+ name: |
+ Monitor name.
+ icon_url: |
+ URL of the monitor icon.
+ description: |
+ A brief description of the monitor.
+ rules:
+ description: |
+ All rules for this monitor must be of the same MonitorRuleKind as specified in ruleKind. Rules should be constructed logically such that a state transition null->Warning implies transition from null->Informational.
+ level: |
+ The alarm level (Critical, Error, Informational, None, Warning).
+ count: |
+ The count rule to apply to incoming data.
+ threshold:
+ description: |
+ Gives flexibility for threshold and range-based monitors to trigger on values. To look for sustained behavior (CPU > 80 for 5 mins), specify lookbackTime.
+ value_column_name: |
+ Indicates which column in the input query has the value to apply the aggregation.
+ aggregation: |
+ The query aggregator (AllOf, AnyOf, AvgOf, SumOf) for the value monitor type.
+ promote: |
+ The monitor will promote each event in the raw input dataset into an alert. For now, the promote rule will ignore link columns and only care about columnWithPath.
+ If multiple compareColumns are specified in one promote rule, it will act as an AND condition. When defined through separate promote rules, it will act as an OR condition.
+ lookback_time: |
+ optionally describes a duration that must be satisifed by this monitor. It applies to all rules, but is only applicable to rule kinds that utilize it.
+ data_stabilization_delay: |
+ expresses the minimum time that should elapse before data is considered "good enough" to evaluate. Choosing a delay really depends on the expectations of latency of data and whether data is expected to arrive later than other data and thus would change previously evaluated results.
+ groupings: |
+ Describes the groups that logically separate events/rows/etc from each other. If monitor dataset is resource type and monitor strategy is promote, this field should be either empty or only contain the primary keys of the dataset.
+ scheduling:
+ description: |
+ Holds information about when the monitor should evaluate. The types of scheduling (interval, transform) are exclusive, but at least one is required.
+ interval:
+ description: |
+ Should be used to run explicit ad-hoc queries.
+ interval: |
+ How often the monitor should attempt to run.
+ randomize: |
+ A maximum +/- to apply to the interval to avoid things like harmonics and work stacking up in parallel.
+ transform:
+ description: |
+ Should be used to defer scheduling to the transformer and evaluate when data becomes available.
+ freshness_goal: |
+ The freshness goal.
+ compare_values: |
+ list of comparisons that provide an implicit AND where all comparisons must match.
+ compare_groups: |
+ list of comparisons made against the columns which the monitor is grouped by.
+ column_path:
+ description: |
+ Specifies how the user wants to group by a specific column name or a JSON object column that has a path.
+ name: |
+ The name of the column.
+ path: |
+ The path of the path, if the name refers to a column with a JSON object.
+ link_column_meta:
+ description: |
+ Contains the context surrounding the link column.
+ src_fields: |
+ The source fields used to link against the primary keys of the target dataset.
+ dst_fields: |
+ The destination fields (a.k.a. primary keys) of the target dataset being linked against.
+ target_dataset: |
+ The resource dataset ID which the link came from. Empty if the link was created from a stage in the shape of a resource from the worksheet.
+ link_column:
+ description: |
+ Identifies a link-type column created by connecting two different datasets' columns (primary sources & destination sources).
+ name: |
+ The name of the link column.
+ comparison:
+ compare_fn: |
+ the type of comparison (greater, less, equal, etc.)
+ value_int64: |
+ list of size <=1 consisting of an integer value.
+ value_float64: |
+ list of size <=1 consisting of a float value.
+ value_bool: |
+ list of size <=1 consisting of a boolean value.
+ value_string: |
+ list of size <=1 consisting of a string value.
+ value_duration: |
+ list of size <=1 consisting of a duration value.
+ value_timestamp: |
+ list of size <=1 consisting of a timestamp value.
+ column:
+ description: |
+ Represents two possible column types (link column, columnPath) of an observe dataset.
+ column_comparison:
+ description: |
+ Specifies the one or multiple values you'd like to compare against the column.
\ No newline at end of file
diff --git a/observe/helpers.go b/observe/helpers.go
index 275b3874..d4b83eab 100644
--- a/observe/helpers.go
+++ b/observe/helpers.go
@@ -295,6 +295,12 @@ func diffSuppressTimeDuration(k, prv, nxt string, d *schema.ResourceData) bool {
return o == n
}
+func diffSuppressTimeDurationZeroDistinctFromEmpty(k, prv, nxt string, d *schema.ResourceData) bool {
+ o, e1 := time.ParseDuration(prv)
+ n, e2 := time.ParseDuration(nxt)
+ return o == n && e1 == e2 // the e1 == e2 check distinguishes "0" from ""
+}
+
func diffSuppressJSON(k, prv, nxt string, d *schema.ResourceData) bool {
var prvValue, nxtValue interface{}
if err := json.Unmarshal([]byte(prv), &prvValue); err != nil {
diff --git a/observe/provider.go b/observe/provider.go
index 8abacb75..92713ad4 100644
--- a/observe/provider.go
+++ b/observe/provider.go
@@ -153,6 +153,7 @@ func Provider() *schema.Provider {
"observe_monitor_action": resourceMonitorAction(),
"observe_monitor_action_attachment": resourceMonitorActionAttachment(),
"observe_monitor": resourceMonitor(),
+ "observe_monitor_v2": resourceMonitorV2(),
"observe_board": resourceBoard(),
"observe_poller": resourcePoller(),
"observe_datastream": resourceDatastream(),
diff --git a/observe/resource_monitor_v2.go b/observe/resource_monitor_v2.go
new file mode 100644
index 00000000..00d27923
--- /dev/null
+++ b/observe/resource_monitor_v2.go
@@ -0,0 +1,1216 @@
+package observe
+
+import (
+ "context"
+ "fmt"
+ "strings"
+ "time"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+ observe "github.com/observeinc/terraform-provider-observe/client"
+ "github.com/observeinc/terraform-provider-observe/client/meta"
+ gql "github.com/observeinc/terraform-provider-observe/client/meta"
+ "github.com/observeinc/terraform-provider-observe/client/meta/types"
+ "github.com/observeinc/terraform-provider-observe/client/oid"
+ "github.com/observeinc/terraform-provider-observe/observe/descriptions"
+)
+
+// TODO: make the schema keys constants?
+// annoying to change varnames in 3 non-obvious places
+
+func resourceMonitorV2() *schema.Resource {
+ return &schema.Resource{
+ Description: descriptions.Get("monitorv2", "description"),
+ CreateContext: resourceMonitorV2Create,
+ ReadContext: resourceMonitorV2Read,
+ UpdateContext: resourceMonitorV2Update,
+ DeleteContext: resourceMonitorV2Delete,
+ Schema: map[string]*schema.Schema{
+ // needed as input to MonitorV2Create, also part of MonitorV2 struct
+ "workspace_id": { // ObjectId!
+ Type: schema.TypeString,
+ ForceNew: true,
+ Required: true,
+ ValidateDiagFunc: validateOID(oid.TypeWorkspace),
+ Description: descriptions.Get("monitorv2", "schema", "workspace_id"),
+ },
+ // fields of MonitorV2Input excluding the components of MonitorV2DefinitionInput
+ "comment": { // String
+ Type: schema.TypeString,
+ Optional: true,
+ Description: descriptions.Get("monitorv2", "schema", "comment"),
+ },
+ "rule_kind": { // MonitorV2RuleKind!
+ Type: schema.TypeString,
+ Required: true,
+ ValidateDiagFunc: validateEnums(gql.AllMonitorV2RuleKinds),
+ Description: descriptions.Get("monitorv2", "schema", "rule_kind"),
+ },
+ "name": { // String!
+ Type: schema.TypeString,
+ Required: true,
+ Description: descriptions.Get("monitorv2", "schema", "name"),
+ },
+ "icon_url": { // String
+ Type: schema.TypeString,
+ Optional: true,
+ Description: descriptions.Get("monitorv2", "schema", "icon_url"),
+ },
+ "description": { // String
+ Type: schema.TypeString,
+ Optional: true,
+ Description: descriptions.Get("monitorv2", "schema", "description"),
+ },
+ // until specified otherwise, the following are for building MonitorV2DefinitionInput
+ "stage": { // for building inputQuery (MultiStageQueryInput!))
+ Type: schema.TypeList,
+ MinItems: 1,
+ Required: true,
+ Description: descriptions.Get("transform", "schema", "stage", "description"),
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "alias": {
+ Type: schema.TypeString,
+ Optional: true,
+ DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
+ // ignore alias for last stage, because it won't be set anyway
+ stage := d.Get("stage").([]interface{})
+ return k == fmt.Sprintf("stage.%d.alias", len(stage)-1)
+ },
+ Description: descriptions.Get("transform", "schema", "stage", "alias"),
+ },
+ "input": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: descriptions.Get("transform", "schema", "stage", "input"),
+ },
+ "pipeline": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: descriptions.Get("transform", "schema", "stage", "pipeline"),
+ },
+ "output_stage": {
+ Type: schema.TypeBool,
+ Default: false,
+ Optional: true,
+ Description: descriptions.Get("transform", "schema", "stage", "output_stage"),
+ },
+ },
+ },
+ },
+ "inputs": { // for building inputQuery (MultiStageQueryInput!)
+ Type: schema.TypeMap,
+ Required: true,
+ ValidateDiagFunc: validateMapValues(validateOID()),
+ Description: descriptions.Get("transform", "schema", "inputs"),
+ },
+ "rules": { // [MonitorV2RuleInput!]!
+ Type: schema.TypeList,
+ Required: true,
+ MinItems: 1,
+ Description: descriptions.Get("monitorv2", "schema", "rules", "description"),
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "level": { // MonitorV2AlarmLevel!
+ Type: schema.TypeString,
+ Required: true,
+ ValidateDiagFunc: validateEnums(gql.AllMonitorV2AlarmLevels),
+ Description: descriptions.Get("monitorv2", "schema", "rules", "level"),
+ },
+ "count": { // MonitorV2CountRuleInput
+ Type: schema.TypeList,
+ Optional: true,
+ MaxItems: 1,
+ Description: descriptions.Get("monitorv2", "schema", "rules", "count"),
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "compare_values": { // [MonitorV2ComparisonInput!]!
+ Type: schema.TypeList,
+ Required: true,
+ MinItems: 1,
+ Description: descriptions.Get("monitorv2", "schema", "compare_values"),
+ Elem: monitorV2ComparisonResource(),
+ },
+ "compare_groups": { // [MonitorV2ColumnComparisonInput!]
+ Type: schema.TypeList,
+ Optional: true,
+ Description: descriptions.Get("monitorv2", "schema", "compare_groups"),
+ Elem: monitorV2ColumnComparisonResource(),
+ },
+ },
+ },
+ },
+ "threshold": { // MonitorV2ThresholdRuleInput
+ Type: schema.TypeList,
+ Optional: true,
+ MaxItems: 1,
+ Description: descriptions.Get("monitorv2", "schema", "rules", "threshold", "description"),
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "compare_values": { // [MonitorV2ComparisonInput!]!
+ Type: schema.TypeList,
+ Required: true,
+ MinItems: 1,
+ Elem: monitorV2ComparisonResource(),
+ Description: descriptions.Get("monitorv2", "schema", "compare_values"),
+ },
+ "value_column_name": { // String!
+ Type: schema.TypeString,
+ Required: true,
+ Description: descriptions.Get("monitorv2", "schema", "rules", "threshold", "value_column_name"),
+ },
+ "aggregation": { // MonitorV2ValueAggregation!
+ Type: schema.TypeString,
+ Required: true,
+ ValidateDiagFunc: validateEnums(gql.AllMonitorV2ValueAggregations),
+ Description: descriptions.Get("monitorv2", "schema", "rules", "threshold", "aggregation"),
+ },
+ "compare_groups": { // [MonitorV2ColumnComparisonInput!]
+ Type: schema.TypeList,
+ Optional: true,
+ Elem: monitorV2ColumnComparisonResource(),
+ Description: descriptions.Get("monitorv2", "schema", "compare_groups"),
+ },
+ },
+ },
+ },
+ "promote": { // MonitorV2PromoteRuleInput
+ Type: schema.TypeList,
+ Optional: true,
+ MaxItems: 1,
+ Description: descriptions.Get("monitorv2", "schema", "rules", "promote"),
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "compare_columns": { // [MonitorV2ColumnComparisonInput!]
+ Type: schema.TypeList,
+ Optional: true,
+ Elem: monitorV2ColumnComparisonResource(),
+ Description: descriptions.Get("monitorv2", "schema", "column_comparison", "description"),
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ "lookback_time": { // Duration
+ Type: schema.TypeString,
+ Optional: true,
+ ValidateDiagFunc: validateTimeDuration,
+ DiffSuppressFunc: diffSuppressTimeDurationZeroDistinctFromEmpty,
+ Description: descriptions.Get("monitorv2", "schema", "lookback_time"),
+ },
+ "data_stabilization_delay": { // Duration
+ Type: schema.TypeString,
+ Optional: true,
+ ValidateDiagFunc: validateTimeDuration,
+ DiffSuppressFunc: diffSuppressTimeDurationZeroDistinctFromEmpty,
+ Description: descriptions.Get("monitorv2", "schema", "data_stabilization_delay"),
+ },
+ "groupings": { // [MonitorV2ColumnInput!]
+ Type: schema.TypeList,
+ Optional: true,
+ Elem: monitorV2ColumnResource(),
+ Description: descriptions.Get("monitorv2", "schema", "groupings"),
+ },
+ "scheduling": { // MonitorV2SchedulingInput (required *only* for TF)
+ Type: schema.TypeList,
+ Required: true,
+ MaxItems: 1,
+ Description: descriptions.Get("monitorv2", "schema", "scheduling", "description"),
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "interval": { // MonitorV2IntervalScheduleInput
+ Type: schema.TypeList,
+ Optional: true,
+ MaxItems: 1,
+ ExactlyOneOf: []string{"scheduling.0.interval", "scheduling.0.transform"},
+ Description: descriptions.Get("monitorv2", "schema", "scheduling", "interval", "description"),
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "interval": { // Duration!
+ Type: schema.TypeString,
+ Required: true,
+ ValidateDiagFunc: validateTimeDuration,
+ DiffSuppressFunc: diffSuppressTimeDurationZeroDistinctFromEmpty,
+ Description: descriptions.Get("monitorv2", "schema", "scheduling", "interval", "interval"),
+ },
+ "randomize": { // Duration!
+ Type: schema.TypeString,
+ Required: true,
+ ValidateDiagFunc: validateTimeDuration,
+ DiffSuppressFunc: diffSuppressTimeDurationZeroDistinctFromEmpty,
+ Description: descriptions.Get("monitorv2", "schema", "scheduling", "interval", "randomize"),
+ },
+ },
+ },
+ },
+ "transform": { // MonitorV2TransformScheduleInput
+ Type: schema.TypeList,
+ Optional: true,
+ MaxItems: 1,
+ ExactlyOneOf: []string{"scheduling.0.interval", "scheduling.0.transform"},
+ Description: descriptions.Get("monitorv2", "schema", "scheduling", "transform", "description"),
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "freshness_goal": { // Duration!
+ Type: schema.TypeString,
+ Required: true,
+ ValidateDiagFunc: validateTimeDuration,
+ DiffSuppressFunc: diffSuppressTimeDurationZeroDistinctFromEmpty,
+ Description: descriptions.Get("monitorv2", "schema", "scheduling", "transform", "freshness_goal"),
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ // end of fields of MonitorV2DefinitionInput
+ // the following fields are those that aren't given as input to CU ops, but can be read by R ops.
+ "id": { // ObjectId!
+ Type: schema.TypeString,
+ Computed: true,
+ },
+ },
+ }
+}
+
+func monitorV2ComparisonResource() *schema.Resource {
+ return &schema.Resource{ // MonitorV2Comparison
+ Schema: map[string]*schema.Schema{
+ "compare_fn": { // MonitorV2ComparisonFunction!
+ Type: schema.TypeString,
+ Required: true,
+ ValidateDiagFunc: validateEnums(gql.AllCompareFunctions),
+ Description: descriptions.Get("monitorv2", "schema", "comparison", "compare_fn"),
+ },
+ "value_int64": { // Int64
+ Type: schema.TypeList,
+ Optional: true,
+ MaxItems: 1,
+ Elem: &schema.Schema{Type: schema.TypeInt},
+ Description: descriptions.Get("monitorv2", "schema", "comparison", "value_int64"),
+ },
+ "value_float64": { // Float
+ Type: schema.TypeList,
+ Optional: true,
+ MaxItems: 1,
+ Elem: &schema.Schema{Type: schema.TypeFloat},
+ Description: descriptions.Get("monitorv2", "schema", "comparison", "value_float64"),
+ },
+ "value_bool": { // Boolean
+ Type: schema.TypeList,
+ Optional: true,
+ MaxItems: 1,
+ Elem: &schema.Schema{Type: schema.TypeBool},
+ Description: descriptions.Get("monitorv2", "schema", "comparison", "value_bool"),
+ },
+ "value_string": { // String
+ Type: schema.TypeList,
+ Optional: true,
+ MaxItems: 1,
+ Elem: &schema.Schema{Type: schema.TypeString},
+ Description: descriptions.Get("monitorv2", "schema", "comparison", "value_string"),
+ },
+ "value_duration": { // Int64
+ Type: schema.TypeList,
+ Optional: true,
+ MaxItems: 1,
+ Elem: &schema.Schema{
+ Type: schema.TypeBool,
+ ValidateDiagFunc: validateTimeDuration,
+ DiffSuppressFunc: diffSuppressTimeDurationZeroDistinctFromEmpty,
+ },
+ Description: descriptions.Get("monitorv2", "schema", "comparison", "value_duration"),
+ },
+ "value_timestamp": { // Time
+ Type: schema.TypeList,
+ Optional: true,
+ MaxItems: 1,
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ ValidateDiagFunc: validateTimestamp,
+ },
+ Description: descriptions.Get("monitorv2", "schema", "comparison", "value_timestamp"),
+ },
+ },
+ }
+}
+
+func monitorV2ColumnPathResource() *schema.Resource {
+ return &schema.Resource{ // MonitorV2ColumnPathInput
+ Schema: map[string]*schema.Schema{
+ "name": { // String!
+ Type: schema.TypeString,
+ Required: true,
+ Description: descriptions.Get("monitorv2", "schema", "column_path", "name"),
+ },
+ "path": { // String
+ Type: schema.TypeString,
+ Optional: true,
+ Description: descriptions.Get("monitorv2", "schema", "column_path", "path"),
+ },
+ },
+ }
+}
+
+func monitorV2LinkColumnMetaResource() *schema.Resource {
+ return &schema.Resource{ // MonitorV2LinkColumnMetaInput
+ Schema: map[string]*schema.Schema{
+ "src_fields": { // [MonitorV2ColumnPathInput!]
+ Type: schema.TypeList,
+ Optional: true,
+ Elem: monitorV2ColumnPathResource(),
+ Description: descriptions.Get("monitorv2", "schema", "link_column_meta", "src_fields"),
+ },
+ "dst_fields": { // [String!]
+ Type: schema.TypeList,
+ Optional: true,
+ Elem: &schema.Schema{Type: schema.TypeString},
+ Description: descriptions.Get("monitorv2", "schema", "link_column_meta", "dst_fields"),
+ },
+ "target_dataset": { // Int64
+ Type: schema.TypeInt,
+ Optional: true,
+ Description: descriptions.Get("monitorv2", "schema", "link_column_meta", "target_dataset"),
+ },
+ },
+ }
+}
+
+func monitorV2LinkColumnResource() *schema.Resource {
+ return &schema.Resource{ // MonitorV2LinkColumnInput
+ Schema: map[string]*schema.Schema{
+ "name": { // String!
+ Type: schema.TypeString,
+ Required: true,
+ Description: descriptions.Get("monitorv2", "schema", "link_column", "name"),
+ },
+ "meta": { // MonitorV2LinkColumnMetaInput
+ Type: schema.TypeList,
+ Optional: true,
+ MaxItems: 1,
+ Elem: monitorV2LinkColumnMetaResource(),
+ Description: descriptions.Get("monitorv2", "schema", "link_column_meta", "description"),
+ },
+ },
+ }
+}
+
+func monitorV2ColumnResource() *schema.Resource {
+ return &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "link_column": { // MonitorV2LinkColumnInput
+ Type: schema.TypeList,
+ Optional: true,
+ MaxItems: 1,
+ Elem: monitorV2LinkColumnResource(),
+ Description: descriptions.Get("monitorv2", "schema", "link_column", "description"),
+ },
+ "column_path": { // MonitorV2ColumnPathInput
+ Type: schema.TypeList,
+ Optional: true,
+ MaxItems: 1,
+ Elem: monitorV2ColumnPathResource(),
+ Description: descriptions.Get("monitorv2", "schema", "column_path", "description"),
+ },
+ },
+ }
+}
+
+func monitorV2ColumnComparisonResource() *schema.Resource {
+ return &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "compare_values": { // [MonitorV2ComparisonInput!]!
+ Type: schema.TypeList,
+ Required: true,
+ MinItems: 1,
+ Elem: monitorV2ComparisonResource(),
+ Description: descriptions.Get("monitorv2", "schema", "compare_values"),
+ },
+ "column": { // MonitorV2ColumnInput!
+ Type: schema.TypeList,
+ Required: true,
+ MinItems: 1,
+ MaxItems: 1,
+ Elem: monitorV2ColumnResource(),
+ Description: descriptions.Get("monitorv2", "schema", "column", "description"),
+ },
+ },
+ }
+}
+
+func resourceMonitorV2Create(ctx context.Context, data *schema.ResourceData, meta interface{}) (diags diag.Diagnostics) {
+ client := meta.(*observe.Client)
+
+ input, diags := newMonitorV2Input(data)
+ if diags.HasError() {
+ return diags
+ }
+
+ id, _ := oid.NewOID(data.Get("workspace_id").(string))
+ result, err := client.CreateMonitorV2(ctx, id.Id, input)
+ if err != nil {
+ return diag.Errorf("failed to create monitor: %s", err.Error())
+ }
+
+ data.SetId(result.Id)
+ return append(diags, resourceMonitorV2Read(ctx, data, meta)...)
+}
+
+func resourceMonitorV2Update(ctx context.Context, data *schema.ResourceData, meta interface{}) (diags diag.Diagnostics) {
+ client := meta.(*observe.Client)
+
+ input, diags := newMonitorV2Input(data)
+ if diags.HasError() {
+ return diags
+ }
+
+ _, err := client.UpdateMonitorV2(ctx, data.Id(), input)
+ if err != nil {
+ if gql.HasErrorCode(err, "NOT_FOUND") {
+ diags = resourceMonitorV2Create(ctx, data, meta)
+ if diags.HasError() {
+ return diags
+ }
+ return nil
+ }
+ return diag.Errorf("failed to create monitor: %s", err.Error())
+ }
+
+ return append(diags, resourceMonitorV2Read(ctx, data, meta)...)
+}
+
+func resourceMonitorV2Read(ctx context.Context, data *schema.ResourceData, meta interface{}) (diags diag.Diagnostics) {
+ client := meta.(*observe.Client)
+
+ monitor, err := client.GetMonitorV2(ctx, data.Id())
+ if err != nil {
+ if gql.HasErrorCode(err, "NOT_FOUND") {
+ data.SetId("")
+ return nil
+ }
+ return diag.Errorf("failed to read monitorv2: %s", err.Error())
+ }
+
+ // perform data.set on all the fields from this monitor
+ if err := data.Set("workspace_id", oid.WorkspaceOid(monitor.WorkspaceId).String()); err != nil {
+ diags = append(diags, diag.FromErr(err)...)
+ }
+
+ if err := data.Set("name", monitor.Name); err != nil {
+ diags = append(diags, diag.FromErr(err)...)
+ }
+
+ if err := data.Set("icon_url", monitor.IconUrl); err != nil {
+ diags = append(diags, diag.FromErr(err)...)
+ }
+
+ if err := data.Set("description", monitor.Description); err != nil {
+ diags = append(diags, diag.FromErr(err)...)
+ }
+
+ if err := data.Set("id", monitor.Oid().String()); err != nil {
+ diags = append(diags, diag.FromErr(err)...)
+ }
+
+ if err := data.Set("rule_kind", toSnake(string(monitor.GetRuleKind()))); err != nil {
+ diags = append(diags, diag.FromErr(err)...)
+ }
+
+ _, err = flattenAndSetQuery(data, monitor.Definition.InputQuery.Stages, monitor.Definition.InputQuery.OutputStage)
+ if err != nil {
+ diags = append(diags, diag.FromErr(err)...)
+ }
+
+ if err := data.Set("rules", monitorV2FlattenRules(monitor.Definition.Rules)); err != nil {
+ diags = append(diags, diag.FromErr(err)...)
+ }
+
+ if err := data.Set("lookback_time", monitor.Definition.LookbackTime.String()); err != nil {
+ diags = append(diags, diag.FromErr(err)...)
+ }
+
+ if monitor.Definition.DataStabilizationDelay != nil {
+ if err := data.Set("data_stabilization_delay", monitor.Definition.DataStabilizationDelay.String()); err != nil {
+ diags = append(diags, diag.FromErr(err)...)
+ }
+ }
+
+ if monitor.Definition.Groupings != nil {
+ if err := data.Set("groupings", monitorV2FlattenGroupings(monitor.Definition.Groupings)); err != nil {
+ diags = append(diags, diag.FromErr(err)...)
+ }
+ }
+
+ if monitor.Definition.Scheduling != nil {
+ if err := data.Set("scheduling", monitorV2FlattenScheduling(*monitor.Definition.Scheduling)); err != nil {
+ diags = append(diags, diag.FromErr(err)...)
+ }
+ }
+
+ return diags
+}
+
+func resourceMonitorV2Delete(ctx context.Context, data *schema.ResourceData, meta interface{}) (diags diag.Diagnostics) {
+ client := meta.(*observe.Client)
+ if err := client.DeleteMonitorV2(ctx, data.Id()); err != nil {
+ return diag.Errorf("failed to delete monitor: %s", err.Error())
+ }
+ return diags
+}
+
+func monitorV2FlattenRules(gqlRules []gql.MonitorV2Rule) []interface{} {
+ var rules []interface{}
+ for _, gqlRule := range gqlRules {
+ rules = append(rules, monitorV2FlattenRule(gqlRule))
+ }
+ return rules
+}
+
+func monitorV2FlattenRule(gqlRule gql.MonitorV2Rule) interface{} {
+ rule := map[string]interface{}{
+ "level": toSnake(string(gqlRule.Level)),
+ }
+ if gqlRule.Count != nil {
+ rule["count"] = monitorV2FlattenCountRule(*gqlRule.Count)
+ }
+ if gqlRule.Threshold != nil {
+ rule["threshold"] = monitorV2FlattenThresholdRule(*gqlRule.Threshold)
+ }
+ if gqlRule.Promote != nil {
+ rule["promote"] = monitorV2FlattenPromoteRule(*gqlRule.Promote)
+ }
+ return rule
+}
+
+func monitorV2FlattenCountRule(gqlCount gql.MonitorV2CountRule) []interface{} {
+ countRule := map[string]interface{}{}
+ if gqlCount.CompareValues != nil {
+ countRule["compare_values"] = monitorV2FlattenComparisons(gqlCount.CompareValues)
+ }
+ if gqlCount.CompareGroups != nil {
+ countRule["compare_groups"] = monitorV2FlattenColumnComparisons(gqlCount.CompareGroups)
+ }
+ return []interface{}{countRule}
+}
+
+func monitorV2FlattenThresholdRule(gqlThreshold gql.MonitorV2ThresholdRule) []interface{} {
+ thresholdRule := map[string]interface{}{
+ "value_column_name": gqlThreshold.ValueColumnName,
+ "aggregation": toSnake(string(gqlThreshold.Aggregation)),
+ }
+ if gqlThreshold.CompareValues != nil {
+ thresholdRule["compare_values"] = monitorV2FlattenComparisons(gqlThreshold.CompareValues)
+ }
+ if gqlThreshold.CompareGroups != nil {
+ thresholdRule["compare_groups"] = monitorV2FlattenColumnComparisons(gqlThreshold.CompareGroups)
+ }
+ return []interface{}{thresholdRule}
+}
+
+func monitorV2FlattenPromoteRule(gqlPromote gql.MonitorV2PromoteRule) []interface{} {
+ promoteRule := map[string]interface{}{}
+ if gqlPromote.CompareColumns != nil {
+ promoteRule["compare_columns"] = monitorV2FlattenColumnComparisons(gqlPromote.CompareColumns)
+ }
+ return []interface{}{promoteRule}
+}
+
+func monitorV2FlattenColumnComparisons(gqlColumnComparisons []gql.MonitorV2ColumnComparison) []interface{} {
+ columnComparisons := []interface{}{}
+ for _, gqlColumnComparison := range gqlColumnComparisons {
+ columnComparisons = append(columnComparisons, monitorV2FlattenColumnComparison(gqlColumnComparison))
+ }
+ return columnComparisons
+}
+
+func monitorV2FlattenColumnComparison(gqlColumnComparison gql.MonitorV2ColumnComparison) interface{} {
+ columnComparison := map[string]interface{}{
+ "column": monitorV2FlattenColumn(gqlColumnComparison.Column),
+ }
+ if gqlColumnComparison.CompareValues != nil {
+ columnComparison["compare_values"] = monitorV2FlattenComparisons(gqlColumnComparison.CompareValues)
+ }
+ return columnComparison
+}
+
+func monitorV2FlattenColumn(gqlColumn gql.MonitorV2Column) []interface{} {
+ column := map[string]interface{}{}
+ if gqlColumn.LinkColumn != nil {
+ column["link_column"] = monitorV2FlattenLinkColumn(*gqlColumn.LinkColumn)
+ }
+ if gqlColumn.ColumnPath != nil {
+ column["column_path"] = monitorV2FlattenColumnPath(*gqlColumn.ColumnPath)
+ }
+ return []interface{}{column}
+}
+
+func monitorV2FlattenComparisons(gqlComparisons []gql.MonitorV2Comparison) []interface{} {
+ comparisons := []interface{}{}
+ for _, gqlComparison := range gqlComparisons {
+ comparisons = append(comparisons, monitorV2FlattenComparison(gqlComparison))
+ }
+ return comparisons
+}
+
+func monitorV2FlattenComparison(gqlComparison gql.MonitorV2Comparison) interface{} {
+ comparison := map[string]interface{}{
+ "compare_fn": toSnake(string(gqlComparison.CompareFn)),
+ }
+ monitorV2FlattenPrimitiveValue(gqlComparison.CompareValue, comparison)
+ return comparison
+}
+
+func monitorV2FlattenPrimitiveValue(gqlPrimitiveValue gql.PrimitiveValue, primitiveValue map[string]interface{}) {
+ if gqlPrimitiveValue.Bool != nil {
+ primitiveValue["value_bool"] = []interface{}{*gqlPrimitiveValue.Bool}
+ }
+ if gqlPrimitiveValue.Int64 != nil {
+ primitiveValue["value_int64"] = []interface{}{int(*gqlPrimitiveValue.Int64)}
+ }
+ if gqlPrimitiveValue.Float64 != nil {
+ primitiveValue["value_float64"] = []interface{}{*gqlPrimitiveValue.Float64}
+ }
+ if gqlPrimitiveValue.String != nil {
+ primitiveValue["value_string"] = []interface{}{*gqlPrimitiveValue.String}
+ }
+ if gqlPrimitiveValue.Timestamp != nil {
+ primitiveValue["value_timestamp"] = []interface{}{gqlPrimitiveValue.Timestamp.String()}
+ }
+ if gqlPrimitiveValue.Duration != nil {
+ primitiveValue["value_duration"] = []interface{}{gqlPrimitiveValue.Duration.String()}
+ }
+}
+
+func monitorV2FlattenGroupings(gqlGroupings []gql.MonitorV2Column) []interface{} {
+ var groupings []interface{}
+ for _, gqlGrouping := range gqlGroupings {
+ grouping := map[string]interface{}{}
+ if gqlGrouping.LinkColumn != nil {
+ grouping["link_column"] = monitorV2FlattenLinkColumn(*gqlGrouping.LinkColumn)
+ }
+ if gqlGrouping.ColumnPath != nil {
+ grouping["column_path"] = monitorV2FlattenColumnPath(*gqlGrouping.ColumnPath)
+ }
+ groupings = append(groupings, grouping)
+ }
+ return groupings
+}
+
+func monitorV2FlattenColumnPaths(gqlColumnPaths []gql.MonitorV2ColumnPath) []interface{} {
+ var columnPaths []interface{}
+ for _, gqlColumnPath := range gqlColumnPaths {
+ columnPaths = append(columnPaths, monitorV2FlattenColumnPath(gqlColumnPath))
+ }
+ return columnPaths
+}
+
+func monitorV2FlattenColumnPath(gqlColumnPath gql.MonitorV2ColumnPath) []interface{} {
+ columnPath := map[string]interface{}{
+ "name": gqlColumnPath.Name,
+ }
+ if gqlColumnPath.Path != nil {
+ columnPath["path"] = *gqlColumnPath.Path
+ }
+ return []interface{}{columnPath}
+}
+
+func monitorV2FlattenLinkColumn(gqlLinkColumn gql.MonitorV2LinkColumn) []interface{} {
+ linkColumn := map[string]interface{}{
+ "name": gqlLinkColumn.Name,
+ }
+ if gqlLinkColumn.Meta != nil {
+ linkColumn["meta"] = monitorV2FlattenLinkColumnMeta(*gqlLinkColumn.Meta)
+ }
+ return []interface{}{linkColumn}
+}
+
+func monitorV2FlattenLinkColumnMeta(gqlLinkColumnMeta gql.MonitorV2LinkColumnMeta) []interface{} {
+ linkColumnMeta := map[string]interface{}{}
+ if gqlLinkColumnMeta.SrcFields != nil {
+ linkColumnMeta["src_fields"] = monitorV2FlattenColumnPaths(gqlLinkColumnMeta.SrcFields)
+ }
+ if gqlLinkColumnMeta.DstFields != nil {
+ linkColumnMeta["dst_fields"] = gqlLinkColumnMeta.DstFields
+ }
+ if gqlLinkColumnMeta.TargetDataset != nil {
+ linkColumnMeta["target_dataset"] = *gqlLinkColumnMeta.TargetDataset
+ }
+ return []interface{}{linkColumnMeta}
+}
+
+func monitorV2FlattenScheduling(gqlScheduling gql.MonitorV2Scheduling) []interface{} {
+ scheduling := map[string]interface{}{}
+ if gqlScheduling.Interval != nil {
+ scheduling["interval"] = monitorV2FlattenIntervalSchedule(*gqlScheduling.Interval)
+ }
+ if gqlScheduling.Transform != nil {
+ scheduling["transform"] = monitorV2FlattenTransformSchedule(*gqlScheduling.Transform)
+ }
+ return []interface{}{scheduling}
+}
+
+func monitorV2FlattenIntervalSchedule(gqlIntervalSchedule gql.MonitorV2IntervalSchedule) []interface{} {
+ intervalSchedule := map[string]interface{}{
+ "interval": gqlIntervalSchedule.Interval.String(),
+ "randomize": gqlIntervalSchedule.Randomize.String(),
+ }
+ return []interface{}{intervalSchedule}
+}
+
+func monitorV2FlattenTransformSchedule(gqlTransformSchedule gql.MonitorV2TransformSchedule) []interface{} {
+ transformSchedule := map[string]interface{}{
+ "freshness_goal": gqlTransformSchedule.FreshnessGoal.String(),
+ }
+ return []interface{}{transformSchedule}
+}
+
+func newMonitorV2Input(data *schema.ResourceData) (input *gql.MonitorV2Input, diags diag.Diagnostics) {
+ // required
+ definitionInput, diags := newMonitorV2DefinitionInput(data)
+ if diags.HasError() {
+ return nil, diags
+ }
+ ruleKind := toCamel(data.Get("rule_kind").(string))
+ name := data.Get("name").(string)
+
+ // instantiation
+ input = &gql.MonitorV2Input{
+ Definition: *definitionInput,
+ RuleKind: meta.MonitorV2RuleKind(ruleKind),
+ Name: name,
+ }
+
+ // optionals
+ if v, ok := data.GetOk("comment"); ok {
+ input.Comment = stringPtr(v.(string))
+ }
+ if v, ok := data.GetOk("icon_url"); ok {
+ input.IconUrl = stringPtr(v.(string))
+ }
+ if v, ok := data.GetOk("description"); ok {
+ input.Description = stringPtr(v.(string))
+ }
+
+ return input, diags
+}
+
+func newMonitorV2DefinitionInput(data *schema.ResourceData) (defnInput *gql.MonitorV2DefinitionInput, diags diag.Diagnostics) {
+ // required
+ query, diags := newQuery(data)
+ if diags.HasError() {
+ return nil, diags
+ }
+ if query == nil {
+ return nil, diag.Errorf("no query provided")
+ }
+ rules := make([]gql.MonitorV2RuleInput, 0)
+ for i := range data.Get("rules").([]interface{}) {
+ rule, diags := newMonitorV2RuleInput(fmt.Sprintf("rules.%d.", i), data)
+ if diags.HasError() {
+ return nil, diags
+ }
+ rules = append(rules, *rule)
+ }
+ scheduling, diags := newMonitorV2SchedulingInput("scheduling.0.", data)
+ if diags.HasError() {
+ return nil, diags
+ }
+
+ // instantiation
+ defnInput = &gql.MonitorV2DefinitionInput{
+ InputQuery: *query,
+ Rules: rules,
+ Scheduling: scheduling,
+ }
+
+ // optionals
+ if v, ok := data.GetOk("data_stabilization_delay"); ok {
+ dataStabilizationDelay, _ := types.ParseDurationScalar(v.(string))
+ defnInput.DataStabilizationDelay = dataStabilizationDelay
+ }
+ if _, ok := data.GetOk("groupings"); ok {
+ groupings := make([]gql.MonitorV2ColumnInput, 0)
+ for _, i := range data.Get("groupings").([]interface{}) {
+ colInput, diags := newMonitorV2ColumnInput(fmt.Sprintf("groupings.%d.", i), data)
+ if diags.HasError() {
+ return nil, diags
+ }
+ groupings = append(groupings, *colInput)
+ }
+ defnInput.Groupings = groupings
+ }
+ if lookbackTimeStr, ok := data.GetOk("lookback_time"); ok {
+ lookbackTime, err := types.ParseDurationScalar(lookbackTimeStr.(string))
+ if err != nil {
+ return nil, diag.Errorf("lookback_time is invalid: %s", err.Error())
+ }
+ defnInput.LookbackTime = lookbackTime
+ } else {
+ lookbackTime, err := types.ParseDurationScalar("0")
+ if err != nil {
+ return nil, diag.Errorf("lookback_time is invalid: %s", err.Error())
+ }
+ defnInput.LookbackTime = lookbackTime
+ }
+
+ return defnInput, diags
+}
+
+func newMonitorV2SchedulingInput(path string, data *schema.ResourceData) (scheduling *gql.MonitorV2SchedulingInput, diags diag.Diagnostics) {
+ // instantiation
+ scheduling = &gql.MonitorV2SchedulingInput{}
+
+ // optionals
+ if _, ok := data.GetOk(fmt.Sprintf("%sinterval", path)); ok {
+ interval, diags := newMonitorV2IntervalScheduleInput(fmt.Sprintf("%sinterval.0.", path), data)
+ if diags.HasError() {
+ return nil, diags
+ }
+ scheduling.Interval = interval
+ }
+ if _, ok := data.GetOk(fmt.Sprintf("%stransform", path)); ok {
+ transform, diags := newMonitorV2TransformScheduleInput(fmt.Sprintf("%stransform.0.", path), data)
+ if diags.HasError() {
+ return nil, diags
+ }
+ scheduling.Transform = transform
+ }
+
+ return scheduling, diags
+}
+
+func newMonitorV2IntervalScheduleInput(path string, data *schema.ResourceData) (interval *gql.MonitorV2IntervalScheduleInput, diags diag.Diagnostics) {
+ // required
+ intervalField := data.Get(fmt.Sprintf("%sinterval", path)).(string)
+ randomizeField := data.Get(fmt.Sprintf("%srandomize", path)).(string)
+ intervalDuration, _ := types.ParseDurationScalar(intervalField)
+ randomizeDuration, _ := types.ParseDurationScalar(randomizeField)
+
+ // instantiation
+ interval = &gql.MonitorV2IntervalScheduleInput{
+ Interval: *intervalDuration,
+ Randomize: *randomizeDuration,
+ }
+
+ return interval, diags
+}
+
+func newMonitorV2TransformScheduleInput(path string, data *schema.ResourceData) (transform *gql.MonitorV2TransformScheduleInput, diags diag.Diagnostics) {
+ // required
+ transformField := data.Get(fmt.Sprintf("%sfreshness_goal", path)).(string)
+ transformDuration, _ := types.ParseDurationScalar(transformField)
+
+ // instantiation
+ transform = &gql.MonitorV2TransformScheduleInput{FreshnessGoal: *transformDuration}
+
+ return transform, diags
+}
+
+func newMonitorV2RuleInput(path string, data *schema.ResourceData) (rule *gql.MonitorV2RuleInput, diags diag.Diagnostics) {
+ // required
+ level := toCamel(data.Get(fmt.Sprintf("%slevel", path)).(string))
+
+ // instantiation
+ rule = &gql.MonitorV2RuleInput{Level: gql.MonitorV2AlarmLevel(level)}
+
+ // optionals
+ nRules := 0
+ if _, ok := data.GetOk(fmt.Sprintf("%scount", path)); ok {
+ count, diags := newMonitorV2CountRuleInput(fmt.Sprintf("%scount.0.", path), data)
+ if diags.HasError() {
+ return nil, diags
+ }
+ rule.Count = count
+ nRules++
+ }
+ if _, ok := data.GetOk(fmt.Sprintf("%sthreshold", path)); ok {
+ threshold, diags := newMonitorV2ThresholdRuleInput(fmt.Sprintf("%sthreshold.0.", path), data)
+ if diags.HasError() {
+ return nil, diags
+ }
+ rule.Threshold = threshold
+ nRules++
+ }
+ if _, ok := data.GetOk(fmt.Sprintf("%spromote", path)); ok {
+ promote, diags := newMonitorV2PromoteRuleInput(fmt.Sprintf("%spromote.0.", path), data)
+ if diags.HasError() {
+ return nil, diags
+ }
+ rule.Promote = promote
+ nRules++
+ }
+ if nRules != 1 {
+ return nil, diag.Errorf("exactly one of count, threshold, or promote must be specified")
+ }
+
+ return rule, diags
+}
+
+func newMonitorV2CountRuleInput(path string, data *schema.ResourceData) (comparison *gql.MonitorV2CountRuleInput, diags diag.Diagnostics) {
+ // required
+ comparisonInputs := make([]gql.MonitorV2ComparisonInput, 0)
+ for i := range data.Get(fmt.Sprintf("%scompare_values", path)).([]interface{}) {
+ comparisonInput, diags := newMonitorV2ComparisonInput(fmt.Sprintf("%scompare_values.%d.", path, i), data)
+ if diags.HasError() {
+ return nil, diags
+ }
+ comparisonInputs = append(comparisonInputs, *comparisonInput)
+ }
+
+ // instantiation
+ comparison = &gql.MonitorV2CountRuleInput{
+ CompareValues: comparisonInputs,
+ }
+
+ // optionals
+ if _, ok := data.GetOk(fmt.Sprintf("%scompare_groups", path)); ok {
+ compareGroups := make([]gql.MonitorV2ColumnComparisonInput, 0)
+ for _, i := range data.Get(fmt.Sprintf("%scompare_groups", path)).([]interface{}) {
+ columnComparison, diags := newMonitorV2ColumnComparisonInput(fmt.Sprintf("%scompare_groups.%d.", path, i), data)
+ if diags.HasError() {
+ return nil, diags
+ }
+ compareGroups = append(compareGroups, *columnComparison)
+ }
+ comparison.CompareGroups = compareGroups
+ }
+
+ return comparison, diags
+}
+
+func newMonitorV2ComparisonInput(path string, data *schema.ResourceData) (comparison *gql.MonitorV2ComparisonInput, diags diag.Diagnostics) {
+ // required
+ compareFn := gql.MonitorV2ComparisonFunction(toCamel(data.Get(fmt.Sprintf("%scompare_fn", path)).(string)))
+ var compareValue gql.PrimitiveValueInput
+ diags = newMonitorV2PrimitiveValue(path, data, &compareValue)
+ if diags.HasError() {
+ return nil, diags
+ }
+
+ // instantiation
+ comparison = &gql.MonitorV2ComparisonInput{
+ CompareFn: compareFn,
+ CompareValue: compareValue,
+ }
+
+ return comparison, diags
+}
+
+func newMonitorV2ThresholdRuleInput(path string, data *schema.ResourceData) (threshold *gql.MonitorV2ThresholdRuleInput, diags diag.Diagnostics) {
+ // required
+ compareValues := []gql.MonitorV2ComparisonInput{}
+ for i := range data.Get(fmt.Sprintf("%scompare_values", path)).([]interface{}) {
+ comparisonInput, diags := newMonitorV2ComparisonInput(fmt.Sprintf("%scompare_values.%d.", path, i), data)
+ if diags.HasError() {
+ return threshold, diags
+ }
+ compareValues = append(compareValues, *comparisonInput)
+ }
+ valueColumnName := data.Get(fmt.Sprintf("%svalue_column_name", path)).(string)
+ aggregation := gql.MonitorV2ValueAggregation(toCamel(data.Get(fmt.Sprintf("%saggregation", path)).(string)))
+
+ // instantiation
+ threshold = &gql.MonitorV2ThresholdRuleInput{
+ CompareValues: compareValues,
+ ValueColumnName: valueColumnName,
+ Aggregation: aggregation,
+ }
+
+ return threshold, diags
+}
+
+func newMonitorV2PromoteRuleInput(prefix string, data *schema.ResourceData) (promoteRule *gql.MonitorV2PromoteRuleInput, diags diag.Diagnostics) {
+ // instantiation
+ promoteRule = &gql.MonitorV2PromoteRuleInput{}
+
+ // optionals
+ if _, ok := data.GetOk(fmt.Sprintf("%scompare_columns", prefix)); ok {
+ compareColumns := make([]gql.MonitorV2ColumnComparisonInput, 0)
+ for i := range data.Get(fmt.Sprintf("%scompare_columns", prefix)).([]interface{}) {
+ input, diags := newMonitorV2ColumnComparisonInput(fmt.Sprintf("%scompare_columns.%d.", prefix, i), data)
+ if diags.HasError() {
+ return nil, diags
+ }
+ compareColumns = append(compareColumns, *input)
+ }
+ promoteRule.CompareColumns = compareColumns
+ }
+
+ return promoteRule, diags
+}
+
+func newMonitorV2ColumnComparisonInput(path string, data *schema.ResourceData) (comparison *gql.MonitorV2ColumnComparisonInput, diags diag.Diagnostics) {
+ // required
+ compareValues := make([]gql.MonitorV2ComparisonInput, 0)
+ for i := range data.Get(fmt.Sprintf("%scompare_values", path)).([]interface{}) {
+ comparisonInput, diags := newMonitorV2ComparisonInput(fmt.Sprintf("%scompare_values.%d.", path, i), data)
+ if diags.HasError() {
+ return nil, diags
+ }
+ compareValues = append(compareValues, *comparisonInput)
+ }
+ columnInput, diags := newMonitorV2ColumnInput(fmt.Sprintf("%scolumn.0.", path), data)
+ if diags.HasError() {
+ return nil, diags
+ }
+
+ // instantiation
+ comparison = &gql.MonitorV2ColumnComparisonInput{
+ Column: *columnInput,
+ CompareValues: compareValues,
+ }
+
+ return comparison, diags
+}
+
+func newMonitorV2ColumnInput(path string, data *schema.ResourceData) (column *gql.MonitorV2ColumnInput, diags diag.Diagnostics) {
+ // instantiation
+ column = &gql.MonitorV2ColumnInput{}
+
+ // optional
+ if _, ok := data.GetOk(fmt.Sprintf("%slink_column", path)); ok {
+ linkColumn, diags := newMonitorV2LinkColumnInput(fmt.Sprintf("%slink_column.0.", path), data)
+ if diags.HasError() {
+ return nil, diags
+ }
+ column.LinkColumn = linkColumn
+ }
+
+ if _, ok := data.GetOk(fmt.Sprintf("%scolumn_path", path)); ok {
+ columnPath, diags := newMonitorV2ColumnPathInput(fmt.Sprintf("%scolumn_path.0.", path), data)
+ if diags.HasError() {
+ return nil, diags
+ }
+ column.ColumnPath = columnPath
+ }
+
+ return column, diags
+}
+
+func newMonitorV2LinkColumnInput(path string, data *schema.ResourceData) (column *gql.MonitorV2LinkColumnInput, diags diag.Diagnostics) {
+ // required
+ name := data.Get(fmt.Sprintf("%sname", path)).(string)
+
+ // instantiation
+ column = &gql.MonitorV2LinkColumnInput{Name: name}
+
+ // optionals
+ if _, ok := data.GetOk(fmt.Sprintf("%smeta", path)); ok {
+ meta, diags := newMonitorV2LinkColumnMetaInput(fmt.Sprintf("%smeta.0.", path), data)
+ if diags.HasError() {
+ return nil, diags
+ }
+ column.Meta = meta
+ }
+
+ return column, diags
+}
+
+func newMonitorV2LinkColumnMetaInput(path string, data *schema.ResourceData) (meta *gql.MonitorV2LinkColumnMetaInput, diags diag.Diagnostics) {
+ // instantiation
+ meta = &gql.MonitorV2LinkColumnMetaInput{}
+
+ // optionals
+ if _, ok := data.GetOk(fmt.Sprintf("%ssrc_fields", path)); ok {
+ srcFields := make([]gql.MonitorV2ColumnPathInput, 0)
+ for i := range data.Get(fmt.Sprintf("%ssrc_fields", path)).([]interface{}) {
+ srcField, diags := newMonitorV2ColumnPathInput(fmt.Sprintf("%ssrc_fields.%d.", path, i), data)
+ if diags.HasError() {
+ return nil, diags
+ }
+ srcFields = append(srcFields, *srcField)
+ }
+ meta.SrcFields = srcFields
+ }
+ if _, ok := data.GetOk(fmt.Sprintf("%sdst_fields", path)); ok {
+ dstFields := make([]string, 0)
+ for i := range data.Get(fmt.Sprintf("%sdst_fields", path)).([]interface{}) {
+ dstField := data.Get(fmt.Sprintf("%sdst_fields.%d", path, i)).(string)
+ dstFields = append(dstFields, dstField)
+ }
+ meta.DstFields = dstFields
+ }
+ if _, ok := data.GetOk(fmt.Sprintf("%starget_dataset", path)); ok {
+ v := data.Get(fmt.Sprintf("%starget_dataset", path))
+ meta.TargetDataset = types.Int64Scalar(v.(int64)).Ptr()
+ }
+
+ return meta, diags
+}
+
+func newMonitorV2ColumnPathInput(path string, data *schema.ResourceData) (column *gql.MonitorV2ColumnPathInput, diags diag.Diagnostics) {
+ // required
+ name := data.Get(fmt.Sprintf("%sname", path)).(string)
+
+ // instantiation
+ column = &gql.MonitorV2ColumnPathInput{Name: name}
+
+ // optionals
+ if v, ok := data.GetOk(fmt.Sprintf("%spath", path)); ok {
+ p := v.(string)
+ column.Path = &p
+ }
+
+ return column, diags
+}
+
+func newMonitorV2PrimitiveValue(path string, data *schema.ResourceData, ret *gql.PrimitiveValueInput) diag.Diagnostics {
+ valueBool, hasBool := data.GetOk(fmt.Sprintf("%svalue_bool", path))
+ valueInt, hasInt := data.GetOk(fmt.Sprintf("%svalue_int64", path))
+ valueFloat, hasFloat := data.GetOk(fmt.Sprintf("%svalue_float64", path))
+ valueString, hasString := data.GetOk(fmt.Sprintf("%svalue_string", path))
+ valueDuration, hasDuration := data.GetOk(fmt.Sprintf("%svalue_duration", path))
+ valueTimestamp, hasTimestamp := data.GetOk(fmt.Sprintf("%svalue_timestamp", path))
+
+ nvalue := 0
+ var kinds []string
+ if hasBool && valueBool != nil {
+ b := valueBool.([]interface{})[0].(bool)
+ ret.Bool = &b
+ nvalue++
+ kinds = append(kinds, "value_bool")
+ }
+ if hasInt && valueInt != nil {
+ i64 := types.Int64Scalar(valueInt.([]interface{})[0].(int))
+ ret.Int64 = &i64
+ nvalue++
+ kinds = append(kinds, "value_int64")
+ }
+ if hasFloat && valueFloat != nil {
+ vlt := valueFloat.([]interface{})[0].(float64)
+ ret.Float64 = &vlt
+ nvalue++
+ kinds = append(kinds, "value_float64")
+ }
+ if hasString && valueString != nil {
+ vstr := valueString.([]interface{})[0].(string)
+ ret.String = &vstr
+ nvalue++
+ kinds = append(kinds, "value_string")
+ }
+ if hasDuration && valueDuration != nil {
+ dur, _ := time.ParseDuration(valueDuration.([]interface{})[0].(string))
+ i64 := types.Int64Scalar(dur.Nanoseconds())
+ ret.Duration = &i64
+ nvalue++
+ kinds = append(kinds, "value_duration")
+ }
+ if hasTimestamp && valueTimestamp != nil {
+ tsp, _ := time.Parse(time.RFC3339, valueTimestamp.([]interface{})[0].(string))
+ tss := types.TimeScalar(tsp)
+ ret.Timestamp = &tss
+ nvalue++
+ kinds = append(kinds, "value_timestamp")
+ }
+ if nvalue == 0 {
+ return diag.Errorf("A value must be specified (value_string, value_bool, etc). Path = %s", path)
+ }
+ if nvalue > 1 {
+ return diag.Errorf("Only one value may be specified (value_string, value_bool, etc); there are %d: %s. Path = %s", len(kinds), strings.Join(kinds, ","), path)
+ }
+ return nil
+}
diff --git a/observe/resource_monitor_v2_test.go b/observe/resource_monitor_v2_test.go
new file mode 100644
index 00000000..124c625b
--- /dev/null
+++ b/observe/resource_monitor_v2_test.go
@@ -0,0 +1,199 @@
+package observe
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
+)
+
+// todo write some tests
+// starting point: count, threshold, ????????????
+
+var monitorV2ConfigPreamble = configPreamble + datastreamConfigPreamble
+
+func TestAccObserveMonitorV2Count(t *testing.T) {
+ randomPrefix := acctest.RandomWithPrefix("tf")
+
+ resource.ParallelTest(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ Providers: testAccProviders,
+ Steps: []resource.TestStep{
+ {
+ Config: fmt.Sprintf(monitorV2ConfigPreamble+`
+ resource "observe_monitor_v2" "first" {
+ workspace_id = data.observe_workspace.default.oid
+ rule_kind = "count"
+ name = "%[1]s"
+ lookback_time = "30m"
+ comment = "a descriptive comment"
+ inputs = {
+ "test" = observe_datastream.test.dataset
+ }
+ stage {
+ pipeline = <<-EOF
+ colmake kind:"test", description:"test"
+ EOF
+ output_stage = true
+ }
+ stage {
+ pipeline = <<-EOF
+ filter kind ~ "test"
+ EOF
+ }
+ rules {
+ level = "informational"
+ count {
+ compare_values {
+ compare_fn = "greater"
+ value_int64 = [0]
+ }
+ }
+ }
+ scheduling {
+ interval {
+ interval = "15m"
+ randomize = "0"
+ }
+ }
+ }
+ `, randomPrefix),
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttrSet("observe_monitor_v2.first", "workspace_id"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "name", randomPrefix),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "lookback_time", "30m0s"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "rule_kind", "count"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "comment", "a descriptive comment"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "rules.0.level", "informational"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "rules.0.count.0.compare_values.0.compare_fn", "greater"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "rules.0.count.0.compare_values.0.value_int64.0", "0"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "scheduling.0.interval.0.interval", "15m0s"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "scheduling.0.interval.0.randomize", "0s"),
+ ),
+ },
+ },
+ })
+}
+
+func TestAccObserveMonitorV2Threshold(t *testing.T) {
+ randomPrefix := acctest.RandomWithPrefix("tf")
+
+ resource.ParallelTest(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ Providers: testAccProviders,
+ Steps: []resource.TestStep{
+ {
+ Config: fmt.Sprintf(monitorV2ConfigPreamble+`
+ resource "observe_monitor_v2" "first" {
+ workspace_id = data.observe_workspace.default.oid
+ rule_kind = "threshold"
+ name = "%[1]s"
+ lookback_time = "30m"
+ comment = "a descriptive comment"
+ inputs = {
+ "test" = observe_datastream.test.dataset
+ }
+ stage {
+ pipeline = "colmake temp_number:14"
+ }
+ rules {
+ level = "informational"
+ threshold {
+ compare_values {
+ compare_fn = "greater"
+ value_int64 = [0]
+ }
+ value_column_name = "temp_number"
+ aggregation = "all_of"
+ }
+ }
+ scheduling {
+ interval {
+ interval = "15m"
+ randomize = "0"
+ }
+ }
+ }
+ `, randomPrefix),
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttrSet("observe_monitor_v2.first", "workspace_id"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "name", randomPrefix),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "lookback_time", "30m0s"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "rule_kind", "threshold"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "comment", "a descriptive comment"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "rules.0.level", "informational"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "rules.0.threshold.0.compare_values.0.compare_fn", "greater"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "rules.0.threshold.0.compare_values.0.value_int64.0", "0"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "rules.0.threshold.0.value_column_name", "temp_number"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "rules.0.threshold.0.aggregation", "all_of"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "scheduling.0.interval.0.interval", "15m0s"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "scheduling.0.interval.0.randomize", "0s"),
+ ),
+ },
+ },
+ })
+}
+
+func TestAccObserveMonitorV2Promote(t *testing.T) {
+ randomPrefix := acctest.RandomWithPrefix("tf")
+
+ resource.ParallelTest(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ Providers: testAccProviders,
+ Steps: []resource.TestStep{
+ {
+ Config: fmt.Sprintf(monitorV2ConfigPreamble+`
+ resource "observe_monitor_v2" "first" {
+ workspace_id = data.observe_workspace.default.oid
+ rule_kind = "promote"
+ name = "%[1]s"
+ lookback_time = "0s"
+ comment = "a descriptive comment"
+ inputs = {
+ "test" = observe_datastream.test.dataset
+ }
+ stage {
+ pipeline = "colmake temp_number:14"
+ }
+ rules {
+ level = "informational"
+ promote {
+ compare_columns {
+ compare_values {
+ compare_fn = "greater"
+ value_int64 = [1]
+ }
+ column {
+ column_path {
+ name = "temp_number"
+ }
+ }
+ }
+ }
+ }
+ scheduling {
+ interval {
+ interval = "15m"
+ randomize = "0"
+ }
+ }
+ }
+ `, randomPrefix),
+ Check: resource.ComposeTestCheckFunc(
+ resource.TestCheckResourceAttrSet("observe_monitor_v2.first", "workspace_id"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "name", randomPrefix),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "lookback_time", "0s"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "rule_kind", "promote"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "comment", "a descriptive comment"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "rules.0.level", "informational"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "rules.0.promote.0.compare_columns.0.compare_values.0.compare_fn", "greater"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "rules.0.promote.0.compare_columns.0.compare_values.0.value_int64.0", "1"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "rules.0.promote.0.compare_columns.0.column.0.column_path.0.name", "temp_number"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "scheduling.0.interval.0.interval", "15m0s"),
+ resource.TestCheckResourceAttr("observe_monitor_v2.first", "scheduling.0.interval.0.randomize", "0s"),
+ ),
+ },
+ },
+ })
+}