Skip to content
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

Networking: add subnet name pattern to router's resource "external_fixed_ip" argument #1150

Closed
kayrus opened this issue Jan 29, 2021 · 0 comments · Fixed by #1151
Closed

Comments

@kayrus
Copy link
Collaborator

kayrus commented Jan 29, 2021

Affected Resource(s)

Please list the resources as a list, for example:

  • openstack_networking_router_v2
  • data.openstack_networking_subnet_v2

Debug Output

OpenStack Request URL: POST https://neutron.local/v2.0/routers
OpenStack Request Headers:
Accept: application/json
Cache-Control: no-cache
Content-Type: application/json
User-Agent: HashiCorp Terraform/0.13.2 (+https://www.terraform.io) Terraform Plugin SDK/1.16.0 gophercloud/2.0.0
X-Auth-Token: ***
2021/01/29 12:19:27 [DEBUG] OpenStack Request Body: {
  "router": {
    "external_gateway_info": {
      "external_fixed_ips": [
        {
          "subnet_id": "069c4312-639d-442b-8608-88931b2b043d"
        }
      ],
      "network_id": "f55c8e3d-c798-4c6c-9f7e-eeb6600f6aed"
    },
    "name": "my_router"
  }
}
OpenStack Response Code: 409
OpenStack Response Headers: 
Connection: keep-alive
Content-Length: 164
Content-Type: application/json
2021/01/29 12:19:31 [DEBUG] OpenStack Response Body: {
  "NeutronError": {
    "detail": "",
    "message": "No more IP addresses available on network f55c8e3d-c798-4c6c-9f7e-eeb6600f6aed.",
    "type": "IpAddressGenerationFailure"
  }
}

Expected Behavior

If a router create request gets 409 response code with a IpAddressGenerationFailure error type on a particular subnet, it should try with another subnet_id.

I expect to see something like this:

resource "openstack_networking_router_v2" "router_1" {
  name                = "my_router"
  external_network_id = "f55c8e3d-c798-4c6c-9f7e-eeb6600f6aed"

  external_subnet_ids = [
    "069c4312-639d-442b-8608-88931b2b043d".
    "169c4312-639d-442b-8608-88931b2b043d",
  ]
}

Actual Behavior

One FIP network can contain a private subnet and a public subnet. When a subnet is not specified as argument, router creation picks up a FIP subnet in a random manner.

When end user specifies a particular subnet, s/he cannot be sure that a particular external subnet is not exhausted, because an API call to get a FIP availability on a particular external subnet works only from the project scope the external network belongs to. Besides this call is very heavy and there may be a race condition, when FIP availability is close to 1.

It is also impossible to allocate a FIP in advance and specify it, because router's FIP is allocated on system level, and preallocated FIP will cause an error: {"NeutronError": {"message": "IP address 1.2.3.4 already allocated in subnet a75e0bf8-9bbe-4ae7-9cd0-e18ca8f08ad3", "type": "IpAddressAlreadyAllocated", "detail": ""}}

Therefore it makes sense to provide a list of external subnets to be used and iterate over them in case of 409 response code.

Steps to Reproduce

resource "openstack_networking_router_v2" "router_1" {
  name                = "my_router"
  external_network_id = "f55c8e3d-c798-4c6c-9f7e-eeb6600f6aed"
  external_fixed_ip {
    subnet_id = "069c4312-639d-442b-8608-88931b2b043d" # subnet with an exhausted FIPavailability
  }
}

Important Factoids

external_fixed_ip is a list, therefore it allows to specify multiple external subnets, but all of them will be applied on a router and a 409 response code can be related to one of these external_fixed_ip's. It is impossible to determine the subnet from a neutron error message, because it contains only the network ID, not a subnet.

My proposal is to introduce a read-only external_subnet_ids argument in a openstack_networking_router_v2 resource and mark it conflicting with an external_fixed_ip argument. This argument will be used only during the router creation.

If all tries fail with a 409, then a resource should return an error:

Error creating openstack_networking_router_v2: 2 subnets exhausted

To have a list of external subnets, we need to introduce the openstack_networking_network_ids_v2 data source like it is done for openstack_networking_port_ids_v2 or openstack_images_image_ids_v2. The openstack_networking_network_ids_v2 data source should be able to match subnet names by regexp, like it is already done in images_image_ids_v2.

References

Are there any other GitHub issues (open or closed) or Pull Requests that should be linked here? For example:

cc @dkistner @RaphaelVogel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant