-
Notifications
You must be signed in to change notification settings - Fork 134
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
feat(ip) - add ovh_ip_move resource to move an IP to a provided service name or park it if no service name given #510
Conversation
77809da
to
b429575
Compare
Personal opinion, but I feel that naming could be improved. Move is an action verb. It doesn't feel right once it is applied. What about something like |
The naming of the resource and datasource depends of the API endpoint you call :-)
So, depending of the API scheme, |
b429575
to
e8c2bdc
Compare
e8c2bdc
to
edfe5f0
Compare
ovh/resource_ip_move.go
Outdated
const taskExpiresAfter = 300 * time.Second | ||
|
||
// WaitingTimeInSecondsBeforeRefreshState number if seconds to wait before making a new API call to refresh ip task state | ||
const WaitingTimeInSecondsBeforeRefreshState = 10 |
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.
const WaitingTimeInSecondsBeforeRefreshState = 10 | |
const waitingTimeInSecondsBeforeRefreshState = 10 |
I think it doesn't need to be exported
ovh/resource_ip_move.go
Outdated
config := meta.(*Config) | ||
ip := d.Get("ip").(string) | ||
|
||
// no need to update if ip is already routed to the appropriate service |
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.
comment does not seem related to the code ? (from what I understand FromResource
func doesn't check that)
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.
right, check is done later down the road.
will move comment to l163
|
||
endpoint := fmt.Sprintf("/ip/%s/task/%d", | ||
url.PathEscape(d.Get("ip").(string)), | ||
ipTask.TaskId, |
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.
needs to be url.PathEscape
'd
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.
but ipTask.TaskId is an int64, not a string (see %d formatter)
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.
my bad, read too fast :)
if timeDiff < taskExpiresAfter { | ||
log.Printf("[DEBUG] ipTask.Status is currently: %s. Waiting %d second (we allow %f more seconds for the task to complete)", ipTask.Status, WaitingTimeInSecondsBeforeRefreshState, taskExpiresAfter.Seconds()-timeDiff.Seconds()) | ||
time.Sleep(WaitingTimeInSecondsBeforeRefreshState * time.Second) | ||
err = resourceIpTaskRead(d, ipTask, meta) |
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.
I think this error should be checked and we should return immediately if it's not nil: if the task doesn't exist anymore for example, I think we shouldn't retry.
What do you think ?
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.
in some instances such as a gone task it might make sense to indeed return error immediately. We can possibly do this by verifying ipTask
nill
ity at the very beginning of recursiveWaitTaskFinished
, which would achieve a similar behavior
In other cases though (network error, temporary server error, etc...) stopping the whole plan is not relevant nor wanted, and we would rather retry recursively
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.
seems ok as a workaround, but IMO a better solution is to verify the error response like it's done in func resourceIpServiceReadByServiceName
(with type assertion err.(*ovh.APIError)
+ status check)
ovh/resource_ip_move.go
Outdated
func waitForTaskFinished(d *schema.ResourceData, meta interface{}, ipTask *IpTask, ip string, opts *IpMoveOpts) (finishedWithSuccess *bool, err error) { | ||
defer func() { | ||
errSet := d.Set("task_status", ipTask.Status) | ||
if errSet == 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.
shouldn't it be != nil
instead ? Otherwise you will hide the underlying error, for example in case your task has a status IpTaskStatusOvhError
.
Additionally, it would be preferable to avoid this defer to ease readability :)
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.
I will replace the whole method body to the following as I realize that go 1.20 introduced a way of joining errors, which is actually what I was ultimately willing to achieve so we are aware of both potential Set error and/or recursiveWaitTaskFinished() error
finishedWithSuccess, err = recursiveWaitTaskFinished(d, meta, ipTask, ip, opts)
errSet := d.Set("task_status", ipTask.Status)
return finishedWithSuccess, errors.Join(err, errSet)
website/docs/r/ip_move.html.markdown
Outdated
* `organisation_id` - IP block organisation Id | ||
* `routed_to` - Routage information | ||
* `service_name` - Service where ip is routed to | ||
* `service_name`: service name in the form of `ip-<part-1>.<part-2>.<part-3>.<part-4>` |
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.
* `service_name`: service name in the form of `ip-<part-1>.<part-2>.<part-3>.<part-4>` | |
* `service_name`: Service name in the form of `ip-<part-1>.<part-2>.<part-3>.<part-4>` |
website/docs/r/ip_move.html.markdown
Outdated
* `can_be_terminated` - can be terminated | ||
* `country` - country | ||
* `description` - description attached to the IP | ||
* `ip` - ip block |
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.
* `ip` - ip block | |
* `ip` - IP block |
website/docs/r/ip_move.html.markdown
Outdated
|
||
* `can_be_terminated` - can be terminated | ||
* `country` - country | ||
* `description` - description attached to the IP |
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.
* `description` - description attached to the IP | |
* `description` - Description attached to the IP |
website/docs/r/ip_move.html.markdown
Outdated
Attributes are mostly the same as for [ovh_ip_service](https://registry.terraform.io/providers/ovh/ovh/latest/docs/resources/ip_service#attributes-reference): | ||
|
||
* `can_be_terminated` - can be terminated | ||
* `country` - country |
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.
* `country` - country | |
* `country` - Country |
website/docs/r/ip_move.html.markdown
Outdated
|
||
Attributes are mostly the same as for [ovh_ip_service](https://registry.terraform.io/providers/ovh/ovh/latest/docs/resources/ip_service#attributes-reference): | ||
|
||
* `can_be_terminated` - can be terminated |
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.
* `can_be_terminated` - can be terminated | |
* `can_be_terminated` - Whether IP service can be terminated |
a9ff432
to
5e4f2b9
Compare
if timeDiff < taskExpiresAfter { | ||
log.Printf("[DEBUG] ipTask.Status is currently: %s. Waiting %d second (we allow %f more seconds for the task to complete)", ipTask.Status, WaitingTimeInSecondsBeforeRefreshState, taskExpiresAfter.Seconds()-timeDiff.Seconds()) | ||
time.Sleep(WaitingTimeInSecondsBeforeRefreshState * time.Second) | ||
err = resourceIpTaskRead(d, ipTask, meta) |
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.
seems ok as a workaround, but IMO a better solution is to verify the error response like it's done in func resourceIpServiceReadByServiceName
(with type assertion err.(*ovh.APIError)
+ status check)
final request, can you add a pipeline in https://github.com/ovh/terraform-provider-ovh/blob/master/.cds/terraform-provider-ovh.yml ? So that your test is run in the CI |
…park it if no service name given taken resource ID is the move task ID if available, or the IP itself otherwise Moving/parking process: - if there is an IpTask recorded in the resource state, we try to wait for it to be finished until it is considered expired - after having waited until previosu task expiration or completion, do the move only if the current service is different from the one given in the inputs add acceptance test that checks attaching IP to a service then detaching it
5e4f2b9
to
26baa44
Compare
22298fb
to
cfde916
Compare
Description
This adds a new add
ovh_ip_move
resource to move an IP to a provided service name or park it if empty service is given.It relies on the following APIV6 routes:
taken resource ID is the move task ID if available, or the IP itself otherwise
Moving/parking process:
Type of change
How Has This Been Tested?
Test Configuration:
terraform version
: Terraform v1.2.9Attaching an IP to a service
Then parking the same IP
Checklist: