Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions components/ironic/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,9 @@ pod:
- name: ironic-inspection-rules
mountPath: /etc/ironic/inspection-rules/
readOnly: true
- name: panos-credentials

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Credentials should not arrive as files mounted from a Secret. ironic_understack/conf/__init__.py already registers an ironic_understack option group via setup_conf(), and these belong there as cfg.StrOpt with secret=True so they stay out of logs and config dumps.

That drops this mount and volume, the /etc/panos-credentials path handling in panos_inspect.validate(), and the cross-package credential() call. It also closes a gap this PR leaves open: nothing in the tree creates the panos-credentials Secret, while every other external secret here is provisioned through an ExternalSecret.

mountPath: /etc/panos-credentials
readOnly: true
volumes:
- name: dnsmasq-ironic
persistentVolumeClaim:
Expand All @@ -279,6 +282,11 @@ pod:
configMap:
name: ironic-inspection-rules
optional: true
- name: panos-credentials
secret:
secretName: panos-credentials
defaultMode: 0400
optional: true
replicas:
api: 4
conductor: 1
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# 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.
"""PAN-OS Hardware Type for Palo Alto firewalls."""

from ironic.drivers import generic
from ironic.drivers.modules import noop
from ironic.drivers.modules.network import neutron
from ironic.drivers.modules.storage import noop as noop_storage

from ironic_understack.drivers import panos_inspect
from ironic_understack.drivers import panos_management


class PanosHardware(generic.ManualManagementHardware):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bf0df36f added a paloalto hardware type for this same device class, after this branch was cut, so merging this as-is leaves two non-interchangeable driver names for the same appliances. Rather than carry both, we will rename paloalto over to panos and this PR should build on the renamed type.

That also removes most of this file. PaloAltoHardware is a thin NetdevHardware subclass, and PanosHardware here is a near-verbatim copy of NetdevHardware that differs only in the inspect and management interfaces. Please subclass NetdevHardware and override supported_inspect_interfaces and supported_management_interfaces only; every other property in this file is already inherited.

The rename needs a note in docs/design-guide/ironic.md, which currently documents netdev only, and we should confirm whether any node already carries driver=paloalto before the rename lands.

"""Hardware type for Palo Alto (PAN-OS) firewalls.

Intended for nodes that represent Palo Alto firewall appliances
(PA-1410, PA-5410, etc.). These devices:
- Have no deploy ramdisk
- Are managed via PAN-OS XML API
- Use Neutron for network port binding
- Require custom inspect and management interfaces

All other interfaces (boot, power, deploy, raid, etc.) use no-op

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This says boot, power, deploy and raid "use no-op implementations", then says two lines down that boot and power are inherited and use FakePower. The second statement is the correct one — Ironic has no NoBoot or NoPower, and the inherited boot interfaces are iPXE/PXE, which also contradicts the "Have no deploy ramdisk" bullet above. netdev_hardware.py words this accurately and is worth copying verbatim.

implementations since they don't apply to firewall appliances.

Boot and power are inherited from ManualManagementHardware, which
uses FakePower (power state controlled by manual operator) since
there's no automated power management for these devices.
"""

@property
def supported_bios_interfaces(self):
"""No BIOS on firewall appliances."""
return [noop.NoBIOS]

@property
def supported_console_interfaces(self):
"""Console access not supported via Ironic for PAN-OS."""
return [noop.NoConsole]

@property
def supported_deploy_interfaces(self):
"""No image deployment for firewall appliances."""
return [noop.NoDeploy]

@property
def supported_firmware_interfaces(self):
"""Firmware updates handled separately."""
return [noop.NoFirmware]

@property
def supported_inspect_interfaces(self):
"""Use custom PAN-OS inspect interface for hardware discovery."""
return [panos_inspect.PanosInspect]

@property
def supported_management_interfaces(self):
"""Use custom PAN-OS management interface for lifecycle operations."""
return [panos_management.PanosManagement]

@property
def supported_network_interfaces(self):
"""Use Neutron for network port binding."""
return [neutron.NeutronNetwork]

@property
def supported_raid_interfaces(self):
"""No RAID on firewall appliances."""
return [noop.NoRAID]

@property
def supported_rescue_interfaces(self):
"""Rescue mode not applicable to firewall appliances."""
return [noop.NoRescue]

@property
def supported_storage_interfaces(self):
"""No storage management for firewall appliances."""
return [noop_storage.NoopStorage]

@property
def supported_vendor_interfaces(self):
"""No vendor-specific passthrough needed."""
return [noop.NoVendor]
Loading
Loading