From 7da7127071a33d2a5dcb750592c1fb9854bdbebb Mon Sep 17 00:00:00 2001 From: Cam Loader Date: Wed, 4 Sep 2019 21:36:30 -0500 Subject: [PATCH] Adds configuration for the Ironic Inspector This commit enables and configures the Ironic Inspector. This feature allows for baremetal nodes to be introspected. This provides useful information about an Ironic host. Such information includes harware and mac addresses. Depends-On: https://review.opendev.org/680553 Change-Id: I2ee09d9cc20f9b8e4430c55129cd8bac9435299d --- defaults/main.yml | 112 +++++++++++++++++- doc/source/configure-inspector.rst | 41 +++++++ doc/source/index.rst | 1 + files/rootwrap.d/ironic-utils.filters | 1 + handlers/main.yml | 6 + .../ironic-inspector-08b5189830698119.yaml | 6 + tasks/ironic_db_setup.yml | 9 ++ tasks/ironic_inspector_post_install.yml | 63 ++++++++++ tasks/ironic_post_install.yml | 13 ++ tasks/ironic_pre_install.yml | 17 ++- tasks/main.yml | 42 ++++--- templates/dhcpd.conf.j2 | 33 ++++++ templates/dnsmasq.conf.j2 | 15 +++ templates/inspector.conf.j2 | 101 ++++++++++++++++ templates/ironic.conf.j2 | 11 ++ templates/pxelinux-default.j2 | 8 ++ templates/sudoers.j2 | 1 + vars/debian.yml | 37 +++++- vars/main.yml | 112 ++++++++++++++++++ vars/redhat-7.yml | 27 ++++- vars/suse.yml | 27 ++++- 21 files changed, 659 insertions(+), 24 deletions(-) create mode 100644 doc/source/configure-inspector.rst create mode 100644 releasenotes/releasenotes/notes/ironic-inspector-08b5189830698119.yaml create mode 100644 tasks/ironic_inspector_post_install.yml create mode 100644 templates/dhcpd.conf.j2 create mode 100644 templates/dnsmasq.conf.j2 create mode 100644 templates/inspector.conf.j2 create mode 100644 templates/pxelinux-default.j2 diff --git a/defaults/main.yml b/defaults/main.yml index f7d37ed6..c16121ca 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -73,7 +73,11 @@ ironic_services: service_name: ironic-conductor init_config_overrides: "{{ ironic_conductor_init_config_overrides }}" execstarts: "{{ ironic_bin }}/ironic-conductor" - + ironic-inspector: + group: ironic_inspector + service_name: ironic-inspector + init_config_overrides: "{{ ironic_inspector_init_config_overrides }}" + execstarts: "{{ ironic_bin }}/ironic-inspector" ironic_service_name: ironic ironic_service_type: baremetal @@ -180,6 +184,7 @@ ironic_tftp_server_address: "{{ ansible_host }}" ironic_pip_packages: - cryptography - ironic + - "{{ (ironic_services['ironic-inspector']['group'] in group_names) | ternary('ironic-inspector', '') }}" - osprofiler - proliantutils - PyMySQL @@ -269,3 +274,108 @@ ironic_conductor_init_config_overrides: {} ironic_drivers_enabled: - agent_ipmitool - pxe_ipmitool + +ironic_inspector_developer_mode: false +ironic_inspector_venv_python_executable: "{{ openstack_venv_python_executable | default('python2') }}" + +# System info +ironic_inspector_service_setup_host: "{{ openstack_service_setup_host | default('localhost') }}" +ironic_inspector_lock_path: /var/lock/ironic-inspector + +ironic_inspector_service_name: ironic-inspector +ironic_inspector_service_type: baremetal-introspection +ironic_inspector_service_description: "Ironic Baremetal Introspection Service" +ironic_inspector_service_publicuri_proto: "{{ openstack_service_publicuri_proto | default(ironic_service_proto) }}" +ironic_inspector_service_adminuri_proto: "{{ openstack_service_adminuri_proto | default(ironic_service_proto) }}" +ironic_inspector_service_internaluri_proto: "{{ openstack_service_internaluri_proto | default(ironic_service_proto) }}" +ironic_inspector_service_port: 5050 +ironic_inspector_service_publicuri: "{{ ironic_inspector_service_publicuri_proto }}://{{ external_lb_vip_address }}:{{ ironic_inspector_service_port }}" +ironic_inspector_service_publicurl: "{{ ironic_inspector_service_publicuri }}" +ironic_inspector_service_adminuri: "{{ ironic_inspector_service_adminuri_proto }}://{{ internal_lb_vip_address }}:{{ ironic_inspector_service_port }}" +ironic_inspector_service_adminurl: "{{ ironic_inspector_service_adminuri }}" +ironic_inspector_service_internaluri: "{{ ironic_inspector_service_internaluri_proto }}://{{ internal_lb_vip_address }}:{{ ironic_inspector_service_port }}" +ironic_inspector_service_internalurl: "{{ ironic_inspector_service_internaluri }}" +ironic_inspector_service_role_name: "admin" +ironic_inspector_service_project_name: "service" +ironic_inspector_service_in_ldap: False +ironic_inspector_service_domain_id: default + +# Database +ironic_inspector_db_setup_host: "{{ ('galera_all' in groups) | ternary(groups['galera_all'][0], 'localhost') }}" +ironic_inspector_galera_address: "{{ galera_address | default('127.0.0.1') }}" +ironic_inspector_galera_user: ironic-inspector +ironic_inspector_galera_database: ironic_inspector + +# Ironic db tuning +ironic_inspector_db_max_overflow: 10 +ironic_inspector_db_max_pool_size: 120 +ironic_inspector_db_pool_timeout: 30 + +ironic_inspector_pip_install_args: "{{ pip_install_options | default('') }}" + + +# Auth +ironic_inspector_service_user_name: "ironic_inspector" + +### OpenStack Services to integrate with +# Ironic swift store information +ironic_inspector_swift_user_name: swift-inspector +ironic_inspector_swift_role_names: + - _member_ + - swiftoperator + +# Ironic inspector +ironic_inspector_enable_discovery: True +ironic_inspector_openstack_db_connection_string: "mysql+pymysql://{{ ironic_inspector_galera_user }}:{{ ironic_inspector_container_mysql_password }}@{{ ironic_inspector_galera_address }}/{{ ironic_inspector_galera_database }}" + +# Ironic inspector dhcp +ironic_inspector_dhcp_pool_range: 192.168.0.51 192.168.0.150 +ironic_inspector_dhcp_subnet: 192.168.0.0/22 +ironic_inspector_dhcp_subnet_mask: 255.255.252.0 +ironic_inspector_dhcp_gateway: 192.168.0.1 +ironic_inspector_dhcp_nameservers: 192.168.0.1 +ironic_inspector_dhcp_lease_time: 600 + +ironic_inspector_dhcp_type: dnsmasq # isc_dhcp +ironic_inspector_boot_mode: http #tftp +ironic_inspector_pxe_boot_mode: "{{ ironic_inspector_boot_mode }}" +ironic_inspector_httpboot_dir: /httpboot +ironic_inspector_tftpboot_dir: "{{ ironic_tftpd_root }}" + +ironic_inspector_dhcp_interface: br-ironic +ironic_inspector_valid_interfaces: internal,public + +### Config Overrides +ironic_inspector_conf_overrides: {} +ironic_inspector_rootwrap_conf_overrides: {} +ironic_inspector_init_config_overrides: {} +# pxe boot +ironic_inspector_pxe_append_params: "ipa-debug=1 systemd.journald.forward_to_console=yes" #ipa-inspection-collectors=default,logs,extra_hardware + +ironic_inspector_pxe_filter: dnsmasq #iptables + +ironic_inspector_oslomsg_rpc_host_group: "{{ oslomsg_rpc_host_group | default('rabbitmq_all') }}" +ironic_inspector_oslomsg_rpc_setup_host: "{{ (ironic_oslomsg_rpc_host_group in groups) | ternary(groups[ironic_oslomsg_rpc_host_group][0], 'localhost') }}" +ironic_inspector_oslomsg_rpc_transport: "{{ oslomsg_rpc_transport | default('rabbit') }}" +ironic_inspector_oslomsg_rpc_servers: "{{ oslomsg_rpc_servers | default('127.0.0.1') }}" +ironic_inspector_oslomsg_rpc_port: "{{ oslomsg_rpc_port | default('5672') }}" +ironic_inspector_oslomsg_rpc_use_ssl: "True" +ironic_inspector_oslomsg_rpc_userid: ironic +ironic_inspector_oslomsg_rpc_vhost: /ironic + +ironic_inspector_oslomsg_notify_host_group: "{{ oslomsg_notify_host_group | default('rabbitmq_all') }}" +ironic_inspector_oslomsg_notify_setup_host: "{{ (ironic_inspector_oslomsg_notify_host_group in groups) | ternary(groups[ironic_inspector_oslomsg_notify_host_group][0], 'localhost') }}" +ironic_inspector_oslomsg_notify_transport: "{{ oslomsg_notify_transport | default('rabbit') }}" +ironic_inspector_oslomsg_notify_servers: "{{ oslomsg_notify_servers | default('127.0.0.1') }}" +ironic_inspector_oslomsg_notify_port: "{{ oslomsg_notify_port | default('5672') }}" +ironic_inspector_oslomsg_notify_use_ssl: "False" +ironic_inspector_oslomsg_notify_userid: "{{ ironic_inspector_oslomsg_rpc_userid }}" +ironic_inspector_oslomsg_notify_password: "{{ ironic_oslomsg_rpc_password }}" +ironic_inspector_oslomsg_notify_vhost: "{{ ironic_inspector_oslomsg_rpc_vhost }}" +ironic_inspector_optional_oslomsg_amqp1_pip_packages: + - oslo.messaging[amqp1] +ironic_inspector_oslomsg_amqp1_enabled: True +ironic_inspector_upper_constraints_url: "{{ requirements_git_url | default('https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt?h=' ~ requirements_git_install_branch | default('master')) }}" + +ironic_inspector_ipa_initrd_name: ironic-deploy.initrd +ironic_inspector_ipa_kernel_name: ironic-deploy.kernel diff --git a/doc/source/configure-inspector.rst b/doc/source/configure-inspector.rst new file mode 100644 index 00000000..ca39a09a --- /dev/null +++ b/doc/source/configure-inspector.rst @@ -0,0 +1,41 @@ +================================================================ +Configuring the Bare Metal (ironic) inspector service (optional) +================================================================ + +.. note:: + + This feature is experimental at this time and it has not been fully + production tested yet. + +Ironic Inspector is an Ironic service that deploys a tiny image called +ironic-python-agent that gathers information about a Bare Metal node. The data +is then stored in the database for further use later. The node is then updated +with properties based in the introspection data. + +The inspector configuration requires some pre-deployment steps to allow the +Ironic playbook to make the inspector functioning. + +Networking +~~~~~~~~~~ +Ironic networking must be configured as normally done. The inspector and +Ironic will both share the TFTP server. + +Networking will depend heavily on your environment. For example, the DHCP for +both Ironic and inspector will come from the same subnet and will be a subset +of the typical ironic allocated range. + + +Required Overrides +~~~~~~~~~~~~~~~~~~ + .. code-block:: + + # names of your ironic-python-agent initrd/kernel images + ironic_inspector_ipa_initrd_name: ironic-deploy.initramfs + ironic_inspector_ipa_kernel_name: ironic-deploy.vmlinuz + + # dnsmasq/dhcp information for inspector + ironic_inspector_dhcp_pool_range: (subset of ironic IPs) + ironic_inspector_dhcp_subnet: + ironic_inspector_dhcp_subnet_mask: 255.255.252.0 + ironic_inspector_dhcp_gateway: + ironic_inspector_dhcp_nameservers: 8.8.8.8 diff --git a/doc/source/index.rst b/doc/source/index.rst index 33c6228d..473c425b 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -6,6 +6,7 @@ OpenStack-Ansible role for Bare Metal (ironic) service :maxdepth: 2 configure-ironic.rst + configure-inspector.rst This is an OpenStack-Ansible role to deploy the Bare Metal (ironic) service. See the `role-ironic spec`_ for more information. diff --git a/files/rootwrap.d/ironic-utils.filters b/files/rootwrap.d/ironic-utils.filters index ad7de6f0..6f185214 100644 --- a/files/rootwrap.d/ironic-utils.filters +++ b/files/rootwrap.d/ironic-utils.filters @@ -8,3 +8,4 @@ iscsiadm: CommandFilter, iscsiadm, root # ironic/common/utils.py mount: CommandFilter, mount, root umount: CommandFilter, umount, root +systemctl: CommandFilter, systemctl, root diff --git a/handlers/main.yml b/handlers/main.yml index cd6f2c0a..d0b4941e 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -46,3 +46,9 @@ name: "isc-dhcp-server" state: restarted failed_when: false + +- name: Restart dnsmasq + service: + name: "dnsmasq" + state: restarted + failed_when: false diff --git a/releasenotes/releasenotes/notes/ironic-inspector-08b5189830698119.yaml b/releasenotes/releasenotes/notes/ironic-inspector-08b5189830698119.yaml new file mode 100644 index 00000000..d8d73390 --- /dev/null +++ b/releasenotes/releasenotes/notes/ironic-inspector-08b5189830698119.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + This adds the configuration for the ironic inspector. The ironic + inspector provides useful information for baremetal nodes such as + hardware specs. diff --git a/tasks/ironic_db_setup.yml b/tasks/ironic_db_setup.yml index b0cf1cbc..c4f40c14 100644 --- a/tasks/ironic_db_setup.yml +++ b/tasks/ironic_db_setup.yml @@ -18,5 +18,14 @@ become: yes become_user: "{{ ironic_system_user_name }}" changed_when: false + when: inventory_hostname in groups['ironic_conductor'][0] + notify: + - Restart ironic services + +- name: Update database schema + command: "{{ ironic_bin }}/ironic-inspector-dbsync --config-file /etc/ironic-inspector/ironic-inspector.conf upgrade" + become: yes + changed_when: false + when: "'ironic_inspector' in groups and inventory_hostname == groups['ironic_inspector'][0]" notify: - Restart ironic services diff --git a/tasks/ironic_inspector_post_install.yml b/tasks/ironic_inspector_post_install.yml new file mode 100644 index 00000000..c32bdcbe --- /dev/null +++ b/tasks/ironic_inspector_post_install.yml @@ -0,0 +1,63 @@ +--- +# Copyright 2019, Rackspace US, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: Copy in dhcp config file + template: + src: "dhcpd.conf.j2" + dest: "/etc/dhcp/dhcpd.conf" + notify: + - Restart isc-dhcp-server + +- name: Ensure except lo dnsmasq setting + lineinfile: + path: /etc/default/dnsmasq + state: present + line: 'DNSMASQ_EXCEPT=lo' + when: ansible_os_family == 'Debian' + notify: + - Restart dnsmasq + +- name: Uncomment IGNORE_RESOLVCONF line + lineinfile: + path: /etc/default/dnsmasq + state: present + regexp: '^#IGNORE_RESOLVCONF=.*' + line: 'IGNORE_RESOLVCONF=yes' + backrefs: yes + when: ansible_os_family == 'Debian' + notify: + - Restart dnsmasq + +- name: Copy in dnsmqsq config file + template: + src: "dnsmasq.conf.j2" + dest: "/etc/dnsmasq.d/inspector-dnsmasq.conf" + notify: + - Restart dnsmasq + +- name: Default pxelinux.0 config + template: + src: pxelinux-default.j2 + dest: "{{ ironic_inspector_tftpboot_dir }}/pxelinux.cfg/default" + +- name: Create directories + file: + path: "{{ item }}" + state: directory + owner: "{{ ironic_system_user_name }}" + group: "{{ ironic_system_group_name }}" + mode: "0755" + with_items: + - /etc/dnsmasq.d/dhcp-hostsdir diff --git a/tasks/ironic_post_install.yml b/tasks/ironic_post_install.yml index 121f366a..7bf88ecb 100644 --- a/tasks/ironic_post_install.yml +++ b/tasks/ironic_post_install.yml @@ -92,6 +92,7 @@ mode: "0644" config_overrides: "{{ item.config_overrides }}" config_type: "{{ item.config_type }}" + when: item.condition | default(True) with_items: - src: "ironic.conf.j2" dest: "/etc/ironic/ironic.conf" @@ -103,6 +104,18 @@ group: "root" config_overrides: "{{ ironic_rootwrap_conf_overrides }}" config_type: "ini" + - src: "inspector.conf.j2" + dest: "/etc/ironic-inspector/ironic-inspector.conf" + config_overrides: "{{ ironic_inspector_conf_overrides }}" + config_type: "ini" + condition: inventory_hostname in groups['ironic-inspector'] + - src: "rootwrap.conf.j2" + dest: "/etc/ironic-inspector/rootwrap.conf" + owner: "root" + group: "root" + config_overrides: "{{ ironic_inspector_rootwrap_conf_overrides }}" + config_type: "ini" + condition: inventory_hostname in groups['ironic-inspector'] notify: Restart ironic services - name: Implement policy.json diff --git a/tasks/ironic_pre_install.yml b/tasks/ironic_pre_install.yml index 6b32cf9b..ee1894d7 100644 --- a/tasks/ironic_pre_install.yml +++ b/tasks/ironic_pre_install.yml @@ -29,7 +29,7 @@ - "{{ ironic_system_home_folder }}/.ssh/id_rsa.pub" when: ironic_recreate_keys | bool -- name: Create the ironic system user +- name: Create ironic system users user: name: "{{ ironic_system_user_name }}" group: "{{ ironic_system_group_name }}" @@ -47,16 +47,31 @@ owner: "{{ item.owner|default(ironic_system_user_name) }}" group: "{{ item.group|default(ironic_system_group_name) }}" mode: "{{ item.mode|default('0755') }}" + when: item.condition | default(True) with_items: - { path: "/openstack/venvs", mode: "0755", owner: "root", group: "root" } - { path: "/etc/ironic" } + - path: "/etc/ironic-inspector" + condition: inventory_hostname in groups['ironic-inspector'] - { path: "/etc/ironic/rootwrap.d" } + - path: "/etc/ironic-inspector/rootwrap.d" + condition: inventory_hostname in groups['ironic-inspector'] - { path: "/etc/sudoers.d", mode: "0750", owner: "root", group: "root" } - { path: "/var/cache/ironic" } + - path: "/var/cache/ironic-inspector" + condition: inventory_hostname in groups['ironic-inspector'] - { path: "{{ ironic_system_home_folder }}" } - { path: "{{ ironic_system_home_folder }}/.ssh", mode: "0700" } - { path: "{{ ironic_system_home_folder }}/images" } - { path: "{{ ironic_system_home_folder }}/master_images" } - { path: "{{ ironic_system_home_folder }}/cache/api", mode: "0700" } - { path: "{{ ironic_lock_path }}" } + - path: "{{ ironic_inspector_lock_path }}" + condition: inventory_hostname in groups['ironic-inspector'] - { path: "/var/run/ironic" } + - path: "/var/run/ironic-inspector" + condition: inventory_hostname in groups['ironic-inspector'] + - path: "{{ ironic_inspector_tftpboot_dir }}/pxelinux.cfg" + condition: inventory_hostname in groups['ironic-inspector'] + - path: "/httpboot" + condition: inventory_hostname in groups['ironic-inspector'] diff --git a/tasks/main.yml b/tasks/main.yml index 17d8059f..a949dab6 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -39,6 +39,21 @@ - common-db - ironic-config +- import_tasks: db_setup.yml + when: + - "ironic_services['ironic-inspector']['group'] in group_names" + - "inventory_hostname == ((groups[ironic_services['ironic-inspector']['group']]| intersect(ansible_play_hosts)) | list)[0]" + vars: + _oslodb_setup_host: "{{ ironic_inspector_db_setup_host }}" + _oslodb_databases: + - name: "{{ ironic_inspector_galera_database }}" + users: + - username: "{{ ironic_inspector_galera_user }}" + password: "{{ ironic_inspector_container_mysql_password }}" + tags: + - common-db + - ironic-config + - import_tasks: mq_setup.yml when: - "ironic_services['ironic-api']['group'] in group_names" @@ -100,7 +115,6 @@ - ironic-config - import_tasks: ironic_db_setup.yml - when: inventory_hostname == groups['ironic_conductor'][0] tags: - ironic-config @@ -130,24 +144,14 @@ _service_setup_host_python_interpreter: "{{ ironic_service_setup_host_python_interpreter }}" _service_project_name: "{{ ironic_service_project_name }}" _service_region: "{{ ironic_service_region }}" - _service_users: - - name: "{{ ironic_service_user_name }}" - password: "{{ ironic_service_password }}" - role: "{{ ironic_service_role_name }}" - _service_endpoints: - - service: "{{ ironic_service_name }}" - interface: "public" - url: "{{ ironic_service_publicurl }}" - - service: "{{ ironic_service_name }}" - interface: "internal" - url: "{{ ironic_service_internalurl }}" - - service: "{{ ironic_service_name }}" - interface: "admin" - url: "{{ ironic_service_adminurl }}" - _service_catalog: - - name: "{{ ironic_service_name }}" - type: "{{ ironic_service_type }}" - description: "{{ ironic_service_description }}" + _service_users: "{{ ironic_service_user_list }}" + _service_endpoints: "{{ ironic_service_endpoint_list }}" + _service_catalog: "{{ ironic_service_catalog_list }}" when: inventory_hostname == groups['ironic_api'][0] tags: - ironic-config + +- import_tasks: ironic_inspector_post_install.yml + when: "{{ inventory_hostname in groups['ironic_inspector'] }}" + tags: + - ironic-inspector diff --git a/templates/dhcpd.conf.j2 b/templates/dhcpd.conf.j2 new file mode 100644 index 00000000..ed9de9bc --- /dev/null +++ b/templates/dhcpd.conf.j2 @@ -0,0 +1,33 @@ + +ddns-update-style interim; + +allow booting; +allow bootp; + +ignore client-updates; +set vendorclass = option vendor-class-identifier; +option pxe-system-type code 93 = unsigned integer 16; +set pxetype = option pxe-system-type; + + +subnet {{ ironic_inspector_dhcp_subnet }} netmask {{ ironic_inspector_dhcp_subnet_mask }} { + option routers {{ ironic_inspector_dhcp_gateway }}; + option domain-name-servers {{ ironic_inspector_dhcp_nameservers}}; + option subnet-mask {{ ironic_inspector_dhcp_subnet_mask }}; + range dynamic-bootp {{ ironic_inspector_dhcp_pool_range }}; + default-lease-time {{ ironic_inspector_dhcp_lease_time }}; + max-lease-time 43200; + next-server {{ ironic_inspector_dhcp_interface }}; + class "pxeclients" { + match if substring (option vendor-class-identifier, 0, 9) = "PXEClient"; + if pxetype=6 or pxetype=7 { + filename "syslinux.efi"; + } else { +{% if ironic_inspector_boot_mode == "http" %} + filename "lpxelinux.0"; +{% else %} + filename "pxelinux.0"; +{% endif %} + } + } +} diff --git a/templates/dnsmasq.conf.j2 b/templates/dnsmasq.conf.j2 new file mode 100644 index 00000000..8a777269 --- /dev/null +++ b/templates/dnsmasq.conf.j2 @@ -0,0 +1,15 @@ +port=15553 +interface={{ ironic_inspector_dhcp_interface }} +dhcp-range={{ ironic_inspector_dhcp_pool_range | regex_replace(' ', ',') }} +tftp-root={{ ironic_inspector_tftpboot_dir }} +dhcp-option=3,{{ ironic_inspector_dhcp_gateway }} +dhcp-option=6,{{ ironic_inspector_dhcp_nameservers }} +dhcp-match=ipxe,175 +dhcp-match=set:efi,option:client-arch,7 +listen-address={{ ironic_inspector_dhcp_address }} +dhcp-match=set:efi,option:client-arch,9 +dhcp-match=set:efi,option:client-arch,11 +dhcp-boot=tag:efi,tag:!ipxe,ipxe.efi +dhcp-boot=pxelinux.0,localhost.localdomain,{{ ironic_tftp_server_address }} +conf-dir=/etc/dnsmasq.d/,*.conf +dhcp-hostsdir=/etc/dnsmasq.d/dhcp-hostsdir diff --git a/templates/inspector.conf.j2 b/templates/inspector.conf.j2 new file mode 100644 index 00000000..04e47bc3 --- /dev/null +++ b/templates/inspector.conf.j2 @@ -0,0 +1,101 @@ +# {{ ansible_managed }} + +[DEFAULT] +rootwrap_config = /etc/ironic-inspector/rootwrap.conf +auth_strategy = keystone +debug = {{ debug }} + +# RPC Backend +transport_url = {{ ironic_inspector_oslomsg_rpc_transport }}://{% for host in ironic_inspector_oslomsg_rpc_servers.split(',') %}{{ ironic_inspector_oslomsg_rpc_userid }}:{{ ironic_oslomsg_rpc_password }}@{{ host }}:{{ ironic_inspector_oslomsg_rpc_port }}{% if not loop.last %},{% else %}/{{ ironic_inspector_oslomsg_rpc_vhost }}{% if ironic_inspector_oslomsg_rpc_use_ssl | bool %}?ssl=1{% else %}?ssl=0{% endif %}{% endif %}{% endfor %} + +[capabilities] + +[cors] + +[database] +connection = {{ ironic_inspector_openstack_db_connection_string }} +max_overflow = {{ ironic_inspector_db_max_overflow }} +max_pool_size = {{ ironic_inspector_db_max_pool_size }} +pool_timeout = {{ ironic_inspector_db_pool_timeout }} + +[discovery] +enroll_node_driver = ipmi + + +[dnsmasq_pxe_filter] +{% if ironic_inspector_pxe_filter == "dnsmasq" %} +dhcp_hostsdir = /etc/dnsmasq.d/dhcp-hostsdir +dnsmasq_start_command = systemctl start dnsmasq +dnsmasq_stop_command = systemctl stop dnsmasq +{% endif %} + +[iptables] +{% if ironic_inspector_pxe_filter == "iptables" %} +manage_firewall = True +{% endif %} +dnsmasq_interface = br-ironic + +[ironic] +username = ironic +password = {{ ironic_service_password }} +project_name = service +user_domain_name = {{ ironic_service_user_domain_id }} +project_domain_name = {{ ironic_service_project_domain_id }} +auth_url = {{ keystone_service_adminurl }} +insecure = {{ keystone_service_adminuri_insecure | bool }} +auth_type = password +valid_interfaces = internal,public +insecure = {{ keystone_service_internaluri_insecure | bool }} + +[keystone_authtoken] +insecure = {{ keystone_service_internaluri_insecure | bool }} +auth_type = password +auth_url = {{ keystone_service_adminuri }} +auth_uri = {{ keystone_service_internaluri }} +project_domain_id = default +user_domain_id = default +project_name = "service" +username = ironic_inspector +password = {{ ironic_inspector_service_password }} +region_name = {{ keystone_service_region }} +memcached_servers = {{ memcached_servers }} +# if your memcached server is shared, use these settings to avoid cache poisoning +memcache_security_strategy = ENCRYPT +memcache_secret_key = {{ memcached_encryption_key }} + +[oslo_policy] + +[pci_devices] + +[processing] +add_ports = pxe +keep_ports = present +store_data = database +store_data_location = report_path +ramdisk_logs_dir = /ironic/log +always_store_ramdisk_logs = true +{% if ironic_inspector_processing_hooks is defined %} +processing_hooks = {{ ironic_inspector_processing_hooks }} +{% endif %} +{% if ironic_inspector_enable_discovery == true %} +node_not_found_hook = enroll +{% endif %} + +[pxe_filter] +{% if ironic_inspector_dhcp_type == "isc_dhcp" %} +driver = iptables +{% else %} +driver = dnsmasq +{% endif %} + +[swift] +username = swift-inspector +password = {{ ironic_inspector_swift_password }} +project_name = ironic-inspector +user_domain_name = default +project_domain_name = default +auth_url = {{ keystone_service_adminurl }} +insecure = {{ keystone_service_adminuri_insecure | bool }} +auth_type = password +valid_interfaces = internal,public +container = ironic-inspector diff --git a/templates/ironic.conf.j2 b/templates/ironic.conf.j2 index 101bc3ae..d1410d67 100644 --- a/templates/ironic.conf.j2 +++ b/templates/ironic.conf.j2 @@ -98,6 +98,17 @@ use_web_server_for_images = True {% endif %} [inspector] +{% if ironic_services['ironic-inspector']['group'] in group_names %} +auth_type = {{ ironic_keystone_auth_plugin }} +auth_url = {{ keystone_service_adminuri }} +insecure = {{ keystone_service_internaluri_insecure | bool }} +password = {{ ironic_inspector_service_password }} +project_domain_name = {{ ironic_inspector_service_domain_id }} +project_name ={{ ironic_inspector_service_project_name }} +user_domain_name = {{ ironic_inspector_service_domain_id }} +username = {{ ironic_inspector_service_user_name }} +valid_interfaces = {{ ironic_inspector_valid_interfaces }} +{% endif %} [ipmi] diff --git a/templates/pxelinux-default.j2 b/templates/pxelinux-default.j2 new file mode 100644 index 00000000..f5c0f25e --- /dev/null +++ b/templates/pxelinux-default.j2 @@ -0,0 +1,8 @@ +default inspect + +label inspect +kernel {{ ironic_inspector_ipa_kernel_name }} +append initrd={{ ironic_inspector_ipa_initrd_name }} ipa-inspection-callback-url=http://{{ internal_lb_vip_address }}:5050/v1/continue nomodeset vga=normal console=tty0 console=ttyS0,115200n8 {{ ironic_inspector_pxe_append_params | default('') }} +ipappend 3 + + diff --git a/templates/sudoers.j2 b/templates/sudoers.j2 index 497f3892..ca9b4a58 100644 --- a/templates/sudoers.j2 +++ b/templates/sudoers.j2 @@ -4,3 +4,4 @@ Defaults:{{ ironic_system_user_name }} !requiretty Defaults:{{ ironic_system_user_name }} secure_path="{{ ironic_bin }}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" {{ ironic_system_user_name }} ALL = (root) NOPASSWD: {{ ironic_bin }}/{{ ironic_service_name }}-rootwrap +{{ ironic_system_user_name }} ALL = (root) NOPASSWD: {{ ironic_bin }}/{{ ironic_inspector_service_name }}-rootwrap diff --git a/vars/debian.yml b/vars/debian.yml index 3214b3d2..8d252460 100644 --- a/vars/debian.yml +++ b/vars/debian.yml @@ -36,7 +36,6 @@ ironic_conductor_distro_packages: - open-iscsi - ipmitool - tftpd-hpa - - gdisk ironic_conductor_standalone_distro_packages: - isc-dhcp-server @@ -48,3 +47,39 @@ ironic_library_modules_paths: ironic_tftpd_service_name: tftpd-hpa ironic_tftpd_root: /tftpboot + +ironic_inspector_distro_packages: + - libxml2-dev + - pxelinux + - syslinux + - syslinux-common + - syslinux-efi + - libxslt1-dev + - libpq-dev + - python-yaml + - ipmitool + +ironic_inspector_http_distro_packages: + - nginx + +ironic_inspector_isc_dhcp_distro_packages: + - tftpd-hpa + - isc-dhcp-server + +ironic_inspector_dnsmasq_distro_packages: + - dnsmasq + +ironic_inspector_standalone_distro_packages: + - isc-dhcp-server + +ironic_inspector_devel_distro_packages: + - git-core + - libffi-dev + - libsystemd-dev + +ironic_inspector_library_modules_paths: + - "/usr/lib/PXELINUX/pxelinux.0" + - "/usr/lib/PXELINUX/lpxelinux.0" + - "/usr/lib/syslinux/modules/efi64/chain.c32" + - "/usr/lib/syslinux/modules/bios/ldlinux.c32" + - "/usr/lib/syslinux/modules/efi64/ldlinux.e64" diff --git a/vars/main.yml b/vars/main.yml index 84992350..9099c10f 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -148,8 +148,120 @@ ironic_packages_list: > {%- set package_list = package_list + ironic_conductor_standalone_distro_packages %} {%- endif %} {%- endif %} + {%- if ironic_inspector_dhcp_type == "dnsmasq" %} + {%- set package_list = package_list + ironic_inspector_dnsmasq_distro_packages %} + {%- else %} + {%- set package_list = package_list + ironic_inspector_isc_dhcp_distro_packages %} + {%- endif %} + {%- if ironic_inspector_boot_mode == "http" %} + {%- set package_list = package_list + ironic_inspector_http_distro_packages %} + {%- endif %} {{- package_list -}} +ironic_service_user_list: > + {%- set service_user_list = [] %} + {%- if ironic_services['ironic-api']['group'] in group_names %} + {%- set _ = service_user_list.append( + { + 'name': ironic_service_user_name, + 'password': ironic_service_password, + 'role': ironic_service_role_name + } + ) + %} + {%- endif %} + {%- if ironic_services['ironic-inspector']['group'] in group_names %} + {%- set _ = service_user_list.append( + { + 'name': ironic_inspector_service_user_name, + 'password': ironic_inspector_service_password, + 'role': ironic_inspector_service_role_name + } + ) + %} + {%- endif %} + {{- service_user_list -}} + +ironic_service_endpoint_list: > + {%- set service_endpoint_list = [] %} + {%- if ironic_services['ironic-api']['group'] in group_names %} + {%- set _ = service_endpoint_list.append( + { + 'service': ironic_service_name, + 'interface': 'public', + 'url': ironic_service_publicurl + } + ) + %} + {%- set _ = service_endpoint_list.append( + { + 'service': ironic_service_name, + 'interface': 'internal', + 'url': ironic_service_internalurl + } + ) + %} + {%- set _ = service_endpoint_list.append( + { + 'service': ironic_service_name, + 'interface': 'admin', + 'url': ironic_service_adminurl + } + ) + %} + {%- endif %} + {%- if inventory_hostname in groups['ironic_inspector'] %} + {%- set _ = service_endpoint_list.append( + { + 'service': ironic_inspector_service_name, + 'interface': 'public', + 'url': ironic_inspector_service_publicurl + } + ) + %} + {%- set _ = service_endpoint_list.append( + { + 'service': ironic_inspector_service_name, + 'interface': 'internal', + 'url': ironic_inspector_service_internalurl + } + ) + %} + {%- set _ = service_endpoint_list.append( + { + 'service': ironic_inspector_service_name, + 'interface': 'admin', + 'url': ironic_inspector_service_adminurl + } + ) + %} + {%- endif %} + {{- service_endpoint_list -}} + +ironic_service_catalog_list: > + {%- set service_catalog_list = [] %} + {%- if ironic_services['ironic-api']['group'] in group_names %} + {%- set _ = service_catalog_list.append( + { + 'name': ironic_service_name, + 'type': ironic_service_type, + 'description': ironic_service_description + } + ) + %} + {%- endif %} + {%- if inventory_hostname in groups['ironic_inspector'] %} + {%- set _ = service_catalog_list.append( + { + 'name': ironic_inspector_service_name, + 'type': ironic_inspector_service_type, + 'description': ironic_inspector_service_description + } + ) + %} + {%- endif %} + {{- service_catalog_list -}} + filtered_ironic_services: |- {% set services = [] %} {% for key, value in ironic_services.items() %} diff --git a/vars/redhat-7.yml b/vars/redhat-7.yml index b43494a4..c73540c5 100644 --- a/vars/redhat-7.yml +++ b/vars/redhat-7.yml @@ -36,7 +36,6 @@ ironic_conductor_distro_packages: - iscsi-initiator-utils - ipmitool - tftp-server - - gdisk ironic_conductor_standalone_distro_packages: - isc-dhcp-server @@ -48,3 +47,29 @@ ironic_library_modules_paths: ironic_tftpd_service_name: tftp ironic_tftpd_root: /var/lib/tftpboot + +ironic_inspector_http_distro_packages: + - nginx + +ironic_inspector_isc_dhcp_distro_packages: + - tftpd-hpa + - isc-dhcp-server + +ironic_inspector_dnsmasq_distro_packages: + - dnsmasq + +ironic_inspector_standalone_distro_packages: + - isc-dhcp-server + +ironic_inspector_devel_distro_packages: + - git-core + - libffi-dev + - libsystemd-dev + +ironic_inspector_library_modules_paths: + - "/usr/lib/PXELINUX/pxelinux.0" + - "/usr/lib/PXELINUX/lpxelinux.0" + - "/usr/lib/syslinux/modules/efi64/chain.c32" + - "/usr/lib/syslinux/modules/bios/ldlinux.c32" + - "/usr/lib/SYSLINUX.EFI/efi64/syslinux.efi" + - "/usr/lib/syslinux/modules/efi64/ldlinux.e64" diff --git a/vars/suse.yml b/vars/suse.yml index f80b8e18..056722c0 100644 --- a/vars/suse.yml +++ b/vars/suse.yml @@ -35,7 +35,6 @@ ironic_conductor_distro_packages: - qemu-tools - syslinux - tftp - - gptfdisk ironic_conductor_standalone_distro_packages: - dhcp-server @@ -47,3 +46,29 @@ ironic_library_modules_paths: ironic_tftpd_service_name: tftp ironic_tftpd_root: /srv/tftpboot + +ironic_inspector_http_distro_packages: + - nginx + +ironic_inspector_isc_dhcp_distro_packages: + - tftpd-hpa + - isc-dhcp-server + +ironic_inspector_dnsmasq_distro_packages: + - dnsmasq + +ironic_inspector_standalone_distro_packages: + - isc-dhcp-server + +ironic_inspector_devel_distro_packages: + - git-core + - libffi-dev + - libsystemd-dev + +ironic_inspector_library_modules_paths: + - "/usr/lib/PXELINUX/pxelinux.0" + - "/usr/lib/PXELINUX/lpxelinux.0" + - "/usr/lib/syslinux/modules/efi64/chain.c32" + - "/usr/lib/syslinux/modules/bios/ldlinux.c32" + - "/usr/lib/SYSLINUX.EFI/efi64/syslinux.efi" + - "/usr/lib/syslinux/modules/efi64/ldlinux.e64"