]> git.apps.os.sepia.ceph.com Git - ceph-cm-ansible.git/commitdiff
Add dhcp-server role
authorDavid Galloway <dgallowa@redhat.com>
Thu, 29 Mar 2018 20:01:47 +0000 (16:01 -0400)
committerDavid Galloway <dgallowa@redhat.com>
Tue, 3 Apr 2018 16:03:33 +0000 (12:03 -0400)
Signed-off-by: David Galloway <dgallowa@redhat.com>
dhcp-server.yml [new file with mode: 0644]
roles/dhcp-server/README.rst [new file with mode: 0644]
roles/dhcp-server/tasks/main.yml [new file with mode: 0644]
roles/dhcp-server/templates/dhcpd.conf.j2 [new file with mode: 0644]
roles/dhcp-server/templates/dhcpd.subnet.conf.j2 [new file with mode: 0644]

diff --git a/dhcp-server.yml b/dhcp-server.yml
new file mode 100644 (file)
index 0000000..3240ff7
--- /dev/null
@@ -0,0 +1,5 @@
+---
+- hosts: dhcp_server
+  roles:
+    - dhcp-server
+  become: true
diff --git a/roles/dhcp-server/README.rst b/roles/dhcp-server/README.rst
new file mode 100644 (file)
index 0000000..251dfbe
--- /dev/null
@@ -0,0 +1,92 @@
+dhcp-server
+===========
+
+This role can be used to install, update, and manage a DHCP server running on CentOS 7.
+
+Notes
++++++
+
+This role is heavily modified to be primarily useful for our test labs that only have two or three subnets.  See https://wiki.sepia.ceph.com/doku.php?id=services:networking.
+
+This role checks for firewalld and iptables.  It will configure firewalld unless iptables is running.  It **does not** configure iptables.  At the time the role was created, our DHCP server was running other services and its iptables was already heavily modified and configured.  This reason, along with firewalld being the default in CentOS 7, is why iptables configuration is skipped.
+
+Variables
++++++++++
+This role basically has two required and two optional variables:
+
++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **Required Variables**                                                                                                                                                                                                                                                                                                                 |
++---------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+|::                                                                   | This list will be used to populate the global ``/etc/dhcpd.conf``.  You can add additional keys and values.  Just make sure they follow the syntax required for dhcpd.conf.                                                                                      |
+|                                                                     |                                                                                                                                                                                                                                                                  |
+|  dhcp_global_options:                                               |                                                                                                                                                                                                                                                                  |
+|    - ddns-update-style: none                                        | Here's the dhcpd_ man page.                                                                                                                                                                                                                                      |
+|    - default-lease-time: 43200                                      |                                                                                                                                                                                                                                                                  |
+|    - max-lease-time: 172800                                         |                                                                                                                                                                                                                                                                  |
+|    - one-lease-per-client: "true"                                   |                                                                                                                                                                                                                                                                  |
+|                                                                     |                                                                                                                                                                                                                                                                  |
++---------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+|::                                                                   | This is large dictionary that gets parsed out into individual dhcpd config files.  Each top-level key (``front`` and ``ipmi`` in the example) will get its own dhcp conf file created.  The example shown to the left is our actual ``dhcp_subnets`` dictionary. |
+|                                                                     |                                                                                                                                                                                                                                                                  |
+|  dhcp_subnets:                                                      |                                                                                                                                                                                                                                                                  |
+|    front:                                                           | Under each subnet, ``cidr``, ``ipvar``, and ``macvar`` are required.  ``ipvar`` and ``macvar`` tell the Jinja2 template which IP address and MAC address should be used for each host in each subnet config file.                                                |
+|      cidr: 172.21.0.0/20                                            |                                                                                                                                                                                                                                                                  |
+|      ipvar: ip                                                      | Here's a line from our Ansible inventory host file                                                                                                                                                                                                               |
+|      macvar: mac                                                    |                                                                                                                                                                                                                                                                  |
+|      domain_name: front.sepia.ceph.com                              | ``smithi001.front.sepia.ceph.com mac=0C:C4:7A:BD:15:E8 ip=172.21.15.1 ipmi=172.21.47.1 bmc=0C:C4:7A:6E:21:A7``                                                                                                                                                   |
+|      domain_search:                                                 |                                                                                                                                                                                                                                                                  |
+|        - front.sepia.ceph.com                                       | This will result in a static IP entry for smithi001-front with IP 172.21.15.1 and MAC 0C:C4:7A:BD:15:E8 in ``dhcpd.front.conf`` and a smithi001-ipmi entry with IP 172.21.47.1 with MAC 0C:C4:7A:6E:21:A7 in ``dhcpd.ipmi.conf``.                                |
+|        - sepia.ceph.com                                             |                                                                                                                                                                                                                                                                  |
+|      domain_name_server:                                            | The ``next_server`` and ``filename`` values can be overridden by ansible group or host.  See below.                                                                                                                                                              |
+|        - 172.21.0.1                                                 |                                                                                                                                                                                                                                                                  |
+|        - 172.21.0.2                                                 | All the other keys are optional.                                                                                                                                                                                                                                 |
+|      routers: 172.21.15.254                                         |                                                                                                                                                                                                                                                                  |
+|      next_server: 172.21.0.11                                       |                                                                                                                                                                                                                                                                  |
+|      filename: "/pxelinux.0"                                        |                                                                                                                                                                                                                                                                  |
+|      classes:                                                       |                                                                                                                                                                                                                                                                  |
+|        virtual: "match if substring(hardware, 0, 4) = 01:52:54:00"  |                                                                                                                                                                                                                                                                  |
+|        lxc: "match if substring(hardware, 0, 4) = 01:52:54:ff"      |                                                                                                                                                                                                                                                                  |
+|      pools:                                                         |                                                                                                                                                                                                                                                                  |
+|        virtual:                                                     |                                                                                                                                                                                                                                                                  |
+|          range: 172.21.10.20 172.21.10.250                          |                                                                                                                                                                                                                                                                  |
+|        unknown_clients:                                             |                                                                                                                                                                                                                                                                  |
+|          range:                                                     |                                                                                                                                                                                                                                                                  |
+|            - 172.21.11.0 172.21.11.19                               |                                                                                                                                                                                                                                                                  |
+|            - 172.21.13.170 172.21.13.250                            |                                                                                                                                                                                                                                                                  |
+|          next_server: 172.21.0.11                                   |                                                                                                                                                                                                                                                                  |
+|          filename: "/pxelinux.0"                                    |                                                                                                                                                                                                                                                                  |
+|        lxc:                                                         |                                                                                                                                                                                                                                                                  |
+|          range: 172.21.14.1 172.21.14.200                           |                                                                                                                                                                                                                                                                  |
+|    ipmi:                                                            |                                                                                                                                                                                                                                                                  |
+|      cidr: 172.21.32.0/20                                           |                                                                                                                                                                                                                                                                  |
+|      ipvar: ipmi                                                    |                                                                                                                                                                                                                                                                  |
+|      macvar: bmc                                                    |                                                                                                                                                                                                                                                                  |
+|      domain_name: ipmi.sepia.ceph.com                               |                                                                                                                                                                                                                                                                  |
+|      domain_search:                                                 |                                                                                                                                                                                                                                                                  |
+|        - ipmi.sepia.ceph.com                                        |                                                                                                                                                                                                                                                                  |
+|        - sepia.ceph.com                                             |                                                                                                                                                                                                                                                                  |
+|      domain_name_servers:                                           |                                                                                                                                                                                                                                                                  |
+|        - 172.21.0.1                                                 |                                                                                                                                                                                                                                                                  |
+|        - 172.21.0.2                                                 |                                                                                                                                                                                                                                                                  |
+|      routers: 172.21.47.254                                         |                                                                                                                                                                                                                                                                  |
+|      next_server: 172.21.0.11                                       |                                                                                                                                                                                                                                                                  |
+|      filename: "/pxelinux.0"                                        |                                                                                                                                                                                                                                                                  |
+|      pools:                                                         |                                                                                                                                                                                                                                                                  |
+|        unknown_clients:                                             |                                                                                                                                                                                                                                                                  |
+|          range: 172.21.43.1 172.21.43.100                           |                                                                                                                                                                                                                                                                  |
+|          next_server: 172.21.0.11                                   |                                                                                                                                                                                                                                                                  |
+|          filename: "/pxelinux.0"                                    |                                                                                                                                                                                                                                                                  |
+|                                                                     |                                                                                                                                                                                                                                                                  |
++---------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| **Optional Variables**                                                                                                                                                                                                                                                                                                                 |
++---------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| ``dhcp_next_server: 1.2.3.4``                                       | This is your PXE/TFTP server's IP address.  This will **override** the subnet's ``next_server`` defined in the ``dhcp_subnets`` dictionary.  It can be defined in your Ansible inventory in a couple ways:                                                       |
+|                                                                     |                                                                                                                                                                                                                                                                  |
+|                                                                     | #. In ``ansible/inventory/group_vars/group.yml`` if some hosts should use a different PXE server                                                                                                                                                                 |
+|                                                                     | #. In your inventory ``hosts`` file on a per-host basis.  See Ansible's docs_ on variable precedence.                                                                                                                                                            |
++---------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| ``dhcp_filename: "/pxelinux.0"``                                    | Same rules as above.  This is the TFTP filename the DHCP server should instruct DHCP clients to download.                                                                                                                                                        |
++---------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+.. _docs: https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable
+.. _dhcpd: https://linux.die.net/man/8/dhcpd
diff --git a/roles/dhcp-server/tasks/main.yml b/roles/dhcp-server/tasks/main.yml
new file mode 100644 (file)
index 0000000..73fbe03
--- /dev/null
@@ -0,0 +1,59 @@
+---
+- name: Install/update packages
+  yum:
+    name: dhcp
+    state: latest
+  register: dhcp_yum_transaction
+
+- name: Check for firewalld
+  command: firewall-cmd --state
+  register: firewalld_state
+  ignore_errors: true
+
+- name: Check for iptables
+  command: systemctl status iptables
+  register: iptables_state
+  ignore_errors: true
+
+- name: Make sure firewalld is running
+  service:
+    name: firewalld
+    state: started
+    enabled: yes
+  when: iptables_state.rc != 0
+
+- name: Configure firewalld
+  firewalld:
+    service: dhcp
+    state: enabled
+    permanent: true
+    immediate: yes
+  when: iptables_state.rc != 0
+
+- name: Write global dhcpd.conf
+  template:
+    src: dhcpd.conf.j2
+    dest: /etc/dhcp/dhcpd.conf
+    backup: yes
+  register: dhcp_global_config
+
+- name: Write each subnet config
+  template:
+    src: dhcpd.subnet.conf.j2
+    dest: "/etc/dhcp/dhcpd.{{ item }}.conf"
+    backup: yes
+  with_items: "{{ dhcp_subnets }}"
+  register: dhcp_subnet_config
+
+- name: Test new config
+  command: dhcpd -t -cf /etc/dhcp/dhcpd.conf
+  register: dhcpd_config_test_result
+  when: dhcp_global_config|changed or dhcp_subnet_config|changed
+
+- name: Restart dhcpd
+  service:
+    name: dhcpd
+    state: restarted
+  when:
+    - dhcpd_config_test_result is defined
+    - dhcpd_config_test_result.rc == 0
diff --git a/roles/dhcp-server/templates/dhcpd.conf.j2 b/roles/dhcp-server/templates/dhcpd.conf.j2
new file mode 100644 (file)
index 0000000..26fe125
--- /dev/null
@@ -0,0 +1,9 @@
+{% for item in dhcp_global_options %}
+{% for key, value in item.items() %}
+{{ key }} {{ value }};
+{% endfor %}
+{% endfor %}
+
+{% for key, value in dhcp_subnets.iteritems() %}
+include "/etc/dhcp/dhcpd.{{ key }}.conf";
+{% endfor %}
diff --git a/roles/dhcp-server/templates/dhcpd.subnet.conf.j2 b/roles/dhcp-server/templates/dhcpd.subnet.conf.j2
new file mode 100644 (file)
index 0000000..89816ff
--- /dev/null
@@ -0,0 +1,70 @@
+{% for subnet, subnet_item in dhcp_subnets.iteritems() %}
+{% if subnet == item %}
+subnet {{ subnet_item.cidr | ipaddr('network') }} netmask {{ subnet_item.cidr | ipaddr('netmask') }} {
+  {% if subnet_item.domain_name is defined -%}
+  option domain-name           "{{ subnet_item.domain_name }}";
+  {% endif -%}
+  {% if subnet_item.domain_search is defined -%}
+  option domain-search         "{{ subnet_item.domain_search|join('", "') }}";
+  {% endif -%}
+  {% if subnet_item.domain_name_servers is defined -%}
+  option domain-name-servers   {{ subnet_item.domain_name_servers|join(', ') }};
+  {% endif -%}
+  {% if subnet_item.routers is defined -%}
+  option routers               {{ subnet_item.routers }};
+  {% endif -%}
+  {% if subnet_item.next_server is defined -%}
+  next-server                  {{ subnet_item.next_server }};
+  {% endif -%}
+  {% if subnet_item.filename is defined -%}
+  filename                     "{{ subnet_item.filename }}";
+  {% endif %}
+
+  {% if subnet_item.classes is defined -%}
+  {% for class_name, class_string in subnet_item.classes.items() -%}
+  class "{{ class_name }}" {
+    {{ class_string }};
+  }
+
+  {% endfor -%}
+  {%- endif -%}
+
+  {% if subnet_item.pools is defined -%}
+  {% for pool, pool_value in subnet_item.pools.items() -%}
+  pool {
+    {% if pool == "unknown_clients" -%}
+    allow unknown-clients;
+    {% else -%}
+    allow members of "{{ pool }}";
+    {% endif -%}
+    {% if pool_value.range is string -%}
+    range {{ pool_value.range }};
+    {% else -%}
+    range {{ pool_value.range|join(';\n    range ') }};
+    {% endif -%}
+    {% if pool_value.next_server is defined -%}
+    next-server {{ pool_value.next_server }};
+    {% endif -%}
+    {% if pool_value.filename is defined -%}
+    filename "{{ pool_value.filename }}";
+    {% endif -%}
+  }
+
+  {% endfor -%}
+  {%- endif -%}
+
+  {% for host in groups['all'] | sort | unique -%}
+  {% if hostvars[host][subnet_item.macvar] is defined -%}
+  host {{ host.split('.')[0] }}-{{ subnet }} {
+    {% if hostvars[host]['dhcp_next_server'] is defined -%}
+    next-server {{ hostvars[host]['dhcp_next_server'] }};
+    filename "{{ hostvars[host]['dhcp_filename'] }}";
+    {% endif -%}
+    hardware ethernet {{ hostvars[host][subnet_item.macvar] }};
+    fixed-address {{ hostvars[host][subnet_item.ipvar] }};
+  }
+  {% endif -%}
+  {% endfor -%}
+} # end subnet
+{% endif %}
+{% endfor %}