-
Notifications
You must be signed in to change notification settings - Fork 134
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #604 from ovh/dev/aamstutz/ip-mitigation
feat: Add resource/datasource ovh_ip_mitigation
- Loading branch information
Showing
10 changed files
with
604 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package ovh | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/url" | ||
|
||
"github.com/hashicorp/terraform-plugin-framework/datasource" | ||
) | ||
|
||
var _ datasource.DataSourceWithConfigure = (*ipMitigationDataSource)(nil) | ||
|
||
func NewIpMitigationDataSource() datasource.DataSource { | ||
return &ipMitigationDataSource{} | ||
} | ||
|
||
type ipMitigationDataSource struct { | ||
config *Config | ||
} | ||
|
||
func (d *ipMitigationDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { | ||
resp.TypeName = req.ProviderTypeName + "_ip_mitigation" | ||
} | ||
|
||
func (d *ipMitigationDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { | ||
if req.ProviderData == nil { | ||
return | ||
} | ||
|
||
config, ok := req.ProviderData.(*Config) | ||
if !ok { | ||
resp.Diagnostics.AddError( | ||
"Unexpected Data Source Configure Type", | ||
fmt.Sprintf("Expected *Config, got: %T. Please report this issue to the provider developers.", req.ProviderData), | ||
) | ||
return | ||
} | ||
|
||
d.config = config | ||
} | ||
|
||
func (d *ipMitigationDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { | ||
resp.Schema = IpMitigationDataSourceSchema(ctx) | ||
} | ||
|
||
func (d *ipMitigationDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { | ||
var data IpMitigationModel | ||
|
||
// Read Terraform configuration data into the model | ||
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) | ||
|
||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
// Read API call logic | ||
endpoint := "/ip/" + url.PathEscape(data.Ip.ValueString()) + "/mitigation/" + url.PathEscape(data.IpOnMitigation.ValueString()) | ||
if err := d.config.OVHClient.Get(endpoint, &data); err != nil { | ||
resp.Diagnostics.AddError( | ||
fmt.Sprintf("Error calling Get %s", endpoint), | ||
err.Error(), | ||
) | ||
return | ||
} | ||
|
||
// Save data into Terraform state | ||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package ovh | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-testing/helper/resource" | ||
) | ||
|
||
const testAccIPMitigationDataSourceConfig = ` | ||
resource "ovh_ip_mitigation" "mitigation" { | ||
ip = "%s" | ||
ip_on_mitigation = "%s" | ||
} | ||
data "ovh_ip_mitigation" "mitigation_data" { | ||
ip = ovh_ip_mitigation.mitigation.ip | ||
ip_on_mitigation = ovh_ip_mitigation.mitigation.ip_on_mitigation | ||
} | ||
` | ||
|
||
func TestAccIPMitigationData_basic(t *testing.T) { | ||
ip := os.Getenv("OVH_IP_TEST") | ||
|
||
config := fmt.Sprintf(testAccIPMitigationDataSourceConfig, ip, ip) | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheckIp(t) }, | ||
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: config, | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestCheckResourceAttr( | ||
"data.ovh_ip_mitigation.mitigation_data", "ip_on_mitigation", ip), | ||
resource.TestCheckResourceAttr( | ||
"data.ovh_ip_mitigation.mitigation_data", "state", "ok"), | ||
resource.TestCheckResourceAttr( | ||
"data.ovh_ip_mitigation.mitigation_data", "auto", "false"), | ||
resource.TestCheckResourceAttr( | ||
"data.ovh_ip_mitigation.mitigation_data", "permanent", "true"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
package ovh | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"net/url" | ||
"time" | ||
|
||
"github.com/hashicorp/terraform-plugin-framework/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" | ||
"github.com/ovh/go-ovh/ovh" | ||
) | ||
|
||
var _ resource.ResourceWithConfigure = (*ipMitigationResource)(nil) | ||
|
||
func NewIpMitigationResource() resource.Resource { | ||
return &ipMitigationResource{} | ||
} | ||
|
||
type ipMitigationResource struct { | ||
config *Config | ||
} | ||
|
||
func (r *ipMitigationResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { | ||
resp.TypeName = req.ProviderTypeName + "_ip_mitigation" | ||
} | ||
|
||
func (d *ipMitigationResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { | ||
if req.ProviderData == nil { | ||
return | ||
} | ||
|
||
config, ok := req.ProviderData.(*Config) | ||
if !ok { | ||
resp.Diagnostics.AddError( | ||
"Unexpected Resource Configure Type", | ||
fmt.Sprintf("Expected *Config, got: %T. Please report this issue to the provider developers.", req.ProviderData), | ||
) | ||
return | ||
} | ||
|
||
d.config = config | ||
} | ||
|
||
func (d *ipMitigationResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { | ||
resp.Schema = IpMitigationResourceSchema(ctx) | ||
} | ||
|
||
func (r *ipMitigationResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { | ||
var data, responseData IpMitigationModel | ||
|
||
// Read Terraform plan data into the model | ||
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
endpoint := "/ip/" + url.PathEscape(data.Ip.ValueString()) + "/mitigation" | ||
if err := r.config.OVHClient.Post(endpoint, data.ToCreate(), &responseData); err != nil { | ||
resp.Diagnostics.AddError( | ||
fmt.Sprintf("Error calling Post %s", endpoint), | ||
err.Error(), | ||
) | ||
return | ||
} | ||
|
||
// Wait for state to be ok | ||
endpoint = "/ip/" + url.PathEscape(data.Ip.ValueString()) + "/mitigation/" + url.PathEscape(data.IpOnMitigation.ValueString()) | ||
err := retry.RetryContext(ctx, 10*time.Minute, func() *retry.RetryError { | ||
readErr := r.config.OVHClient.Get(endpoint, &responseData) | ||
if readErr != nil { | ||
return retry.NonRetryableError(readErr) | ||
} | ||
|
||
if responseData.State.ValueString() == "ok" { | ||
return nil | ||
} | ||
|
||
return retry.RetryableError(errors.New("waiting for resource state to be ok")) | ||
}) | ||
|
||
if err != nil { | ||
resp.Diagnostics.AddError("error waiting status to be ok", err.Error()) | ||
return | ||
} | ||
|
||
responseData.MergeWith(&data) | ||
|
||
// Save data into Terraform state | ||
resp.Diagnostics.Append(resp.State.Set(ctx, &responseData)...) | ||
} | ||
|
||
func (r *ipMitigationResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { | ||
var data, responseData IpMitigationModel | ||
|
||
// Read Terraform prior state data into the model | ||
resp.Diagnostics.Append(req.State.Get(ctx, &data)...) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
endpoint := "/ip/" + url.PathEscape(data.Ip.ValueString()) + "/mitigation/" + url.PathEscape(data.IpOnMitigation.ValueString()) | ||
if err := r.config.OVHClient.Get(endpoint, &responseData); err != nil { | ||
resp.Diagnostics.AddError( | ||
fmt.Sprintf("Error calling Get %s", endpoint), | ||
err.Error(), | ||
) | ||
return | ||
} | ||
|
||
data.MergeWith(&responseData) | ||
|
||
// Save updated data into Terraform state | ||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) | ||
} | ||
|
||
func (r *ipMitigationResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { | ||
var data, planData, responseData IpMitigationModel | ||
|
||
// Read Terraform plan data into the model | ||
resp.Diagnostics.Append(req.Plan.Get(ctx, &planData)...) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
// Read Terraform prior state data into the model | ||
resp.Diagnostics.Append(req.State.Get(ctx, &data)...) | ||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
// Update resource | ||
endpoint := "/ip/" + url.PathEscape(data.Ip.ValueString()) + "/mitigation/" + url.PathEscape(data.IpOnMitigation.ValueString()) | ||
if err := r.config.OVHClient.Put(endpoint, planData.ToUpdate(), nil); err != nil { | ||
resp.Diagnostics.AddError( | ||
fmt.Sprintf("Error calling Put %s", endpoint), | ||
err.Error(), | ||
) | ||
return | ||
} | ||
|
||
// Read updated resource | ||
err := retry.RetryContext(ctx, 10*time.Minute, func() *retry.RetryError { | ||
readErr := r.config.OVHClient.Get(endpoint, &responseData) | ||
if readErr != nil { | ||
return retry.NonRetryableError(readErr) | ||
} | ||
|
||
if responseData.State.ValueString() == "ok" { | ||
return nil | ||
} | ||
|
||
return retry.RetryableError(errors.New("waiting for resource state to be ok")) | ||
}) | ||
|
||
if err != nil { | ||
resp.Diagnostics.AddError("error waiting status to be ok", err.Error()) | ||
return | ||
} | ||
|
||
responseData.MergeWith(&planData) | ||
|
||
// Save updated data into Terraform state | ||
resp.Diagnostics.Append(resp.State.Set(ctx, &responseData)...) | ||
} | ||
|
||
func (r *ipMitigationResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { | ||
var data IpMitigationModel | ||
|
||
// Read Terraform prior state data into the model | ||
resp.Diagnostics.Append(req.State.Get(ctx, &data)...) | ||
|
||
if resp.Diagnostics.HasError() { | ||
return | ||
} | ||
|
||
// Delete API call logic | ||
endpoint := "/ip/" + url.PathEscape(data.Ip.ValueString()) + "/mitigation/" + url.PathEscape(data.IpOnMitigation.ValueString()) | ||
if err := r.config.OVHClient.Delete(endpoint, nil); err != nil { | ||
resp.Diagnostics.AddError( | ||
fmt.Sprintf("Error calling Delete %s", endpoint), | ||
err.Error(), | ||
) | ||
} | ||
|
||
// Wait for resource to be removed | ||
err := retry.RetryContext(ctx, 10*time.Minute, func() *retry.RetryError { | ||
readErr := r.config.OVHClient.Get(endpoint, nil) | ||
if readErr != nil { | ||
if errOvh, ok := readErr.(*ovh.APIError); ok && errOvh.Code == 404 { | ||
return nil | ||
} else { | ||
return retry.NonRetryableError(readErr) | ||
} | ||
} | ||
|
||
return retry.RetryableError(errors.New("waiting for resource to be removed")) | ||
}) | ||
|
||
if err != nil { | ||
resp.Diagnostics.AddError("error verifying that resource was deleted", err.Error()) | ||
} | ||
} |
Oops, something went wrong.