Neutron/enable-to-set-dhcp-port-attributes

Background and motivation
There is no way for a user to specify an ip address (, mac address and so on) of a DHCP port. This is very inconvenient for a user who wishes to fully control over ip address assignment.

This blueprint is based on such actual user's requirement.

Use cases
Use case1

When a user migrates their on-premises system to a cloud environment, there are cases where the user wants to use the same ip address for their virtual servers. In such a case, the user needs to specify an ip address of the DHCP server to avoid conflict with an existing servers' ip address.

Use case2

A user wants to specify an ip address of a DHCP server for security reasons. They don't want DHCP servers to float around.

Goal
The goal of this blueprint is to enable users to explicitly set DCHP port attributes (especially ip address).

Proposal
Add 'dhcp_port' parameter to "dhcp-agent-network-add" API. If 'dhcp_port' parameter is specified, a DHCP port is created at the same time. A user who wants to control a DCHP port attributes must assign a dhcp-agent explicitly. I think this restriction will not be an issue for such users.

Proposed API
Add 'dhcp_port' input parameter to "dhcp-agent-network-add" API provided by the "dhcpagentscheduler" extension.

action: POST url: /agents/ /networks request body: {'network_id': } {'network_id': , 'dhcp_port': {'fixed_ips':, 'mac_address': , 'name': }}
 * current
 * new

note:'dhcp_port' is optional. 'fixed_ips', 'mac_address' and 'name' in 'dhcp_port' are optional. the format of 'fixed_ips' is same as port resource.

response body: none

description:

Assign the dhcp-agent specified by to the network specified by . If 'dhcp_port' is specified the DHCP port is created using the specified attributes.

example of request body: {'network_id': "df514142-90f4-4ab2-8d35-aaaf0b5c4dee", 'dhcp_port': {'fixed_ips': [{'subnet_id': "fd3bc91d-70e5-4325-8f19-c52f2998953e", 'ip_address': "20.0.0.10"}]}}

Current implementation

 * A DHCP port is identified by "device_id" and "device_owner".

"device_id" is generated by network_id for the port and dhcp_agent's host. (i.e. unique with network_id and dhcp_agent's host pair) "device_owner" is "network:dhcp".


 * A DHCP port is created via "create_dhcp_port" RPC call by a dhcp_agent, if the port does not exist yet.


 * A DHCP port creation is triggered by assigning a dhcp_agent to a network. There are two typical cases.

1) explicit assignment via API (eg. when the "neutron dhcp-agent-network-add" CLI is executed.)

2) the first port creation of a network (with one or more dhcp-enabled subnet). if the network is not assigned to a dhcp_agent yet, force dhcp-agent scheduling is done.

(note: Thus if a user want to assign a dhcp_agent to a network explicitly, issue "dhcp-agent-network-add" API before the first port creation.)

Other possible options for this blueprint
There are several implementation options to achieve the goal other than our proposal.

Add 'dhcp_ips' attribute to the subnet. (note that it must be a list since multiple dhcp-agent can be assigned to a network) When create_dhcp_port is called, one of the unused ip address in the list is used. Disadvantage of this option is that it needs a large amount of code addition/modification.
 * option 1

Create a DHCP port explicitly by a user specifying 'device_id' and 'device_owner' attributes before dhcp-agent assignment to a network. There are two issues for this option.
 * option 2

1) how to generate 'device_id' is not open.

2) a port creation forces dhcp-agent scheduling. A dhcp-agent other than the dhcp-agent represented by specified 'device_id' may be assigned. On the other hand assigning dhcp-agent before creating port causes DHCP port creation by create_dhcp_port RPC call by a dhcp-agent.

Our proposal solves those issues and we believe is the best solution for implementing this blueprint.

CLI
'dhcp-ip' option is added to "neutron dhcp-agent-network-add" CLI. Usage of dhcp-agent-network-add sub command is as follows: usage: neutron dhcp-agent-network-add [-h] [--request-format {json,xml}] [--dhcp-ip ip_address=IP_ADDR] dhcp_agent network Add a network to a DHCP agent. positional arguments: dhcp_agent           ID of the DHCP agent network              Network to add optional arguments: -h, --help           show this help message and exit --request-format {json,xml} The xml or json request format --dhcp-ip ip_address=IP_ADDR Desired IP for dhcp port: subnet_id=,ip_address=, (This option                        can be repeated.)

For example: neutron dhcp-agent-network-add --dhcp-ip subnet_id=sub1,ip_address=10.0.0.10 76bf2562-2926-412f-92d0-a71f837c8839 net1

If you want to specify name or mac_address of the port 'values_specs' can be used.

For example: neutron dhcp-agent-network-add --dhcp-ip subnet_id=sub1,ip_address=10.0.0.10 76bf2562-2926-412f-92d0-a71f837c8839 net1 --dhcp_port type=dict name=dhcp1,mac_address=ae:04:0f:ac:17:4c

Note that dhcp-ip option is necessary since 'fixed_ips' attribute of port can not be specified by using 'values_specs'.

Options for 'mac_address' and 'name' are not made since they are low priority and they can be specified by using 'values_specs'.