heat_template_version: wallaby description: > OpenStack containerized Ironic Inspector service (EXPERIMENTAL) parameters: ContainerIronicInspectorImage: description: image type: string ContainerIronicInspectorConfigImage: description: The container image to use for the ironic_inspector config_volume type: string EndpointMap: default: {} description: Mapping of service endpoint -> protocol. Typically set via parameter_defaults in the resource registry. type: json ServiceNetMap: default: {} description: Mapping of service_name -> network name. Typically set via parameter_defaults in the resource registry. Use parameter_merge_strategies to merge it with the defaults. type: json ServiceData: default: {} description: Dictionary packing service data type: json RoleName: default: '' description: Role name on which the service is applied type: string RoleParameters: default: {} description: Parameters specific to the role type: json DeployIdentifier: default: '' type: string description: > Setting this to a unique value will re-run any deployment tasks which perform configuration on a Heat stack-update. IPAImageURLs: default: [] description: IPA image URLs, the format should be ["http://path/to/kernel", "http://path/to/ramdisk"] type: json MonitoringSubscriptionIronicInspector: default: 'overcloud-ironic-inspector' type: string KeystoneRegion: type: string default: 'regionOne' description: Keystone region for endpoint Debug: default: false description: Set to True to enable debugging on all services. type: boolean EnableSQLAlchemyCollectd: type: boolean description: > Set to true to enable the SQLAlchemy-collectd server plugin default: false IronicInspectorDiscoveryDefaultDriver: default: 'ipmi' description: | The default driver to use for newly discovered nodes (requires IronicInspectorEnableNodeDiscovery set to True). This driver is automatically added to enabled_drivers. type: string IronicInspectorEnableNodeDiscovery: default: false description: | Makes ironic-inspector enroll any unknown node that PXE-boots introspection ramdisk in Ironic. The default driver to use for new nodes is specified by the IronicInspectorDiscoveryDefaultDriver parameter. Introspection rules can also be used to specify it. type: boolean IronicInspectorCollectors: default: default,logs description: Comma-separated list of IPA inspection collectors type: string IronicInspectorExtraProcessingHooks: default: extra_hardware,lldp_basic,local_link_connection,physnet_cidr_map description: | Comma-separated list of processing hooks to append to the default list. type: string IronicInspectorInterface: default: br-ex description: | Network interface on which inspection dnsmasq will listen. Should allow access to untagged traffic from nodes booted for inspection. The default value only makes sense if you don't modify any networking configuration. type: string IronicInspectorIPXEEnabled: default: true description: Whether to use iPXE for inspection. type: boolean IronicInspectorKernelArgs: default: 'ipa-inspection-dhcp-all-interfaces=1 ipa-collect-lldp=1 ipa-debug=1' description: Kernel args for the Ironic inspector. type: string IronicInspectorIpRange: description: | DEPRECATED: Use IronicInspectorSubnets instead. Temporary IP range that will be given to nodes during the inspection process. This should not overlap with any range that Neutron's DHCP gives away, but it has to be routeable back to ironic-inspector API. This option has no meaningful defaults, and thus is required. type: string default: '' IronicInspectorSubnets: description: | Temporary IP ranges that will be given to nodes during the inspection process. This should not overlap with any range that Neutron's DHCP gives away, but they need to be routeable back to ironic-inspector API. This option has no meaningful defaults, and thus is required. List of dictionaries with keys: 'tag', 'ip_range', 'netmask', and 'gateway'. 'ip_range' is the only required key. Assigning multiple tagged subnets allow dnsmasq to serve dhcp request that came in via dhcp relay/helper. Example: - ip_range: 192.168.0.100,192.168.0.120 - ip_range: 192.168.1.100,192.168.1.200 netmask: 255.255.255.0 gateway: 192.168.1.254 tag: subnet1 NOTE: For HA deployments use disjoint address pools to avoid potential address conflict. Use the hostname (short form) of each instance that will run Ironic Inspector and define a dictionary with the disjoint ip ranges. Example HA deployment using disjoint address pools: overcloud-ironic-0: - ip_range: 192.168.24.100,192.168.24.119 - ip_range: 192.168.25.100,192.168.25.119 netmask: 255.255.255.0 gateway: 192.168.25.254 tag: subnet1 overcloud-ironic-1: - ip_range: 192.168.24.120,192.168.24.139 - ip_range: 192.168.25.120,192.168.25.139 netmask: 255.255.255.0 gateway: 192.168.25.254 tag: subnet1 type: json default: {} IronicInspectorUseSwift: default: true description: | DEPRECATED: Use IronicInspectorStorageBackend instead. Whether to use Swift for storing introspection data. type: boolean IronicInspectorStorageBackend: default: 'none' description: Storage backend for storing introspection data. type: string constraints: - allowed_values: ['none', 'swift', 'database'] IronicIPXEPort: default: 8088 description: Port to use for serving images when iPXE is used. type: string IronicPassword: description: The password for the Ironic service and db account, used by the Ironic services type: string hidden: true AdditionalArchitectures: default: [] description: List of additional architectures to enable. type: comma_delimited_list PortPhysnetCidrMap: default: {} description: | Mapping of IP subnet CIDR to physical network. When the physnet_cidr_map processing hook is enabled the physical_network property of baremetal ports is populated based on this mapping. Example: PortPhysnetCidrMap: '10.10.10.0/24': 'physnet_a' '2001:db8::/64': 'physnet_b' type: json parameter_groups: - label: deprecated description: | The following parameters are deprecated and will be removed. They should not be relied on for new deployments. If you have concerns regarding deprecated parameters, please contact the TripleO development team on IRC or the OpenStack mailing list. parameters: - IronicInspectorIpRange - IronicInspectorUseSwift conditions: use_swift: or: - {get_param: IronicInspectorUseSwift} - equals: [{get_param: IronicInspectorStorageBackend}, 'swift'] ironic_inspection_subnets_set: not: {equals : [{get_param: IronicInspectorSubnets}, {}]} enable_architecture_ppc64le: {contains: ['ppc64le', {get_param: AdditionalArchitectures}]} ipa_images: {not: {equals: [{get_param: IPAImageURLs}, []]}} resources: ContainersCommon: type: ../containers-common.yaml MySQLClient: type: ../database/mysql-client.yaml outputs: role_data: description: Role data for the Ironic Inspector role. value: service_name: ironic_inspector firewall_rules: '137 ironic-inspector': dport: - 5050 '137 ironic-inspector dhcp input': iniface: {get_param: IronicInspectorInterface} ipversion: 'ipv4' proto: 'udp' chain: 'INPUT' dport: 67 '137 ironic-inspector dhcp output': ipversion: 'ipv4' proto: 'udp' chain: 'OUTPUT' dport: 68 '137 ironic-inspector dhcpv6 input': iniface: {get_param: IronicInspectorInterface} ipversion: 'ipv6' proto: 'udp' chain: 'INPUT' dport: 547 '137 ironic-inspector dhcpv6 output': ipversion: 'ipv6' proto: 'udp' chain: 'OUTPUT' dport: 546 '137 ironic-inspector dhcpv6 relay output': ipversion: 'ipv6' proto: 'udp' chain: 'OUTPUT' dport: 547 keystone_resources: ironic-inspector: endpoints: public: {get_param: [EndpointMap, IronicInspectorPublic, uri]} internal: {get_param: [EndpointMap, IronicInspectorInternal, uri]} admin: {get_param: [EndpointMap, IronicInspectorAdmin, uri]} users: ironic-inspector: password: {get_param: IronicPassword} region: {get_param: KeystoneRegion} service: 'baremetal-introspection' monitoring_subscription: {get_param: MonitoringSubscriptionIronicInspector} config_settings: map_merge: - ironic::inspector::listen_address: str_replace: template: "%{hiera('$NETWORK')}" params: $NETWORK: {get_param: [ServiceNetMap, IronicInspectorNetwork]} ironic::inspector::dnsmasq_local_ip: str_replace: template: "%{hiera('$NETWORK')}" params: $NETWORK: {get_param: [ServiceNetMap, IronicInspectorNetwork]} tripleo::profile::base::ironic_inspector::inspection_subnets: if: - ironic_inspection_subnets_set - get_param: IronicInspectorSubnets - [{ip_range: {get_param: IronicInspectorIpRange}}] ironic::inspector::dnsmasq_interface: {get_param: IronicInspectorInterface} ironic::inspector::dnsmasq_dhcp_hostsdir: /var/lib/ironic-inspector/dhcp-hostsdir ironic::inspector::pxe_filter::dnsmasq::purge_dhcp_hostsdir: false ironic::inspector::pxe_filter::driver: dnsmasq ironic::inspector::logging::debug: {get_param: Debug} ironic::inspector::always_store_ramdisk_logs: {get_param: Debug} ironic::inspector::authtoken::www_authenticate_uri: {get_param: [EndpointMap, KeystoneInternal, uri] } ironic::inspector::authtoken::auth_url: {get_param: [EndpointMap, KeystoneInternal, uri_no_suffix]} ironic::inspector::authtoken::username: 'ironic' ironic::inspector::authtoken::password: {get_param: IronicPassword} ironic::inspector::authtoken::project_name: 'service' ironic::inspector::authtoken::user_domain_name: 'Default' ironic::inspector::authtoken::project_domain_name: 'Default' ironic::inspector::authtoken::region_name: {get_param: KeystoneRegion} ironic::inspector::authtoken::interface: 'internal' ironic::inspector::cors::allowed_origin: '*' ironic::inspector::cors::max_age: 3600 ironic::inspector::cors::allow_methods: 'GET,POST,PUT,DELETE,OPTIONS,PATCH' ironic::inspector::cors::allow_headers: 'Content-Type,Cache-Control,Content-Language,Expires,Last-Modified,Pragma,X-Auth-Token' ironic::inspector::cors::expose_headers: 'Content-Type,Cache-Control,Content-Language,Expires,Last-Modified,Pragma' ironic::inspector::ipxe_timeout: 60 ironic::inspector::ironic::username: 'ironic' ironic::inspector::ironic::password: {get_param: IronicPassword} ironic::inspector::ironic::project_name: 'service' ironic::inspector::ironic::auth_url: {get_param: [EndpointMap, KeystoneInternal, uri_no_suffix]} ironic::inspector::ironic::max_retries: 6 ironic::inspector::ironic::retry_interval: 10 ironic::inspector::ironic::user_domain_name: 'Default' ironic::inspector::ironic::project_domain_name: 'Default' ironic::inspector::ironic::region_name: {get_param: KeystoneRegion} ironic::inspector::http_port: {get_param: IronicIPXEPort} ironic::inspector::additional_processing_hooks: {get_param: IronicInspectorExtraProcessingHooks} ironic::inspector::ramdisk_collectors: {get_param: IronicInspectorCollectors} ironic::inspector::ramdisk_kernel_args: {get_param: IronicInspectorKernelArgs} ironic::inspector::port_physnet_cidr_map: {get_param: PortPhysnetCidrMap} ironic::inspector::db::database_connection: make_url: scheme: {get_param: [EndpointMap, MysqlInternal, protocol]} username: ironic-inspector password: {get_param: IronicPassword} host: {get_param: [EndpointMap, MysqlInternal, host]} path: /ironic-inspector query: if: - {get_param: EnableSQLAlchemyCollectd} - read_default_file: /etc/my.cnf.d/tripleo.cnf read_default_group: tripleo plugin: collectd collectd_program_name: ironic_inspector collectd_host: localhost - read_default_file: /etc/my.cnf.d/tripleo.cnf read_default_group: tripleo ironic::inspector::enable_ppc64le: if: - enable_architecture_ppc64le - true ironic::inspector::pxe_transfer_protocol: if: - {get_param: IronicInspectorIPXEEnabled} - 'http' - if: - use_swift - ironic::inspector::store_data: 'swift' ironic::inspector::swift::username: 'ironic' ironic::inspector::swift::password: {get_param: IronicPassword} ironic::inspector::swift::project_name: 'service' ironic::inspector::swift::auth_url: {get_param: [EndpointMap, KeystoneInternal, uri_no_suffix]} ironic::inspector::swift::user_domain_name: 'Default' ironic::inspector::swift::project_domain_name: 'Default' ironic::inspector::swift::region_name: {get_param: KeystoneRegion} - ironic::inspector::store_data: {get_param: IronicInspectorStorageBackend} - if: - {get_param: IronicInspectorEnableNodeDiscovery} - ironic::inspector::node_not_found_hook: 'enroll' ironic::inspector::discovery_default_driver: {get_param: IronicInspectorDiscoveryDefaultDriver} # Match what we do for Ironic containers - ironic::inspector::tftp_root: /var/lib/ironic/tftpboot ironic::inspector::http_root: /var/lib/ironic/httpboot service_config_settings: mysql: ironic::inspector::db::mysql::password: {get_param: IronicPassword} ironic::inspector::db::mysql::user: ironic-inspector ironic::inspector::db::mysql::host: {get_param: [EndpointMap, MysqlInternal, host_nobrackets]} ironic::inspector::db::mysql::dbname: ironic-inspector ironic::inspector::db::mysql::allowed_hosts: - '%' - "%{hiera('mysql_bind_host')}" # BEGIN DOCKER SETTINGS puppet_config: config_volume: ironic_inspector puppet_tags: ironic_inspector_config step_config: list_join: - "\n" - - include tripleo::profile::base::ironic_inspector - {get_attr: [MySQLClient, role_data, step_config]} config_image: {get_param: ContainerIronicInspectorConfigImage} volumes: - /var/lib/ironic:/var/lib/ironic:z - /var/lib/ironic-inspector/dhcp-hostsdir:/var/lib/ironic-inspector/dhcp-hostsdir:z kolla_config: /var/lib/kolla/config_files/ironic_inspector.json: command: /usr/bin/ironic-inspector --config-file /etc/ironic-inspector/inspector-dist.conf --config-file /etc/ironic-inspector/inspector.conf config_files: &ironic_inspector_config_files - source: "/var/lib/kolla/config_files/src/*" dest: "/" merge: true preserve_properties: true permissions: - path: /var/log/ironic-inspector owner: ironic-inspector:ironic-inspector recurse: true - path: /var/lib/ironic owner: ironic:ironic recurse: true - path: /var/lib/ironic-inspector/dhcp-hostsdir owner: ironic-inspector:ironic-inspector recurse: true /var/lib/kolla/config_files/ironic_inspector_dnsmasq.json: config_files: - source: "/var/lib/kolla/config_files/src/*" dest: "/" merge: true preserve_properties: true permissions: - path: /var/lib/ironic-inspector/dhcp-hostsdir owner: ironic-inspector:ironic-inspector recurse: true command: /sbin/dnsmasq --conf-file=/etc/ironic-inspector/dnsmasq.conf -k --log-facility=/var/log/ironic-inspector/dnsmasq.log /var/lib/kolla/config_files/ironic_inspector_db_sync.json: command: "/usr/bin/bootstrap_host_exec ironic_inspector su ironic-inspector -s /bin/bash -c 'ironic-inspector-dbsync --config-file /etc/ironic-inspector/inspector.conf upgrade'" config_files: *ironic_inspector_config_files permissions: - path: /var/log/ironic-inspector owner: ironic-inspector:ironic-inspector recurse: true docker_config: step_3: ironic_inspector_init_log: start_order: 0 image: &ironic_inspector_image get_param: ContainerIronicInspectorImage net: none user: root volumes: - /var/log/containers/ironic-inspector:/var/log/ironic-inspector:z command: ['/bin/bash', '-c', 'chown -R ironic-inspector:ironic-inspector /var/log/ironic-inspector'] ironic_inspector_init_dnsmasq_dhcp_hostsdir: start_order: 1 image: *ironic_inspector_image net: none user: root volumes: - /var/lib/ironic-inspector/dhcp-hostsdir:/var/lib/ironic-inspector/dhcp-hostsdir:shared,z command: ['/bin/bash', '-c', 'chown -R ironic-inspector:ironic-inspector /var/lib/ironic-inspector/dhcp-hostsdir'] ironic_inspector_db_sync: start_order: 2 image: *ironic_inspector_image net: host user: root privileged: false detach: false volumes: list_concat: - {get_attr: [ContainersCommon, volumes]} - - /var/lib/kolla/config_files/ironic_inspector_db_sync.json:/var/lib/kolla/config_files/config.json:ro - /var/lib/config-data/puppet-generated/ironic_inspector:/var/lib/kolla/config_files/src:ro - /var/log/containers/ironic-inspector:/var/log/ironic-inspector:z environment: KOLLA_CONFIG_STRATEGY: COPY_ALWAYS TRIPLEO_DEPLOY_IDENTIFIER: {get_param: DeployIdentifier} ironic_inspector_get_ipa: start_order: 2 image: *ironic_inspector_image net: host user: root privileged: false detach: false volumes: list_concat: - {get_attr: [ContainersCommon, volumes]} - - /var/lib/kolla/config_files/ironic_inspector.json:/var/lib/kolla/config_files/config.json:ro - /var/lib/ironic:/var/lib/ironic:shared,z environment: KOLLA_CONFIG_STRATEGY: COPY_ALWAYS command: if: - ipa_images - list_join: - " " - - "curl -g -o /var/lib/ironic/httpboot/agent.kernel" - {get_param: [IPAImageURLs, 0]} - "-o /var/lib/ironic/httpboot/agent.ramdisk" - {get_param: [IPAImageURLs, 1]} - 'true' step_4: ironic_inspector: start_order: 92 image: *ironic_inspector_image privileged: true net: host restart: always healthcheck: test: /openstack/healthcheck volumes: list_concat: - {get_attr: [ContainersCommon, volumes]} - - /var/lib/kolla/config_files/ironic_inspector.json:/var/lib/kolla/config_files/config.json:ro - /var/lib/config-data/puppet-generated/ironic_inspector:/var/lib/kolla/config_files/src:ro - /var/lib/ironic:/var/lib/ironic:shared,z - /var/log/containers/ironic-inspector:/var/log/ironic-inspector:z - /var/lib/ironic-inspector/dhcp-hostsdir:/var/lib/ironic-inspector/dhcp-hostsdir:shared,z environment: KOLLA_CONFIG_STRATEGY: COPY_ALWAYS ironic_inspector_dnsmasq: start_order: 93 image: *ironic_inspector_image privileged: true net: host restart: always user: root healthcheck: test: /openstack/healthcheck volumes: list_concat: - {get_attr: [ContainersCommon, volumes]} - - /var/lib/kolla/config_files/ironic_inspector_dnsmasq.json:/var/lib/kolla/config_files/config.json:ro - /var/lib/config-data/puppet-generated/ironic_inspector:/var/lib/kolla/config_files/src:ro - /var/log/containers/ironic-inspector:/var/log/ironic-inspector:z - /var/lib/ironic-inspector/dhcp-hostsdir:/var/lib/ironic-inspector/dhcp-hostsdir:shared,z environment: KOLLA_CONFIG_STRATEGY: COPY_ALWAYS host_prep_tasks: - name: create fcontext entry for ironic-inspector data community.general.sefcontext: target: "/var/lib/ironic-inspector/dhcp-hostsdir(/.*)?" setype: container_file_t state: present - name: create persistent directories file: path: "{{ item.path }}" state: directory setype: "{{ item.setype }}" mode: "{{ item.mode|default(omit) }}" with_items: - { 'path': /var/log/containers/ironic-inspector, 'setype': container_file_t, 'mode': '0750' } - { 'path': /var/lib/ironic-inspector/dhcp-hostsdir, 'setype': container_file_t } - name: create persistent ironic-inspector dnsmasq dhcp hostsdir file: path: /var/lib/ironic-inspector/dhcp-hostsdir state: directory setype: container_file_t # TODO(emilien): remove the cleanup tasks after Ussuri # https://bugs.launchpad.net/tripleo/+bug/1868934 - name: Cleanup unnecessary container config-data block: &ironic_config_data_cleanup - name: Remove /var/lib/config-data/puppet-generated/ironic_inspector/var file: path: /var/lib/config-data/puppet-generated/ironic_inspector/var state: absent upgrade_tasks: - name: Cleanup unnecessary container config-data when: - step|int == 0 tags: common block: *ironic_config_data_cleanup external_upgrade_tasks: - when: - step|int == 1 tags: - never - system_upgrade_transfer_data - system_upgrade_stop_services block: - name: Stop ironic inspector container import_role: name: tripleo_container_stop vars: tripleo_containers_to_stop: - ironic_inspector - ironic_inspector_dnsmasq tripleo_delegate_to: "{{ groups['ironic_inspector'] | default([]) }}"