From 570f704e505cfce50d8f59629f110cf13066d1c4 Mon Sep 17 00:00:00 2001 From: Rajagopalan Subrahmanian Date: Tue, 17 Oct 2023 13:30:51 -0400 Subject: [PATCH] enable widget and dashboard creation --- apstra/iba/probe.go | 2 +- apstra/iba/widget.go | 66 +++++++ apstra/provider.go | 1 + apstra/resource_iba_probe.go | 4 +- apstra/resource_iba_probe_test.go | 56 ++++++ apstra/resource_iba_widget.go | 172 ++++++++++++++++++ apstra/resource_iba_widget_test.go | 78 ++++++++ docs/data-sources/iba_dashboard.md | 2 +- docs/data-sources/iba_dashboards.md | 2 +- docs/data-sources/iba_predefined_probe.md | 155 ++++++++++++++++ docs/data-sources/iba_predefined_probes.md | 63 +++++++ docs/data-sources/iba_widget.md | 2 + docs/resources/iba_probe.md | 80 ++++++++ docs/resources/iba_widget.md | 72 ++++++++ .../apstra_iba_dashboard/example.tf | 2 +- .../apstra_iba_dashboards/example.tf | 2 +- .../apstra_iba_predefined_probe/example.tf | 127 +++++++++++++ .../apstra_iba_predefined_probes/example.tf | 37 ++++ .../resources/apstra_iba_probe/example.tf | 50 +++++ .../resources/apstra_iba_widget/example.tf | 43 +++++ go.mod | 2 +- go.sum | 2 + 22 files changed, 1012 insertions(+), 8 deletions(-) create mode 100644 apstra/resource_iba_probe_test.go create mode 100644 apstra/resource_iba_widget.go create mode 100644 apstra/resource_iba_widget_test.go create mode 100644 docs/data-sources/iba_predefined_probe.md create mode 100644 docs/data-sources/iba_predefined_probes.md create mode 100644 docs/resources/iba_probe.md create mode 100644 docs/resources/iba_widget.md create mode 100644 examples/data-sources/apstra_iba_predefined_probe/example.tf create mode 100644 examples/data-sources/apstra_iba_predefined_probes/example.tf create mode 100644 examples/resources/apstra_iba_probe/example.tf create mode 100644 examples/resources/apstra_iba_widget/example.tf diff --git a/apstra/iba/probe.go b/apstra/iba/probe.go index 4285b782..8199a5c9 100644 --- a/apstra/iba/probe.go +++ b/apstra/iba/probe.go @@ -27,7 +27,7 @@ type IbaProbe struct { func (o IbaProbe) ResourceAttributes() map[string]resourceSchema.Attribute { return map[string]resourceSchema.Attribute{ "blueprint_id": resourceSchema.StringAttribute{ - MarkdownDescription: "Apstra Blueprint ID. Used to identify the Blueprint that the IBA Widget belongs to.", + MarkdownDescription: "Apstra Blueprint ID. Used to identify the Blueprint that the IBA Probe belongs to.", Required: true, Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, }, diff --git a/apstra/iba/widget.go b/apstra/iba/widget.go index 414d45ba..24c56b1d 100644 --- a/apstra/iba/widget.go +++ b/apstra/iba/widget.go @@ -7,6 +7,9 @@ import ( dataSourceSchema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" + resourceSchema "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" ) @@ -16,6 +19,8 @@ type IbaWidget struct { Id types.String `tfsdk:"id"` Name types.String `tfsdk:"name"` Description types.String `tfsdk:"description"` + Stage types.String `tfsdk:"stage"` + ProbeId types.String `tfsdk:"probe_id"` } func (o IbaWidget) DataSourceAttributes() map[string]dataSourceSchema.Attribute { @@ -49,6 +54,54 @@ func (o IbaWidget) DataSourceAttributes() map[string]dataSourceSchema.Attribute MarkdownDescription: "Description of the IBA Widget", Computed: true, }, + "stage": dataSourceSchema.StringAttribute{ + MarkdownDescription: "Stage of IBA Probe used by this widget", + Computed: true, + }, + "probe_id": dataSourceSchema.StringAttribute{ + MarkdownDescription: "Id of IBA Probe used by this widget", + Computed: true, + }, + } +} + +func (o IbaWidget) ResourceAttributes() map[string]resourceSchema.Attribute { + return map[string]resourceSchema.Attribute{ + "blueprint_id": resourceSchema.StringAttribute{ + MarkdownDescription: "ID of the Apstra Blueprint where the IBA Widget will be created", + Required: true, + Validators: []validator.String{stringvalidator.LengthAtLeast(1)}, + }, + "id": resourceSchema.StringAttribute{ + MarkdownDescription: "IBA Widget ID", + Computed: true, + PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, + }, + "name": resourceSchema.StringAttribute{ + MarkdownDescription: "IBA Widget Name", + Required: true, + Validators: []validator.String{ + stringvalidator.LengthAtLeast(1), + }, + }, + "description": resourceSchema.StringAttribute{ + MarkdownDescription: "IBA Widget Description", + Required: true, + }, + "probe_id": dataSourceSchema.StringAttribute{ + MarkdownDescription: "Id of IBA Probe used by this widget", + Required: true, + Validators: []validator.String{ + stringvalidator.LengthAtLeast(1), + }, + }, + "stage": resourceSchema.StringAttribute{ + MarkdownDescription: "Stage of IBA Probe used by this widget", + Required: true, + Validators: []validator.String{ + stringvalidator.LengthAtLeast(1), + }, + }, } } @@ -56,4 +109,17 @@ func (o *IbaWidget) LoadApiData(_ context.Context, in *apstra.IbaWidget, _ *diag o.Id = types.StringValue(in.Id.String()) o.Name = types.StringValue(in.Data.Label) o.Description = types.StringValue(in.Data.Description) + o.Stage = types.StringValue(in.Data.StageName) + o.ProbeId = types.StringValue(in.Data.ProbeId.String()) +} + +func (o *IbaWidget) Request(ctx context.Context, d *diag.Diagnostics) *apstra.IbaWidgetData { + + return &apstra.IbaWidgetData{ + StageName: o.Stage.ValueString(), + Description: o.Description.ValueString(), + ProbeId: apstra.ObjectId(o.ProbeId.ValueString()), + Label: o.Name.ValueString(), + Type: apstra.IbaWidgetTypeStage, + } } diff --git a/apstra/provider.go b/apstra/provider.go index 38f22af7..1be57ca5 100644 --- a/apstra/provider.go +++ b/apstra/provider.go @@ -482,6 +482,7 @@ func (p *Provider) Resources(_ context.Context) []func() resource.Resource { func() resource.Resource { return &resourceDeviceAllocation{} }, func() resource.Resource { return &resourceIbaDashboard{} }, func() resource.Resource { return &resourceIbaProbe{} }, + func() resource.Resource { return &resourceIbaWidget{} }, func() resource.Resource { return &resourceIntegerPool{} }, func() resource.Resource { return &resourceInterfaceMap{} }, func() resource.Resource { return &resourceIpv4Pool{} }, diff --git a/apstra/resource_iba_probe.go b/apstra/resource_iba_probe.go index b6a037bd..46f35acb 100644 --- a/apstra/resource_iba_probe.go +++ b/apstra/resource_iba_probe.go @@ -172,13 +172,13 @@ func (o *resourceIbaProbe) Delete(ctx context.Context, req resource.DeleteReques return } - // Delete IBA Dashboard by calling API + // Delete IBA Probe by calling API err = bpClient.DeleteIbaProbe(ctx, apstra.ObjectId(state.Id.ValueString())) if err != nil { if utils.IsApstra404(err) { return // 404 is okay } - // resp.Diagnostics.AddError("error deleting IBA Dashboard", err.Error()) + resp.Diagnostics.AddError("error deleting IBA Probe", err.Error()) return } } diff --git a/apstra/resource_iba_probe_test.go b/apstra/resource_iba_probe_test.go new file mode 100644 index 00000000..ada975ec --- /dev/null +++ b/apstra/resource_iba_probe_test.go @@ -0,0 +1,56 @@ +package tfapstra + +import ( + "context" + "errors" + "fmt" + testutils "github.com/Juniper/terraform-provider-apstra/apstra/test_utils" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "testing" +) + +const ( + resourceIbaProbeHCL = ` +resource "apstra_iba_probe" "p_device_health" { + blueprint_id = "%s" + predefined_probe_id = "device_health" + probe_config = jsonencode( + { + "max_cpu_utilization": 80, + "max_memory_utilization": 80, + "max_disk_utilization": 80, + "duration": 660, + "threshold_duration": 360, + "history_duration": 604800 + } + ) +} +` +) + +func TestAccResourceProbe(t *testing.T) { + ctx := context.Background() + bpClient, bpDelete, err := testutils.MakeOrFindBlueprint(ctx, "1bb57", testutils.BlueprintA) + if err != nil { + t.Fatal(errors.Join(err, bpDelete(ctx))) + } + defer func() { + err = bpDelete(ctx) + if err != nil { + t.Error(err) + } + }() + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create and Read testing + { + Config: insecureProviderConfigHCL + fmt.Sprintf(resourceIbaProbeHCL, bpClient.Id()), + Check: resource.ComposeAggregateTestCheckFunc( + // Verify ID has any value set + resource.TestCheckResourceAttrSet("apstra_iba_probe.p_device_health", "id"), resource.TestCheckResourceAttr("apstra_iba_probe.p_device_health", "name", "Device System Health")), + }, + }, + }) +} diff --git a/apstra/resource_iba_widget.go b/apstra/resource_iba_widget.go new file mode 100644 index 00000000..32b5480d --- /dev/null +++ b/apstra/resource_iba_widget.go @@ -0,0 +1,172 @@ +package tfapstra + +import ( + "context" + "fmt" + "github.com/Juniper/apstra-go-sdk/apstra" + "github.com/Juniper/terraform-provider-apstra/apstra/iba" + "github.com/Juniper/terraform-provider-apstra/apstra/utils" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +var _ resource.ResourceWithConfigure = &resourceIbaWidget{} + +type resourceIbaWidget struct { + client *apstra.Client +} + +func (o *resourceIbaWidget) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_iba_widget" +} + +func (o *resourceIbaWidget) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + o.client = ResourceGetClient(ctx, req, resp) +} + +func (o *resourceIbaWidget) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + MarkdownDescription: "This resource creates a IBA Widget.", + Attributes: iba.IbaWidget{}.ResourceAttributes(), + } +} + +func (o *resourceIbaWidget) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + // Retrieve values from plan + var plan iba.IbaWidget + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + // create a blueprint client + bpClient, err := o.client.NewTwoStageL3ClosClient(ctx, apstra.ObjectId(plan.BlueprintId.ValueString())) + if err != nil { + resp.Diagnostics.AddError("failed to create blueprint client", err.Error()) + return + } + + // Convert the plan into an API Request + probeReq := plan.Request(ctx, &resp.Diagnostics) + if resp.Diagnostics.HasError() { + return + } + + id, err := bpClient.CreateIbaWidget(ctx, probeReq) + if err != nil { + resp.Diagnostics.AddError("failed to create Iba Probe", err.Error()) + return + } + plan.Id = types.StringValue(id.String()) + + // Set state + resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) +} + +func (o *resourceIbaWidget) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var state iba.IbaWidget + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + bpClient, err := o.client.NewTwoStageL3ClosClient(ctx, apstra.ObjectId(state.BlueprintId.ValueString())) + if err != nil { + if utils.IsApstra404(err) { + resp.State.RemoveResource(ctx) + return + } + resp.Diagnostics.AddError("failed to create blueprint client", err.Error()) + return + } + + api, err := bpClient.GetIbaWidget(ctx, apstra.ObjectId(state.Id.ValueString())) + if err != nil { + if utils.IsApstra404(err) { + resp.State.RemoveResource(ctx) + return + } + resp.Diagnostics.AddError("Failed to Read IBA Dashboard", err.Error()) + return + } + + // create new state object + state.LoadApiData(ctx, api, &resp.Diagnostics) + if resp.Diagnostics.HasError() { + return + } + + // set state + resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) +} + +// Update resource +func (o *resourceIbaWidget) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + // Get plan values + var plan iba.IbaWidget + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + widgetReq := plan.Request(ctx, &resp.Diagnostics) + if resp.Diagnostics.HasError() { + return + } + + bpClient, err := o.client.NewTwoStageL3ClosClient(ctx, apstra.ObjectId(plan.BlueprintId.ValueString())) + if err != nil { + resp.Diagnostics.AddError("failed to create blueprint client", err.Error()) + return + } + + // Update IBA Widget + err = bpClient.UpdateIbaWidget(ctx, apstra.ObjectId(plan.Id.ValueString()), widgetReq) + if err != nil { + resp.Diagnostics.AddError("plan", fmt.Sprintf("%q", plan)) + resp.Diagnostics.AddError("error updating IBA Dashboard plan", err.Error()) + return + } + + api, err := bpClient.GetIbaWidget(ctx, apstra.ObjectId(plan.Id.ValueString())) + if err != nil { + resp.Diagnostics.AddError("Failed to Read IBA Dashboard", err.Error()) + return + } + plan.LoadApiData(ctx, api, &resp.Diagnostics) + if resp.Diagnostics.HasError() { + return + } + + // Set state + resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) +} + +// Delete resource +func (o *resourceIbaWidget) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var state iba.IbaWidget + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + bpClient, err := o.client.NewTwoStageL3ClosClient(ctx, apstra.ObjectId(state.BlueprintId.ValueString())) + if err != nil { + if utils.IsApstra404(err) { + return // 404 is okay + } + resp.Diagnostics.AddError("failed to create blueprint client", err.Error()) + return + } + + // Delete IBA Probe by calling API + err = bpClient.DeleteIbaWidget(ctx, apstra.ObjectId(state.Id.ValueString())) + if err != nil { + if utils.IsApstra404(err) { + return // 404 is okay + } + resp.Diagnostics.AddError("error deleting IBA Probe", err.Error()) + return + } +} diff --git a/apstra/resource_iba_widget_test.go b/apstra/resource_iba_widget_test.go new file mode 100644 index 00000000..88b431ea --- /dev/null +++ b/apstra/resource_iba_widget_test.go @@ -0,0 +1,78 @@ +package tfapstra + +import ( + "context" + "errors" + "fmt" + testutils "github.com/Juniper/terraform-provider-apstra/apstra/test_utils" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "testing" +) + +const ( + resourceIbaWidgetHCL = ` +resource "apstra_iba_probe" "p_device_health" { + blueprint_id = "%s" + predefined_probe_id = "device_health" + probe_config = jsonencode( + { + "max_cpu_utilization": 80, + "max_memory_utilization": 80, + "max_disk_utilization": 80, + "duration": 660, + "threshold_duration": 360, + "history_duration": 604800 + } + ) +} +resource "apstra_iba_widget" "w_device_health_high_cpu" { + blueprint_id = "%s" + name = "%s" + probe_id = apstra_iba_probe.p_device_health.id + stage = "Systems with high CPU utilization" + description = "made from terraform" +} +` +) + +func TestAccResourceWidget(t *testing.T) { + ctx := context.Background() + bpClient, bpDelete, err := testutils.MakeOrFindBlueprint(ctx, "1bb57", testutils.BlueprintA) + if err != nil { + t.Fatal(errors.Join(err, bpDelete(ctx))) + } + defer func() { + err = bpDelete(ctx) + if err != nil { + t.Error(err) + } + }() + + n1 := "Widget1" + n2 := "Widget2" + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create and Read testing + { + Config: insecureProviderConfigHCL + fmt.Sprintf(resourceIbaWidgetHCL, bpClient.Id(), bpClient.Id(), n1), + Check: resource.ComposeAggregateTestCheckFunc( + // Verify ID has any value set + resource.TestCheckResourceAttrSet("apstra_iba_widget.w_device_health_high_cpu", "id"), + // Check the name + resource.TestCheckResourceAttr("apstra_iba_widget.w_device_health_high_cpu", "name", n1), + ), + }, + // Update and Read testing + { + Config: insecureProviderConfigHCL + fmt.Sprintf(resourceIbaWidgetHCL, bpClient.Id(), bpClient.Id(), n2), + Check: resource.ComposeAggregateTestCheckFunc( + // Verify ID has any value set + resource.TestCheckResourceAttrSet("apstra_iba_widget.w_device_health_high_cpu", "id"), + // Check the name + resource.TestCheckResourceAttr("apstra_iba_widget.w_device_health_high_cpu", "name", n2), + ), + }, + }, + }) +} diff --git a/docs/data-sources/iba_dashboard.md b/docs/data-sources/iba_dashboard.md index 14634ce5..db8451f0 100644 --- a/docs/data-sources/iba_dashboard.md +++ b/docs/data-sources/iba_dashboard.md @@ -15,7 +15,7 @@ At least one optional attribute is required. ## Example Usage ```terraform -# This example pulls one iba widget from a blueprint +# This example pulls one iba dashboards from a blueprint data "apstra_datacenter_blueprint" "b" { name = "test" diff --git a/docs/data-sources/iba_dashboards.md b/docs/data-sources/iba_dashboards.md index e53d63ba..dd6839aa 100644 --- a/docs/data-sources/iba_dashboards.md +++ b/docs/data-sources/iba_dashboards.md @@ -12,7 +12,7 @@ This data source returns the ID numbers of all IBA Dashboards in a Blueprint. ## Example Usage ```terraform -# This example pulls one iba widget from a blueprint +# This example pulls all the iba dashboards from a blueprint data "apstra_datacenter_blueprint" "b" { name = "test" diff --git a/docs/data-sources/iba_predefined_probe.md b/docs/data-sources/iba_predefined_probe.md new file mode 100644 index 00000000..f7b2ec3b --- /dev/null +++ b/docs/data-sources/iba_predefined_probe.md @@ -0,0 +1,155 @@ +--- +page_title: "apstra_iba_predefined_probe Data Source - terraform-provider-apstra" +subcategory: "" +description: |- + This data source provides details of a specific IBA Predefined Probe in a Blueprint. +--- + +# apstra_iba_predefined_probe (Data Source) + +This data source provides details of a specific IBA Predefined Probe in a Blueprint. + +## Example Usage + +```terraform +# This example pulls all the predefined iba probes from a blueprint + +data "apstra_datacenter_blueprint" "b" { + name = "test" +} + +data "apstra_iba_predefined_probes" "all" { + blueprint_id = data.apstra_datacenter_blueprint.b.id +} + + +data "apstra_iba_predefined_probe" "all" { + for_each = data.apstra_iba_predefined_probes.all.names + blueprint_id = data.apstra_datacenter_blueprint.b.id + name = each.key +} + +output "o2" { + value = data.apstra_iba_predefined_probe.all +} + +# Output looks something like this +#o2 = { +#"spine_superspine_interface_flapping" = { +# "blueprint_id" = "c151d0c1-fda1-495b-86e8-92d2499ac6f8" +# "description" = <<-EOT +# Generate a probe to determine if spine to superspine +# interfaces are flapping. +# +# A given interface is considered to be flapping if it transitions state +# more than "Threshold" times over the last "Duration". Such +# flapping will cause an anomaly to be raised. +# +# If more-than "Max Flapping Interfaces Percentage" percent of +# interfaces on a given device are flapping, an anomaly will +# be raised for that device. +# +# Finally, the last "Anomaly History Count" anomaly state-changes +# are stored for observation. +# +# EOT +# "name" = "spine_superspine_interface_flapping" +# "schema" = "{\"type\": \"object\", \"properties\": {\"label\": {\"title\": \"Probe Label\", \"type\": \"string\", \"minLength\": 1, \"maxLength\": 120, \"default\": \"Interface Flapping (Spine to Superspine Interfaces)\"}, \"threshold\": {\"title\": \"Threshold\", \"description\": \"Sum total of number of flaps in recent-history for which an anomaly will be raised. The larger the value, the more memory the probe will consume.\", \"type\": \"integer\", \"minimum\": 1, \"default\": 5}, \"max_flapping_interfaces_percentage\": {\"title\": \"Max Flapping Interfaces Percentage\", \"description\": \"Maximum percentage of flapping interfaces on a device\", \"type\": \"integer\", \"minimum\": 0, \"maximum\": 100, \"default\": 10}, \"duration\": {\"title\": \"Duration\", \"description\": \"Duration of recent-history in which interface flapping will be considered. The longer the period, the more memory the probe will consume.\", \"type\": \"integer\", \"minimum\": 1, \"default\": 60}}}" +#} +#"traffic" = { +# "blueprint_id" = "c151d0c1-fda1-495b-86e8-92d2499ac6f8" +# "description" = <<-EOT +# +# This probe displays the all the interface counters available for the +# system, their utilizations and utilizations aggregated on a per system +# basis. +# +# EOT +# "name" = "traffic" +# "schema" = "{\"type\": \"object\", \"properties\": {\"label\": {\"title\": \"Probe Label\", \"type\": \"string\", \"minLength\": 1, \"maxLength\": 120, \"default\": \"Device Traffic\"}, \"interface_counters_average_period\": {\"title\": \"Interface counters average period\", \"description\": \"The average period duration for interface counters\", \"type\": \"integer\", \"minimum\": 1, \"default\": 120}, \"enable_interface_counters_history\": {\"title\": \"Enable interface counters history\", \"description\": \"Maintain historical interface counters data\", \"type\": \"boolean\", \"default\": true}, \"interface_counters_history_retention_period\": {\"title\": \"Interface counters history retention period\", \"description\": \"Duration to maintain historical interface counters data\", \"type\": \"integer\", \"minimum\": 1, \"default\": 2592000}, \"enable_system_counters_history\": {\"title\": \"Enable system counters history\", \"description\": \"Maintain historical system interface counters data\", \"type\": \"boolean\", \"default\": true}, \"system_counters_history_retention_period\": {\"title\": \"System interface counters history retention period\", \"description\": \"Duration to maintain historical system interface counters data\", \"type\": \"integer\", \"minimum\": 1, \"default\": 2592000}}}" +#}, +#"virtual_infra_hypervisor_redundancy_checks" = { +# "blueprint_id" = "c151d0c1-fda1-495b-86e8-92d2499ac6f8" +# "description" = <<-EOT +# Generate a probe to detect hypervisor redundancy. +# +# EOT +# "name" = "virtual_infra_hypervisor_redundancy_checks" +# "schema" = "{\"type\": \"object\", \"properties\": {\"label\": {\"title\": \"Probe Label\", \"type\": \"string\", \"minLength\": 1, \"maxLength\": 120, \"default\": \"Hypervisor Redundancy Checks\"}}}" +#}, +#"virtual_infra_lag_match" = { +# "blueprint_id" = "c151d0c1-fda1-495b-86e8-92d2499ac6f8" +# "description" = <<-EOT +# Generate a probe to detect inconsistent LAG configs between +# fabric and virtual infra. +# +# This probe calculates LAGs missing on hypervisors and AOS managed systems +# connected to hypervisors. +# +# EOT +# "name" = "virtual_infra_lag_match" +# "schema" = "{\"type\": \"object\", \"properties\": {\"label\": {\"title\": \"Probe Label\", \"type\": \"string\", \"minLength\": 1, \"maxLength\": 120, \"default\": \"Hypervisor & Fabric LAG Config Mismatch\"}}}" +#}, +#"virtual_infra_missing_lldp" = { +# "blueprint_id" = "c151d0c1-fda1-495b-86e8-92d2499ac6f8" +# "description" = <<-EOT +# Generate a probe to detect virtual infra hosts that are not +# configured for LLDP. +# +# EOT +# "name" = "virtual_infra_missing_lldp" +# "schema" = "{\"type\": \"object\", \"properties\": {\"label\": {\"title\": \"Probe Label\", \"type\": \"string\", \"minLength\": 1, \"maxLength\": 120, \"default\": \"Hypervisor Missing LLDP Config\"}}}" +#}, +#"virtual_infra_vlan_match" = { +# "blueprint_id" = "c151d0c1-fda1-495b-86e8-92d2499ac6f8" +# "description" = <<-EOT +# Generate a probe to calculate missing VLANs +# +# This probe calculates VLAN(s) mismatch between AOS configured +# virtual networks on the systems and the VLANs needed by the VMs running +# on the hypervisors attached to the systems. +# +# EOT +# "name" = "virtual_infra_vlan_match" +# "schema" = "{\"type\": \"object\", \"properties\": {\"label\": {\"title\": \"Probe Label\", \"type\": \"string\", \"minLength\": 1, \"maxLength\": 120, \"default\": \"Hypervisor & Fabric VLAN Config Mismatch\"}}}" +#}, +#"vxlan_floodlist" = { +# "blueprint_id" = "c151d0c1-fda1-495b-86e8-92d2499ac6f8" +# "description" = <<-EOT +# +# This probe validates the VXLAN flood list entries on every leaf +# in the network. It collects appropriate telemetry data, +# compares it to the set of flood list forwarding entries +# expected to be present and alerts if expected entries are missing +# on any device. +# +# Route Labels +# +# Expected: This route is expected on the device as per service +# defined. +# +# Missing: This route is missing on the device when compared to +# the expected route set. +# +# Unexpected: There are no expectations rendered (by AOS) for this +# route. +# +# EOT +# "name" = "vxlan_floodlist" +# "schema" = "{\"type\": \"object\", \"properties\": {\"label\": {\"title\": \"Probe Label\", \"type\": \"string\", \"minLength\": 1, \"maxLength\": 120, \"default\": \"VXLAN Flood List Validation\"}, \"duration\": {\"title\": \"Anomaly Time Window\", \"type\": \"integer\", \"minimum\": 1, \"default\": 360}, \"threshold\": {\"title\": \"Anomaly Threshold (in %)\", \"description\": \"If routes are missing for more than or equal to percentage of Anomaly Time Window, an anomaly will be raised.\", \"type\": \"integer\", \"minimum\": 0, \"maximum\": 100, \"default\": 100}, \"collection_period\": {\"title\": \"Collection period\", \"description\": \"Telemetry collection interval.\", \"type\": \"number\", \"minimum\": 0, \"default\": 300.0}}}" +#} +#} +``` + + +## Schema + +### Required + +- `blueprint_id` (String) Apstra Blueprint ID. Used to identify the Blueprint that the IBA Predefined Probe belongs to. +- `name` (String) Populate this field to look up a IBA Predefined Probe. + +### Read-Only + +- `description` (String) Description of the IBA Predefined Probe +- `schema` (String) Schema of the IBA Predefined Probe's parameters diff --git a/docs/data-sources/iba_predefined_probes.md b/docs/data-sources/iba_predefined_probes.md new file mode 100644 index 00000000..4e0a5c8b --- /dev/null +++ b/docs/data-sources/iba_predefined_probes.md @@ -0,0 +1,63 @@ +--- +page_title: "apstra_iba_predefined_probes Data Source - terraform-provider-apstra" +subcategory: "" +description: |- + This data source returns the IDs of the IBA Predefined Probes in a Blueprint. +--- + +# apstra_iba_predefined_probes (Data Source) + +This data source returns the IDs of the IBA Predefined Probes in a Blueprint. + +## Example Usage + +```terraform +# This example pulls one predefined iba probe from a blueprint + +data "apstra_datacenter_blueprint" "b" { + name = "test" +} + +data "apstra_iba_predefined_probe" "p1" { + blueprint_id = data.apstra_datacenter_blueprint.b.id + name = "spine_superspine_interface_flapping" +} + +output "o3" { + value = data.apstra_iba_predefined_probe.p1 +} + + +#o3 = { +# "blueprint_id" = "c151d0c1-fda1-495b-86e8-92d2499ac6f8" +# "description" = <<-EOT +# Generate a probe to determine if spine to superspine +# interfaces are flapping. +# +# A given interface is considered to be flapping if it transitions state +# more than "Threshold" times over the last "Duration". Such +# flapping will cause an anomaly to be raised. +# +# If more-than "Max Flapping Interfaces Percentage" percent of +# interfaces on a given device are flapping, an anomaly will +# be raised for that device. +# +# Finally, the last "Anomaly History Count" anomaly state-changes +# are stored for observation. +# +# EOT +# "name" = "spine_superspine_interface_flapping" +# "schema" = "{\"type\": \"object\", \"properties\": {\"label\": {\"title\": \"Probe Label\", \"type\": \"string\", \"minLength\": 1, \"maxLength\": 120, \"default\": \"Interface Flapping (Spine to Superspine Interfaces)\"}, \"threshold\": {\"title\": \"Threshold\", \"description\": \"Sum total of number of flaps in recent-history for which an anomaly will be raised. The larger the value, the more memory the probe will consume.\", \"type\": \"integer\", \"minimum\": 1, \"default\": 5}, \"max_flapping_interfaces_percentage\": {\"title\": \"Max Flapping Interfaces Percentage\", \"description\": \"Maximum percentage of flapping interfaces on a device\", \"type\": \"integer\", \"minimum\": 0, \"maximum\": 100, \"default\": 10}, \"duration\": {\"title\": \"Duration\", \"description\": \"Duration of recent-history in which interface flapping will be considered. The longer the period, the more memory the probe will consume.\", \"type\": \"integer\", \"minimum\": 1, \"default\": 60}}}" +#} +``` + + +## Schema + +### Required + +- `blueprint_id` (String) Apstra Blueprint ID. Used to identify the Blueprint that the IBA Predefined Probes belongs to. + +### Read-Only + +- `names` (Set of String) A set of names representing the IBA Predefined Probes in the blueprint. diff --git a/docs/data-sources/iba_widget.md b/docs/data-sources/iba_widget.md index b5af8ebe..246997ac 100644 --- a/docs/data-sources/iba_widget.md +++ b/docs/data-sources/iba_widget.md @@ -53,3 +53,5 @@ output "o" { ### Read-Only - `description` (String) Description of the IBA Widget +- `probe_id` (String) Id of IBA Probe used by this widget +- `stage` (String) Stage of IBA Probe used by this widget diff --git a/docs/resources/iba_probe.md b/docs/resources/iba_probe.md new file mode 100644 index 00000000..a7109164 --- /dev/null +++ b/docs/resources/iba_probe.md @@ -0,0 +1,80 @@ +--- +page_title: "apstra_iba_probe Resource - terraform-provider-apstra" +subcategory: "" +description: |- + This resource creates a IBA Dashboard. +--- + +# apstra_iba_probe (Resource) + +This resource creates a IBA Dashboard. + +## Example Usage + +```terraform +# The following example instantiates predefined probes in Apstra + +data "apstra_datacenter_blueprint" "b" { + name = "test" +} + +resource "apstra_iba_probe" "p_device_health" { + blueprint_id = data.apstra_datacenter_blueprint.b.id + predefined_probe_id = "device_health" + probe_config = jsonencode( + { + "max_cpu_utilization": 80, + "max_memory_utilization": 80, + "max_disk_utilization": 80, + "duration": 660, + "threshold_duration": 360, + "history_duration": 604800 + } + ) +} + +output "o"{ + value = apstra_iba_probe.p_device_health +} + +#Output Looks somethng like this +#o = { +#"blueprint_id" = "c151d0c1-fda1-495b-86e8-92d2499ac6f8" +#"description" = "This probe alerts if the system health parameters (CPU, memory and disk usage) exceed their specified thresholds for the specified duration." +#"id" = "0b738068-11dc-4050-aa7c-65cd8715cc6e" +#"name" = "Device System Health" +#"predefined_probe_id" = "device_health" +#"probe_config" = "{\"duration\":660,\"history_duration\":604800,\"max_cpu_utilization\":80,\"max_disk_utilization\":80,\"max_memory_utilization\":80,\"threshold_duration\":360}" +#"stages" = toset([ +#"Check cpu utilization threshold", +#"Check disk utilization threshold", +#"Check memory utilization threshold", +#"Disk utilization data", +#"Disk utilization data per partition", +#"System cpu utilization data", +#"System memory utilization data", +#"Systems with high CPU utilization", +#"Systems with high disk utilization", +#"Systems with high memory utilization", +#"sustained_high_cpu_utilization", +#"sustained_high_disk_utilization", +#"sustained_high_memory_utilization", +#]) +#} +``` + + +## Schema + +### Required + +- `blueprint_id` (String) Apstra Blueprint ID. Used to identify the Blueprint that the IBA Probe belongs to. +- `predefined_probe_id` (String) Id of predefined IBA Probe +- `probe_config` (String) Configuration elements for the IBA Probe + +### Read-Only + +- `description` (String) Description of the IBA Probe +- `id` (String) IBA Probe ID. +- `name` (String) IBA Probe Name. +- `stages` (Set of String) Description of the IBA Probe diff --git a/docs/resources/iba_widget.md b/docs/resources/iba_widget.md new file mode 100644 index 00000000..754a31ed --- /dev/null +++ b/docs/resources/iba_widget.md @@ -0,0 +1,72 @@ +--- +page_title: "apstra_iba_widget Resource - terraform-provider-apstra" +subcategory: "" +description: |- + This resource creates a IBA Widget. +--- + +# apstra_iba_widget (Resource) + +This resource creates a IBA Widget. + +## Example Usage + +```terraform +# The following example instantiates a predefined probe and initiates a widget in Apstra + +data "apstra_datacenter_blueprint" "b" { + name = "test" +} + +resource "apstra_iba_probe" "p_device_health" { + blueprint_id = data.apstra_datacenter_blueprint.b.id + predefined_probe_id = "device_health" + probe_config = jsonencode( + { + "max_cpu_utilization": 80, + "max_memory_utilization": 80, + "max_disk_utilization": 80, + "duration": 660, + "threshold_duration": 360, + "history_duration": 604800 + } + ) +} + +resource "apstra_iba_widget" "w_device_health_high_cpu" { + blueprint_id = data.apstra_datacenter_blueprint.b.id + name = "Devices with high CPU Utilization" + probe_id = apstra_iba_probe.p_device_health.id + stage = "Systems with high CPU utilization" + description = "made from terraform" +} + +output "o"{ + value = apstra_iba_widget.w_device_health_high_cpu +} + +# Output looks something like this +#o = { +# "blueprint_id" = "c151d0c1-fda1-495b-86e8-92d2499ac6f8" +# "description" = "made from terraform" +# "id" = "39613d7f-a5be-4359-bbd8-497c56894153" +# "name" = "Devices with high CPU Utilization" +# "probe_id" = "0b738068-11dc-4050-aa7c-65cd8715cc6e" +# "stage" = "Systems with high CPU utilization" +#} +``` + + +## Schema + +### Required + +- `blueprint_id` (String) ID of the Apstra Blueprint where the IBA Widget will be created +- `description` (String) IBA Widget Description +- `name` (String) IBA Widget Name +- `probe_id` (String) Id of IBA Probe used by this widget +- `stage` (String) Stage of IBA Probe used by this widget + +### Read-Only + +- `id` (String) IBA Widget ID diff --git a/examples/data-sources/apstra_iba_dashboard/example.tf b/examples/data-sources/apstra_iba_dashboard/example.tf index 7d9eb80f..11f67d5b 100644 --- a/examples/data-sources/apstra_iba_dashboard/example.tf +++ b/examples/data-sources/apstra_iba_dashboard/example.tf @@ -1,4 +1,4 @@ -# This example pulls one iba widget from a blueprint +# This example pulls one iba dashboards from a blueprint data "apstra_datacenter_blueprint" "b" { name = "test" diff --git a/examples/data-sources/apstra_iba_dashboards/example.tf b/examples/data-sources/apstra_iba_dashboards/example.tf index 7e6491bd..2be7e92e 100644 --- a/examples/data-sources/apstra_iba_dashboards/example.tf +++ b/examples/data-sources/apstra_iba_dashboards/example.tf @@ -1,4 +1,4 @@ -# This example pulls one iba widget from a blueprint +# This example pulls all the iba dashboards from a blueprint data "apstra_datacenter_blueprint" "b" { name = "test" diff --git a/examples/data-sources/apstra_iba_predefined_probe/example.tf b/examples/data-sources/apstra_iba_predefined_probe/example.tf new file mode 100644 index 00000000..b3b8fa22 --- /dev/null +++ b/examples/data-sources/apstra_iba_predefined_probe/example.tf @@ -0,0 +1,127 @@ +# This example pulls all the predefined iba probes from a blueprint + +data "apstra_datacenter_blueprint" "b" { + name = "test" +} + +data "apstra_iba_predefined_probes" "all" { + blueprint_id = data.apstra_datacenter_blueprint.b.id +} + + +data "apstra_iba_predefined_probe" "all" { + for_each = data.apstra_iba_predefined_probes.all.names + blueprint_id = data.apstra_datacenter_blueprint.b.id + name = each.key +} + +output "o2" { + value = data.apstra_iba_predefined_probe.all +} + +# Output looks something like this +#o2 = { +#"spine_superspine_interface_flapping" = { +# "blueprint_id" = "c151d0c1-fda1-495b-86e8-92d2499ac6f8" +# "description" = <<-EOT +# Generate a probe to determine if spine to superspine +# interfaces are flapping. +# +# A given interface is considered to be flapping if it transitions state +# more than "Threshold" times over the last "Duration". Such +# flapping will cause an anomaly to be raised. +# +# If more-than "Max Flapping Interfaces Percentage" percent of +# interfaces on a given device are flapping, an anomaly will +# be raised for that device. +# +# Finally, the last "Anomaly History Count" anomaly state-changes +# are stored for observation. +# +# EOT +# "name" = "spine_superspine_interface_flapping" +# "schema" = "{\"type\": \"object\", \"properties\": {\"label\": {\"title\": \"Probe Label\", \"type\": \"string\", \"minLength\": 1, \"maxLength\": 120, \"default\": \"Interface Flapping (Spine to Superspine Interfaces)\"}, \"threshold\": {\"title\": \"Threshold\", \"description\": \"Sum total of number of flaps in recent-history for which an anomaly will be raised. The larger the value, the more memory the probe will consume.\", \"type\": \"integer\", \"minimum\": 1, \"default\": 5}, \"max_flapping_interfaces_percentage\": {\"title\": \"Max Flapping Interfaces Percentage\", \"description\": \"Maximum percentage of flapping interfaces on a device\", \"type\": \"integer\", \"minimum\": 0, \"maximum\": 100, \"default\": 10}, \"duration\": {\"title\": \"Duration\", \"description\": \"Duration of recent-history in which interface flapping will be considered. The longer the period, the more memory the probe will consume.\", \"type\": \"integer\", \"minimum\": 1, \"default\": 60}}}" +#} +#"traffic" = { +# "blueprint_id" = "c151d0c1-fda1-495b-86e8-92d2499ac6f8" +# "description" = <<-EOT +# +# This probe displays the all the interface counters available for the +# system, their utilizations and utilizations aggregated on a per system +# basis. +# +# EOT +# "name" = "traffic" +# "schema" = "{\"type\": \"object\", \"properties\": {\"label\": {\"title\": \"Probe Label\", \"type\": \"string\", \"minLength\": 1, \"maxLength\": 120, \"default\": \"Device Traffic\"}, \"interface_counters_average_period\": {\"title\": \"Interface counters average period\", \"description\": \"The average period duration for interface counters\", \"type\": \"integer\", \"minimum\": 1, \"default\": 120}, \"enable_interface_counters_history\": {\"title\": \"Enable interface counters history\", \"description\": \"Maintain historical interface counters data\", \"type\": \"boolean\", \"default\": true}, \"interface_counters_history_retention_period\": {\"title\": \"Interface counters history retention period\", \"description\": \"Duration to maintain historical interface counters data\", \"type\": \"integer\", \"minimum\": 1, \"default\": 2592000}, \"enable_system_counters_history\": {\"title\": \"Enable system counters history\", \"description\": \"Maintain historical system interface counters data\", \"type\": \"boolean\", \"default\": true}, \"system_counters_history_retention_period\": {\"title\": \"System interface counters history retention period\", \"description\": \"Duration to maintain historical system interface counters data\", \"type\": \"integer\", \"minimum\": 1, \"default\": 2592000}}}" +#}, +#"virtual_infra_hypervisor_redundancy_checks" = { +# "blueprint_id" = "c151d0c1-fda1-495b-86e8-92d2499ac6f8" +# "description" = <<-EOT +# Generate a probe to detect hypervisor redundancy. +# +# EOT +# "name" = "virtual_infra_hypervisor_redundancy_checks" +# "schema" = "{\"type\": \"object\", \"properties\": {\"label\": {\"title\": \"Probe Label\", \"type\": \"string\", \"minLength\": 1, \"maxLength\": 120, \"default\": \"Hypervisor Redundancy Checks\"}}}" +#}, +#"virtual_infra_lag_match" = { +# "blueprint_id" = "c151d0c1-fda1-495b-86e8-92d2499ac6f8" +# "description" = <<-EOT +# Generate a probe to detect inconsistent LAG configs between +# fabric and virtual infra. +# +# This probe calculates LAGs missing on hypervisors and AOS managed systems +# connected to hypervisors. +# +# EOT +# "name" = "virtual_infra_lag_match" +# "schema" = "{\"type\": \"object\", \"properties\": {\"label\": {\"title\": \"Probe Label\", \"type\": \"string\", \"minLength\": 1, \"maxLength\": 120, \"default\": \"Hypervisor & Fabric LAG Config Mismatch\"}}}" +#}, +#"virtual_infra_missing_lldp" = { +# "blueprint_id" = "c151d0c1-fda1-495b-86e8-92d2499ac6f8" +# "description" = <<-EOT +# Generate a probe to detect virtual infra hosts that are not +# configured for LLDP. +# +# EOT +# "name" = "virtual_infra_missing_lldp" +# "schema" = "{\"type\": \"object\", \"properties\": {\"label\": {\"title\": \"Probe Label\", \"type\": \"string\", \"minLength\": 1, \"maxLength\": 120, \"default\": \"Hypervisor Missing LLDP Config\"}}}" +#}, +#"virtual_infra_vlan_match" = { +# "blueprint_id" = "c151d0c1-fda1-495b-86e8-92d2499ac6f8" +# "description" = <<-EOT +# Generate a probe to calculate missing VLANs +# +# This probe calculates VLAN(s) mismatch between AOS configured +# virtual networks on the systems and the VLANs needed by the VMs running +# on the hypervisors attached to the systems. +# +# EOT +# "name" = "virtual_infra_vlan_match" +# "schema" = "{\"type\": \"object\", \"properties\": {\"label\": {\"title\": \"Probe Label\", \"type\": \"string\", \"minLength\": 1, \"maxLength\": 120, \"default\": \"Hypervisor & Fabric VLAN Config Mismatch\"}}}" +#}, +#"vxlan_floodlist" = { +# "blueprint_id" = "c151d0c1-fda1-495b-86e8-92d2499ac6f8" +# "description" = <<-EOT +# +# This probe validates the VXLAN flood list entries on every leaf +# in the network. It collects appropriate telemetry data, +# compares it to the set of flood list forwarding entries +# expected to be present and alerts if expected entries are missing +# on any device. +# +# Route Labels +# +# Expected: This route is expected on the device as per service +# defined. +# +# Missing: This route is missing on the device when compared to +# the expected route set. +# +# Unexpected: There are no expectations rendered (by AOS) for this +# route. +# +# EOT +# "name" = "vxlan_floodlist" +# "schema" = "{\"type\": \"object\", \"properties\": {\"label\": {\"title\": \"Probe Label\", \"type\": \"string\", \"minLength\": 1, \"maxLength\": 120, \"default\": \"VXLAN Flood List Validation\"}, \"duration\": {\"title\": \"Anomaly Time Window\", \"type\": \"integer\", \"minimum\": 1, \"default\": 360}, \"threshold\": {\"title\": \"Anomaly Threshold (in %)\", \"description\": \"If routes are missing for more than or equal to percentage of Anomaly Time Window, an anomaly will be raised.\", \"type\": \"integer\", \"minimum\": 0, \"maximum\": 100, \"default\": 100}, \"collection_period\": {\"title\": \"Collection period\", \"description\": \"Telemetry collection interval.\", \"type\": \"number\", \"minimum\": 0, \"default\": 300.0}}}" +#} +#} diff --git a/examples/data-sources/apstra_iba_predefined_probes/example.tf b/examples/data-sources/apstra_iba_predefined_probes/example.tf new file mode 100644 index 00000000..0461da6d --- /dev/null +++ b/examples/data-sources/apstra_iba_predefined_probes/example.tf @@ -0,0 +1,37 @@ +# This example pulls one predefined iba probe from a blueprint + +data "apstra_datacenter_blueprint" "b" { + name = "test" +} + +data "apstra_iba_predefined_probe" "p1" { + blueprint_id = data.apstra_datacenter_blueprint.b.id + name = "spine_superspine_interface_flapping" +} + +output "o3" { + value = data.apstra_iba_predefined_probe.p1 +} + + +#o3 = { +# "blueprint_id" = "c151d0c1-fda1-495b-86e8-92d2499ac6f8" +# "description" = <<-EOT +# Generate a probe to determine if spine to superspine +# interfaces are flapping. +# +# A given interface is considered to be flapping if it transitions state +# more than "Threshold" times over the last "Duration". Such +# flapping will cause an anomaly to be raised. +# +# If more-than "Max Flapping Interfaces Percentage" percent of +# interfaces on a given device are flapping, an anomaly will +# be raised for that device. +# +# Finally, the last "Anomaly History Count" anomaly state-changes +# are stored for observation. +# +# EOT +# "name" = "spine_superspine_interface_flapping" +# "schema" = "{\"type\": \"object\", \"properties\": {\"label\": {\"title\": \"Probe Label\", \"type\": \"string\", \"minLength\": 1, \"maxLength\": 120, \"default\": \"Interface Flapping (Spine to Superspine Interfaces)\"}, \"threshold\": {\"title\": \"Threshold\", \"description\": \"Sum total of number of flaps in recent-history for which an anomaly will be raised. The larger the value, the more memory the probe will consume.\", \"type\": \"integer\", \"minimum\": 1, \"default\": 5}, \"max_flapping_interfaces_percentage\": {\"title\": \"Max Flapping Interfaces Percentage\", \"description\": \"Maximum percentage of flapping interfaces on a device\", \"type\": \"integer\", \"minimum\": 0, \"maximum\": 100, \"default\": 10}, \"duration\": {\"title\": \"Duration\", \"description\": \"Duration of recent-history in which interface flapping will be considered. The longer the period, the more memory the probe will consume.\", \"type\": \"integer\", \"minimum\": 1, \"default\": 60}}}" +#} diff --git a/examples/resources/apstra_iba_probe/example.tf b/examples/resources/apstra_iba_probe/example.tf new file mode 100644 index 00000000..7c2d87e8 --- /dev/null +++ b/examples/resources/apstra_iba_probe/example.tf @@ -0,0 +1,50 @@ +# The following example instantiates predefined probes in Apstra + +data "apstra_datacenter_blueprint" "b" { + name = "test" +} + +resource "apstra_iba_probe" "p_device_health" { + blueprint_id = data.apstra_datacenter_blueprint.b.id + predefined_probe_id = "device_health" + probe_config = jsonencode( + { + "max_cpu_utilization": 80, + "max_memory_utilization": 80, + "max_disk_utilization": 80, + "duration": 660, + "threshold_duration": 360, + "history_duration": 604800 + } + ) +} + +output "o"{ + value = apstra_iba_probe.p_device_health +} + +#Output Looks somethng like this +#o = { +#"blueprint_id" = "c151d0c1-fda1-495b-86e8-92d2499ac6f8" +#"description" = "This probe alerts if the system health parameters (CPU, memory and disk usage) exceed their specified thresholds for the specified duration." +#"id" = "0b738068-11dc-4050-aa7c-65cd8715cc6e" +#"name" = "Device System Health" +#"predefined_probe_id" = "device_health" +#"probe_config" = "{\"duration\":660,\"history_duration\":604800,\"max_cpu_utilization\":80,\"max_disk_utilization\":80,\"max_memory_utilization\":80,\"threshold_duration\":360}" +#"stages" = toset([ +#"Check cpu utilization threshold", +#"Check disk utilization threshold", +#"Check memory utilization threshold", +#"Disk utilization data", +#"Disk utilization data per partition", +#"System cpu utilization data", +#"System memory utilization data", +#"Systems with high CPU utilization", +#"Systems with high disk utilization", +#"Systems with high memory utilization", +#"sustained_high_cpu_utilization", +#"sustained_high_disk_utilization", +#"sustained_high_memory_utilization", +#]) +#} + diff --git a/examples/resources/apstra_iba_widget/example.tf b/examples/resources/apstra_iba_widget/example.tf new file mode 100644 index 00000000..6db3c569 --- /dev/null +++ b/examples/resources/apstra_iba_widget/example.tf @@ -0,0 +1,43 @@ +# The following example instantiates a predefined probe and initiates a widget in Apstra + +data "apstra_datacenter_blueprint" "b" { + name = "test" +} + +resource "apstra_iba_probe" "p_device_health" { + blueprint_id = data.apstra_datacenter_blueprint.b.id + predefined_probe_id = "device_health" + probe_config = jsonencode( + { + "max_cpu_utilization": 80, + "max_memory_utilization": 80, + "max_disk_utilization": 80, + "duration": 660, + "threshold_duration": 360, + "history_duration": 604800 + } + ) +} + +resource "apstra_iba_widget" "w_device_health_high_cpu" { + blueprint_id = data.apstra_datacenter_blueprint.b.id + name = "Devices with high CPU Utilization" + probe_id = apstra_iba_probe.p_device_health.id + stage = "Systems with high CPU utilization" + description = "made from terraform" +} + +output "o"{ + value = apstra_iba_widget.w_device_health_high_cpu +} + +# Output looks something like this +#o = { +# "blueprint_id" = "c151d0c1-fda1-495b-86e8-92d2499ac6f8" +# "description" = "made from terraform" +# "id" = "39613d7f-a5be-4359-bbd8-497c56894153" +# "name" = "Devices with high CPU Utilization" +# "probe_id" = "0b738068-11dc-4050-aa7c-65cd8715cc6e" +# "stage" = "Systems with high CPU utilization" +#} + diff --git a/go.mod b/go.mod index c49d5648..b2d56504 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.20 require ( github.com/IBM/netaddr v1.5.0 - github.com/Juniper/apstra-go-sdk v0.0.0-20231014134337-d36959aa30d4 + github.com/Juniper/apstra-go-sdk v0.0.0-20231017135235-6928acdbc77f github.com/chrismarget-j/go-licenses v0.0.0-20230424163011-d60082a506e0 github.com/hashicorp/go-version v1.6.0 github.com/hashicorp/terraform-plugin-docs v0.13.0 diff --git a/go.sum b/go.sum index ec9487d2..d561c94c 100644 --- a/go.sum +++ b/go.sum @@ -71,6 +71,8 @@ github.com/Juniper/apstra-go-sdk v0.0.0-20231014094535-29acb3e1bf00 h1:YYqFb1Hsl github.com/Juniper/apstra-go-sdk v0.0.0-20231014094535-29acb3e1bf00/go.mod h1:It+5cLgOj77K+s+7m5Nsnbms3Tu/4ObqDuBjsTR2Oh0= github.com/Juniper/apstra-go-sdk v0.0.0-20231014134337-d36959aa30d4 h1:H/ZXWL3acgyWplJt8q5lS15X9IN8in8OQ3WXrdVzPj0= github.com/Juniper/apstra-go-sdk v0.0.0-20231014134337-d36959aa30d4/go.mod h1:It+5cLgOj77K+s+7m5Nsnbms3Tu/4ObqDuBjsTR2Oh0= +github.com/Juniper/apstra-go-sdk v0.0.0-20231017135235-6928acdbc77f h1:+9i18zSI2iEUqgKvDiCFM3HghRAN4Grjmp+4hDlljMw= +github.com/Juniper/apstra-go-sdk v0.0.0-20231017135235-6928acdbc77f/go.mod h1:It+5cLgOj77K+s+7m5Nsnbms3Tu/4ObqDuBjsTR2Oh0= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=