diff --git a/internal/blueprint/customizations.go b/internal/blueprint/customizations.go index a528ab68f..1dfdb53c9 100644 --- a/internal/blueprint/customizations.go +++ b/internal/blueprint/customizations.go @@ -74,11 +74,11 @@ type LocaleCustomization struct { type FirewallCustomization struct { Ports []string `json:"ports,omitempty" toml:"ports,omitempty"` Services *FirewallServicesCustomization `json:"services,omitempty" toml:"services,omitempty"` - Sources []FirewallSourceCustomization `json:"sources,omitempty" toml:"sources,omitempty"` + Zones []FirewallZoneCustomization `json:"zones,omitempty" toml:"zones,omitempty"` } -type FirewallSourceCustomization struct { - Zone string `json:"zone,omitempty" toml:"zone,omitempty"` +type FirewallZoneCustomization struct { + Name *string `json:"name,omitempty" toml:"name,omitempty"` Sources []string `json:"sources,omitempty" toml:"sources,omitempty"` } diff --git a/internal/distro/rhel8/pipelines.go b/internal/distro/rhel8/pipelines.go index 5348f5e2e..f7a2d363b 100644 --- a/internal/distro/rhel8/pipelines.go +++ b/internal/distro/rhel8/pipelines.go @@ -497,12 +497,12 @@ func osPipeline(t *imageType, // merge the user-provided firewall config with the default one if fwStageOptions != nil { fwStageOptions = &osbuild.FirewallStageOptions{ - // Prefer the firewall ports, services and sources settings provided + // Prefer the firewall ports, services and zone settings provided // via BP customization. Ports: fwStageOptions.Ports, EnabledServices: fwStageOptions.EnabledServices, DisabledServices: fwStageOptions.DisabledServices, - Sources: fwStageOptions.Sources, + Zones: fwStageOptions.Zones, // Default zone can not be set using BP customizations, therefore // default to the one provided in the default image configuration. DefaultZone: firewallConfig.DefaultZone, diff --git a/internal/distro/rhel8/stage_options.go b/internal/distro/rhel8/stage_options.go index 0d001038e..d653e8823 100644 --- a/internal/distro/rhel8/stage_options.go +++ b/internal/distro/rhel8/stage_options.go @@ -76,11 +76,11 @@ func firewallStageOptions(firewall *blueprint.FirewallCustomization) *osbuild.Fi options.DisabledServices = firewall.Services.Disabled } - if len(firewall.Sources) != 0 { - for _, s := range firewall.Sources { - options.Sources = append(options.Sources, osbuild.FirewallSource{ - Zone: s.Zone, - Sources: s.Sources, + if len(firewall.Zones) != 0 { + for _, z := range firewall.Zones { + options.Zones = append(options.Zones, osbuild.FirewallZone{ + Name: *z.Name, + Sources: z.Sources, }) } } diff --git a/internal/distro/rhel9/images.go b/internal/distro/rhel9/images.go index e6fad1dc5..09e9377c6 100644 --- a/internal/distro/rhel9/images.go +++ b/internal/distro/rhel9/images.go @@ -65,6 +65,7 @@ func osCustomizations( osc.DefaultTarget = *imageConfig.DefaultTarget } + osc.Firewall = imageConfig.Firewall if fw := c.GetFirewall(); fw != nil { options := osbuild.FirewallStageOptions{ Ports: fw.Ports, @@ -74,11 +75,11 @@ func osCustomizations( options.EnabledServices = fw.Services.Enabled options.DisabledServices = fw.Services.Disabled } - if fw.Sources != nil { - for _, s := range fw.Sources { - options.Sources = append(options.Sources, osbuild.FirewallSource{ - Zone: s.Zone, - Sources: s.Sources, + if fw.Zones != nil { + for _, z := range fw.Zones { + options.Zones = append(options.Zones, osbuild.FirewallZone{ + Name: *z.Name, + Sources: z.Sources, }) } } @@ -163,7 +164,6 @@ func osCustomizations( osc.RHSMConfig = imageConfig.RHSMConfig osc.Subscription = options.Subscription osc.WAAgentConfig = imageConfig.WAAgentConfig - osc.Firewall = imageConfig.Firewall osc.UdevRules = imageConfig.UdevRules osc.GCPGuestAgentConfig = imageConfig.GCPGuestAgentConfig diff --git a/internal/osbuild/firewall_stage.go b/internal/osbuild/firewall_stage.go index bc384ae68..2ed28ec23 100644 --- a/internal/osbuild/firewall_stage.go +++ b/internal/osbuild/firewall_stage.go @@ -1,20 +1,33 @@ package osbuild +import "fmt" + type FirewallStageOptions struct { - Ports []string `json:"ports,omitempty"` - EnabledServices []string `json:"enabled_services,omitempty"` - DisabledServices []string `json:"disabled_services,omitempty"` - DefaultZone string `json:"default_zone,omitempty"` - Sources []FirewallSource `json:"sources,omitempty"` + Ports []string `json:"ports,omitempty"` + EnabledServices []string `json:"enabled_services,omitempty"` + DisabledServices []string `json:"disabled_services,omitempty"` + DefaultZone string `json:"default_zone,omitempty"` + Zones []FirewallZone `json:"zones,omitempty"` } -type FirewallSource struct { - Zone string `json:"zone,omitempty"` +type FirewallZone struct { + Name string `json:"name,omitempty"` Sources []string `json:"sources,omitempty"` } func (FirewallStageOptions) isStageOptions() {} +func (o FirewallStageOptions) validate() error { + if len(o.Zones) != 0 { + for _, fz := range o.Zones { + if fz.Name == "" || len(fz.Sources) == 0 { + return fmt.Errorf("items in firewall Zones cannot be empty, provide a non-empty 'Name' and a list of 'Sources'") + } + } + } + return nil +} + func NewFirewallStage(options *FirewallStageOptions) *Stage { return &Stage{ Type: "org.osbuild.firewall", diff --git a/internal/osbuild/firewall_stage_test.go b/internal/osbuild/firewall_stage_test.go index 89fa2776c..e4e64b4e3 100644 --- a/internal/osbuild/firewall_stage_test.go +++ b/internal/osbuild/firewall_stage_test.go @@ -14,3 +14,14 @@ func TestNewFirewallStage(t *testing.T) { actualFirewall := NewFirewallStage(&FirewallStageOptions{}) assert.Equal(t, expectedFirewall, actualFirewall) } + +func TestFirewallStageZones_ValidateInvalid(t *testing.T) { + options := FirewallStageOptions{} + var sources []string + options.Zones = append(options.Zones, FirewallZone{ + Name: "", + Sources: sources, + }) + assert := assert.New(t) + assert.Error(options.validate()) +}