-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New data source: azurerm_dynatrace_monitor
#28381
base: main
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,217 @@ | ||
package dynatrace | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"time" | ||
|
||
"github.com/hashicorp/go-azure-helpers/lang/pointer" | ||
"github.com/hashicorp/go-azure-helpers/lang/response" | ||
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema" | ||
"github.com/hashicorp/go-azure-helpers/resourcemanager/identity" | ||
"github.com/hashicorp/go-azure-sdk/resource-manager/dynatrace/2023-04-27/monitors" | ||
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk" | ||
"github.com/hashicorp/terraform-provider-azurerm/internal/tags" | ||
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" | ||
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" | ||
) | ||
|
||
type MonitorsDataSource struct{} | ||
|
||
type MonitorsDataSourceModel struct { | ||
Name string `tfschema:"name"` | ||
ResourceGroup string `tfschema:"resource_group_name"` | ||
Location string `tfschema:"location"` | ||
MonitoringStatus bool `tfschema:"monitoring_enabled"` | ||
MarketplaceSubscriptionStatus string `tfschema:"marketplace_subscription"` | ||
Identity []identity.ModelSystemAssigned `tfschema:"identity"` | ||
EnvironmentProperties []EnvironmentProperties `tfschema:"environment_properties"` | ||
PlanData []PlanData `tfschema:"plan"` | ||
UserInfo []UserInfo `tfschema:"user"` | ||
Tags map[string]string `tfschema:"tags"` | ||
} | ||
|
||
type EnvironmentProperties struct { | ||
EnvironmentInfo []EnvironmentInfo `tfschema:"environment_info"` | ||
} | ||
|
||
type EnvironmentInfo struct { | ||
EnvironmentId string `tfschema:"environment_id"` | ||
} | ||
|
||
var _ sdk.DataSource = MonitorsDataSource{} | ||
|
||
func (d MonitorsDataSource) Arguments() map[string]*pluginsdk.Schema { | ||
return map[string]*pluginsdk.Schema{ | ||
"name": { | ||
Type: pluginsdk.TypeString, | ||
Required: true, | ||
ValidateFunc: validation.StringIsNotEmpty, | ||
}, | ||
|
||
"resource_group_name": commonschema.ResourceGroupNameForDataSource(), | ||
} | ||
} | ||
|
||
func (d MonitorsDataSource) Attributes() map[string]*pluginsdk.Schema { | ||
return map[string]*pluginsdk.Schema{ | ||
"location": commonschema.LocationComputed(), | ||
|
||
"monitoring_enabled": { | ||
Type: pluginsdk.TypeBool, | ||
Computed: true, | ||
}, | ||
|
||
"marketplace_subscription": { | ||
Type: pluginsdk.TypeString, | ||
Computed: true, | ||
}, | ||
|
||
"identity": commonschema.SystemAssignedIdentityComputed(), | ||
|
||
"plan": { | ||
Type: pluginsdk.TypeList, | ||
Computed: true, | ||
Elem: &pluginsdk.Resource{ | ||
Schema: map[string]*pluginsdk.Schema{ | ||
"billing_cycle": { | ||
Type: pluginsdk.TypeString, | ||
Computed: true, | ||
}, | ||
|
||
"plan": { | ||
Type: pluginsdk.TypeString, | ||
Computed: true, | ||
}, | ||
|
||
"usage_type": { | ||
Type: pluginsdk.TypeString, | ||
Computed: true, | ||
}, | ||
|
||
"effective_date": { | ||
Type: pluginsdk.TypeString, | ||
Computed: true, | ||
}, | ||
}, | ||
}, | ||
}, | ||
|
||
"user": { | ||
Type: pluginsdk.TypeList, | ||
Computed: true, | ||
Elem: &pluginsdk.Resource{ | ||
Schema: map[string]*pluginsdk.Schema{ | ||
"country": { | ||
Type: pluginsdk.TypeString, | ||
Computed: true, | ||
}, | ||
|
||
"email": { | ||
Type: pluginsdk.TypeString, | ||
Computed: true, | ||
}, | ||
|
||
"first_name": { | ||
Type: pluginsdk.TypeString, | ||
Computed: true, | ||
}, | ||
|
||
"last_name": { | ||
Type: pluginsdk.TypeString, | ||
Computed: true, | ||
}, | ||
|
||
"phone_number": { | ||
Type: pluginsdk.TypeString, | ||
Computed: true, | ||
}, | ||
}, | ||
}, | ||
}, | ||
|
||
"environment_properties": { | ||
Type: pluginsdk.TypeList, | ||
Computed: true, | ||
Elem: &pluginsdk.Resource{ | ||
Schema: map[string]*pluginsdk.Schema{ | ||
"environment_info": { | ||
Type: pluginsdk.TypeList, | ||
Computed: true, | ||
Elem: &pluginsdk.Resource{ | ||
Schema: map[string]*pluginsdk.Schema{ | ||
"environment_id": { | ||
Type: pluginsdk.TypeString, | ||
Computed: true, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
|
||
"tags": tags.SchemaDataSource(), | ||
} | ||
} | ||
|
||
func (d MonitorsDataSource) ModelObject() interface{} { | ||
return &MonitorsDataSourceModel{} | ||
} | ||
|
||
func (d MonitorsDataSource) ResourceType() string { | ||
return "azurerm_dynatrace_monitor" | ||
} | ||
|
||
func (d MonitorsDataSource) Read() sdk.ResourceFunc { | ||
return sdk.ResourceFunc{ | ||
Timeout: 5 * time.Minute, | ||
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { | ||
client := metadata.Client.Dynatrace.MonitorsClient | ||
subscriptionId := metadata.Client.Account.SubscriptionId | ||
|
||
var monitor MonitorsDataSourceModel | ||
if err := metadata.Decode(&monitor); err != nil { | ||
return err | ||
} | ||
id := monitors.NewMonitorID(subscriptionId, monitor.ResourceGroup, monitor.Name) | ||
|
||
existing, err := client.Get(ctx, id) | ||
if err != nil { | ||
if response.WasNotFound(existing.HttpResponse) { | ||
return fmt.Errorf("%s was not found", id) | ||
} | ||
return fmt.Errorf("reading %s: %+v", id, err) | ||
} | ||
|
||
if model := existing.Model; model != nil { | ||
props := model.Properties | ||
identityProps, err := flattenDynatraceIdentity(model.Identity) | ||
if err != nil { | ||
return fmt.Errorf("flattening identity: %+v", err) | ||
} | ||
monitoringStatus := true | ||
if pointer.From(props.MonitoringStatus) == monitors.MonitoringStatusDisabled { | ||
monitoringStatus = false | ||
} | ||
|
||
monitorResource := MonitorsDataSourceModel{ | ||
Name: id.MonitorName, | ||
ResourceGroup: id.ResourceGroupName, | ||
Location: model.Location, | ||
MonitoringStatus: monitoringStatus, | ||
MarketplaceSubscriptionStatus: string(pointer.From(props.MarketplaceSubscriptionStatus)), | ||
Identity: identityProps, | ||
EnvironmentProperties: FlattenDynatraceEnvironmentProperties(props.DynatraceEnvironmentProperties), | ||
PlanData: FlattenDynatracePlanData(props.PlanData), | ||
UserInfo: FlattenDynatraceUserInfo(metadata.ResourceData.Get("user").([]interface{})), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is computed only, so we cannot "Get" it here, if this is not returned by the API, it cannot be included in the Data Source as it will always be empty. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will fix. |
||
} | ||
if model.Tags != nil { | ||
monitorResource.Tags = pointer.From(model.Tags) | ||
} | ||
return metadata.Encode(&monitorResource) | ||
} | ||
return nil | ||
}, | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package dynatrace_test | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" | ||
) | ||
|
||
type MonitorsDataSource struct{} | ||
|
||
func TestAccDynatraceMonitorsDataSource_basic(t *testing.T) { | ||
data := acceptance.BuildTestData(t, "data.azurerm_dynatrace_monitor", "test") | ||
r := MonitorsDataSource{} | ||
|
||
data.DataSourceTest(t, []acceptance.TestStep{ | ||
{ | ||
Config: r.basic(data), | ||
Check: acceptance.ComposeTestCheckFunc(), | ||
}, | ||
}) | ||
} | ||
|
||
func (d MonitorsDataSource) basic(data acceptance.TestData) string { | ||
return fmt.Sprintf(` | ||
%s | ||
|
||
data "azurerm_dynatrace_monitor" "test" { | ||
name = azurerm_dynatrace_monitor.test.name | ||
resource_group_name = azurerm_resource_group.test.name | ||
} | ||
`, MonitorsResource{}.basic(data)) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -155,11 +155,11 @@ resource "azurerm_dynatrace_monitor" "test" { | |
} | ||
|
||
user { | ||
first_name = "%s" | ||
last_name = "%s" | ||
email = "%s" | ||
phone_number = "%s" | ||
country = "%s" | ||
first_name = "Alice" | ||
last_name = "Bobab" | ||
email = "[email protected]" | ||
phone_number = "123456" | ||
country = "westus" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are we now supplying data directly here? This looks like it might actually be a real email (or could be in future?) Is this a mistake from local testing that should be removed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, it was for local testing, will remove them. |
||
} | ||
|
||
plan { | ||
|
@@ -172,7 +172,7 @@ resource "azurerm_dynatrace_monitor" "test" { | |
environment = "Dev" | ||
} | ||
} | ||
`, template, data.RandomInteger, r.dynatraceInfo.UserFirstName, r.dynatraceInfo.UserLastName, r.dynatraceInfo.UserEmail, r.dynatraceInfo.UserPhoneNumber, r.dynatraceInfo.UserCountry) | ||
`, template, data.RandomInteger) | ||
} | ||
|
||
func (r MonitorsResource) updated(data acceptance.TestData) string { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason we're doing 2 levels of nesting here for a single value? Can this just be flattened to the top level?
Also, this property doesn't appear to be supported by the related resource, should it even be included here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'd better not flatten this because according to the service team, there are a bunch of other attributes under
environment_properties
andenvironment_info
, but they do not want them on TF right now. We will have to onboard them once they request in the future.This property is not supported by the related resource is because it's an optional + computed attribute and its value comes from the API response only, that's why we will have to onboard the data source first. Then I'll add it to the related resource.