-
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 resource: azurerm_spring_cloud_dynatrace_application_performance_monitoring
#23889
Changes from 7 commits
79a6208
5486491
fbb153a
90e5ceb
505e656
2be27d6
4d95e0d
0693bea
662e133
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,348 @@ | ||
package springcloud | ||
|
||
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/commonids" | ||
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema" | ||
"github.com/hashicorp/go-azure-sdk/resource-manager/appplatform/2023-09-01-preview/appplatform" | ||
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk" | ||
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" | ||
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" | ||
) | ||
|
||
type SpringCloudDynatraceApplicationPerformanceMonitoringModel struct { | ||
Name string `tfschema:"name"` | ||
SpringCloudServiceId string `tfschema:"spring_cloud_service_id"` | ||
GloballyEnabled bool `tfschema:"globally_enabled"` | ||
ApiUrl string `tfschema:"api_url"` | ||
ApiToken string `tfschema:"api_token"` | ||
ConnectionPoint string `tfschema:"connection_point"` | ||
EnvironmentId string `tfschema:"environment_id"` | ||
Tenant string `tfschema:"tenant"` | ||
TenantToken string `tfschema:"tenant_token"` | ||
} | ||
|
||
type SpringCloudDynatraceApplicationPerformanceMonitoringResource struct{} | ||
|
||
var _ sdk.ResourceWithUpdate = SpringCloudDynatraceApplicationPerformanceMonitoringResource{} | ||
|
||
func (s SpringCloudDynatraceApplicationPerformanceMonitoringResource) ResourceType() string { | ||
return "azurerm_spring_cloud_dynatrace_application_performance_monitoring" | ||
} | ||
|
||
func (s SpringCloudDynatraceApplicationPerformanceMonitoringResource) ModelObject() interface{} { | ||
return &SpringCloudDynatraceApplicationPerformanceMonitoringModel{} | ||
} | ||
|
||
func (s SpringCloudDynatraceApplicationPerformanceMonitoringResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { | ||
return appplatform.ValidateApmID | ||
} | ||
|
||
func (s SpringCloudDynatraceApplicationPerformanceMonitoringResource) Arguments() map[string]*pluginsdk.Schema { | ||
return map[string]*pluginsdk.Schema{ | ||
"name": { | ||
Type: pluginsdk.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
ValidateFunc: validation.StringIsNotEmpty, | ||
}, | ||
|
||
"spring_cloud_service_id": commonschema.ResourceIDReferenceRequiredForceNew(commonids.SpringCloudServiceId{}), | ||
|
||
"connection_point": { | ||
Type: pluginsdk.TypeString, | ||
Required: true, | ||
ValidateFunc: validation.StringIsNotEmpty, | ||
}, | ||
|
||
"tenant": { | ||
Type: pluginsdk.TypeString, | ||
Required: true, | ||
Sensitive: true, | ||
ValidateFunc: validation.StringIsNotEmpty, | ||
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. can we do a better job validating this? 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. I'm afraid that we can't |
||
}, | ||
|
||
"tenant_token": { | ||
magodo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Type: pluginsdk.TypeString, | ||
Required: true, | ||
Sensitive: true, | ||
ValidateFunc: validation.StringIsNotEmpty, | ||
magodo marked this conversation as resolved.
Show resolved
Hide resolved
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. and here 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 the token used to authenticated, so we can't validate it. |
||
}, | ||
|
||
"api_url": { | ||
Type: pluginsdk.TypeString, | ||
Optional: true, | ||
ValidateFunc: validation.StringIsNotEmpty, | ||
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 should be validate as a url? |
||
}, | ||
|
||
"api_token": { | ||
Type: pluginsdk.TypeString, | ||
Optional: true, | ||
Sensitive: true, | ||
ValidateFunc: validation.StringIsNotEmpty, | ||
magodo marked this conversation as resolved.
Show resolved
Hide resolved
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. can we properly validate this? 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 a token used to authenticated, so we can't validate it. |
||
}, | ||
|
||
"environment_id": { | ||
Type: pluginsdk.TypeString, | ||
Optional: true, | ||
ValidateFunc: validation.StringIsNotEmpty, | ||
magodo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}, | ||
|
||
"globally_enabled": { | ||
Type: pluginsdk.TypeBool, | ||
Optional: true, | ||
Default: false, | ||
}, | ||
} | ||
} | ||
|
||
func (s SpringCloudDynatraceApplicationPerformanceMonitoringResource) Attributes() map[string]*pluginsdk.Schema { | ||
return map[string]*pluginsdk.Schema{} | ||
} | ||
|
||
func (s SpringCloudDynatraceApplicationPerformanceMonitoringResource) Create() sdk.ResourceFunc { | ||
return sdk.ResourceFunc{ | ||
Timeout: 30 * time.Minute, | ||
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { | ||
var model SpringCloudDynatraceApplicationPerformanceMonitoringModel | ||
if err := metadata.Decode(&model); err != nil { | ||
return fmt.Errorf("decoding: %+v", err) | ||
} | ||
|
||
client := metadata.Client.AppPlatform.AppPlatformClient | ||
springId, err := commonids.ParseSpringCloudServiceID(model.SpringCloudServiceId) | ||
if err != nil { | ||
return fmt.Errorf("parsing spring service ID: %+v", err) | ||
} | ||
id := appplatform.NewApmID(springId.SubscriptionId, springId.ResourceGroupName, springId.ServiceName, model.Name) | ||
|
||
existing, err := client.ApmsGet(ctx, id) | ||
if err != nil && !response.WasNotFound(existing.HttpResponse) { | ||
return fmt.Errorf("checking for existing %s: %+v", id, err) | ||
} | ||
if !response.WasNotFound(existing.HttpResponse) { | ||
return metadata.ResourceRequiresImport(s.ResourceType(), id) | ||
} | ||
|
||
resource := appplatform.ApmResource{ | ||
Properties: &appplatform.ApmProperties{ | ||
Type: "Dynatrace", | ||
Properties: pointer.To(map[string]string{ | ||
"api-url": model.ApiUrl, | ||
"connection_point": model.ConnectionPoint, | ||
"environment-id": model.EnvironmentId, | ||
}), | ||
Secrets: pointer.To(map[string]string{ | ||
"api-token": model.ApiToken, | ||
"tenanttoken": model.TenantToken, | ||
"tenant": model.Tenant, | ||
}), | ||
}, | ||
} | ||
err = client.ApmsCreateOrUpdateThenPoll(ctx, id, resource) | ||
if err != nil { | ||
return fmt.Errorf("creating %s: %+v", id, err) | ||
} | ||
|
||
metadata.SetID(id) | ||
|
||
if model.GloballyEnabled { | ||
magodo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
apmReference := appplatform.ApmReference{ | ||
ResourceId: id.ID(), | ||
} | ||
err = client.ServicesEnableApmGloballyThenPoll(ctx, *springId, apmReference) | ||
if err != nil { | ||
return fmt.Errorf("enabling %s globally: %+v", id, err) | ||
} | ||
} | ||
|
||
return nil | ||
}, | ||
} | ||
} | ||
|
||
func (s SpringCloudDynatraceApplicationPerformanceMonitoringResource) Update() sdk.ResourceFunc { | ||
return sdk.ResourceFunc{ | ||
Timeout: 30 * time.Minute, | ||
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { | ||
client := metadata.Client.AppPlatform.AppPlatformClient | ||
|
||
id, err := appplatform.ParseApmID(metadata.ResourceData.Id()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var model SpringCloudDynatraceApplicationPerformanceMonitoringModel | ||
if err := metadata.Decode(&model); err != nil { | ||
return fmt.Errorf("decoding: %+v", err) | ||
} | ||
|
||
resp, err := client.ApmsGet(ctx, *id) | ||
if err != nil { | ||
return fmt.Errorf("retrieving %s: %+v", *id, err) | ||
} | ||
|
||
properties := resp.Model.Properties | ||
if properties == nil { | ||
return fmt.Errorf("retrieving %s: properties was nil", id) | ||
} | ||
if properties.Properties == nil { | ||
properties.Properties = pointer.To(map[string]string{}) | ||
} | ||
if properties.Secrets == nil { | ||
properties.Secrets = pointer.To(map[string]string{}) | ||
} | ||
|
||
if metadata.ResourceData.HasChange("api_url") { | ||
(*properties.Properties)["api-url"] = model.ApiUrl | ||
} | ||
|
||
if metadata.ResourceData.HasChange("api_token") { | ||
(*properties.Secrets)["api-token"] = model.ApiToken | ||
} | ||
|
||
if metadata.ResourceData.HasChange("connection_point") { | ||
(*properties.Properties)["connection_point"] = model.ConnectionPoint | ||
} | ||
|
||
if metadata.ResourceData.HasChange("environment_id") { | ||
(*properties.Properties)["environment-id"] = model.EnvironmentId | ||
} | ||
|
||
if metadata.ResourceData.HasChange("tenant") { | ||
(*properties.Secrets)["tenant"] = model.Tenant | ||
} | ||
|
||
if metadata.ResourceData.HasChange("tenant_token") { | ||
(*properties.Secrets)["tenanttoken"] = model.TenantToken | ||
} | ||
|
||
resource := appplatform.ApmResource{ | ||
Properties: properties, | ||
} | ||
|
||
err = client.ApmsCreateOrUpdateThenPoll(ctx, *id, resource) | ||
if err != nil { | ||
return fmt.Errorf("updating %s: %+v", id, err) | ||
} | ||
|
||
if metadata.ResourceData.HasChange("globally_enabled") { | ||
apmReference := appplatform.ApmReference{ | ||
ResourceId: id.ID(), | ||
} | ||
springId := commonids.NewSpringCloudServiceID(id.SubscriptionId, id.ResourceGroupName, id.SpringName) | ||
if model.GloballyEnabled { | ||
err := client.ServicesEnableApmGloballyThenPoll(ctx, springId, apmReference) | ||
if err != nil { | ||
return fmt.Errorf("enabling %s globally: %+v", id, err) | ||
} | ||
} else { | ||
err := client.ServicesDisableApmGloballyThenPoll(ctx, springId, apmReference) | ||
if err != nil { | ||
return fmt.Errorf("disabling %s globally: %+v", id, err) | ||
} | ||
} | ||
} | ||
|
||
return nil | ||
}, | ||
} | ||
} | ||
|
||
func (s SpringCloudDynatraceApplicationPerformanceMonitoringResource) Read() sdk.ResourceFunc { | ||
return sdk.ResourceFunc{ | ||
Timeout: 5 * time.Minute, | ||
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { | ||
client := metadata.Client.AppPlatform.AppPlatformClient | ||
|
||
id, err := appplatform.ParseApmID(metadata.ResourceData.Id()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
resp, err := client.ApmsGet(ctx, *id) | ||
if err != nil { | ||
if response.WasNotFound(resp.HttpResponse) { | ||
return metadata.MarkAsGone(id) | ||
} | ||
|
||
return fmt.Errorf("retrieving %s: %+v", *id, err) | ||
} | ||
|
||
springId := commonids.NewSpringCloudServiceID(id.SubscriptionId, id.ResourceGroupName, id.SpringName) | ||
result, err := client.ServicesListGloballyEnabledApms(ctx, springId) | ||
if err != nil { | ||
return fmt.Errorf("listing globally enabled apms: %+v", err) | ||
} | ||
globallyEnabled := false | ||
if result.Model != nil && result.Model.Value != nil { | ||
for _, value := range *result.Model.Value { | ||
apmId, err := appplatform.ParseApmIDInsensitively(value) | ||
if err == nil && apmId.ID() == id.ID() { | ||
globallyEnabled = true | ||
break | ||
} | ||
} | ||
} | ||
|
||
var model SpringCloudDynatraceApplicationPerformanceMonitoringModel | ||
if err := metadata.Decode(&model); err != nil { | ||
return fmt.Errorf("decoding: %+v", err) | ||
} | ||
|
||
state := SpringCloudDynatraceApplicationPerformanceMonitoringModel{ | ||
Name: id.ApmName, | ||
SpringCloudServiceId: springId.ID(), | ||
GloballyEnabled: globallyEnabled, | ||
ApiToken: model.ApiToken, | ||
TenantToken: model.TenantToken, | ||
Tenant: model.Tenant, | ||
} | ||
|
||
if props := resp.Model.Properties; props != nil { | ||
if props.Type != "Dynatrace" { | ||
return fmt.Errorf("retrieving %s: type was not Dynatrace", *id) | ||
} | ||
if props.Properties != nil { | ||
if value, ok := (*props.Properties)["api-url"]; ok { | ||
state.ApiUrl = value | ||
} | ||
if value, ok := (*props.Properties)["connection_point"]; ok { | ||
state.ConnectionPoint = value | ||
} | ||
if value, ok := (*props.Properties)["environment-id"]; ok { | ||
state.EnvironmentId = value | ||
} | ||
} | ||
} | ||
|
||
return metadata.Encode(&state) | ||
}, | ||
} | ||
} | ||
|
||
func (s SpringCloudDynatraceApplicationPerformanceMonitoringResource) Delete() sdk.ResourceFunc { | ||
return sdk.ResourceFunc{ | ||
Timeout: 30 * time.Minute, | ||
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { | ||
client := metadata.Client.AppPlatform.AppPlatformClient | ||
|
||
id, err := appplatform.ParseApmID(metadata.ResourceData.Id()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = client.ApmsDeleteThenPoll(ctx, *id) | ||
if err != nil { | ||
return fmt.Errorf("deleting %s: %+v", *id, err) | ||
} | ||
|
||
return nil | ||
}, | ||
} | ||
} |
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.
should this be
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.
or is this different then a standard azure tennant id?
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.
Yes, this is not a standard azure tenant id.