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"