Skip to content

Commit 2af62fd

Browse files
committed
Allow specifying an initial firewall ruleset.
This is handy for the capi-provider.
1 parent 91feb1f commit 2af62fd

File tree

2 files changed

+65
-11
lines changed

2 files changed

+65
-11
lines changed

api/v2/types_firewall.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ type FirewallSpec struct {
7474
// EgressRules contains egress rules configured for this firewall.
7575
EgressRules []EgressRuleSNAT `json:"egressRules,omitempty"`
7676

77+
// InitialRuleSet is the initial firewall ruleset applied before the firewall-controller starts running.
78+
InitialRuleSet *InitialRuleSet `json:"initialRuleSet,omitempty"`
79+
7780
// Interval on which rule reconciliation by the firewall-controller should happen.
7881
Interval string `json:"interval,omitempty"`
7982
// DryRun if set to true, firewall rules are not applied. For devel-purposes only.
@@ -122,6 +125,33 @@ type FirewallTemplateSpec struct {
122125
Spec FirewallSpec `json:"spec,omitempty"`
123126
}
124127

128+
// InitialRuleSet is the initial rule set deployed on the firewall.
129+
type InitialRuleSet struct {
130+
Egress []EgressRule
131+
Ingress []IngressRule
132+
}
133+
134+
type NetworkProtocol string
135+
136+
const (
137+
NetworkProtocolTCP = "TCP"
138+
NetworkProtocolUDP = "UDP"
139+
)
140+
141+
type EgressRule struct {
142+
Comment string
143+
Ports []int32
144+
Protocol NetworkProtocol
145+
To []string
146+
}
147+
148+
type IngressRule struct {
149+
Comment string
150+
Ports []int32
151+
Protocol NetworkProtocol
152+
From []string
153+
}
154+
125155
// EgressRuleSNAT holds a Source-NAT rule
126156
type EgressRuleSNAT struct {
127157
// NetworkID is the network for which the egress rule will be configured.

controllers/firewall/reconcile.go

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -142,18 +142,42 @@ func (c *controller) createFirewall(r *controllers.Ctx[*v2.Firewall]) (*models.V
142142
tags = append(tags, v2.FirewallSetTag(ref.Name))
143143
}
144144

145+
var rules *models.V1FirewallRules
146+
if r.Target.Spec.InitialRuleSet != nil {
147+
rules = &models.V1FirewallRules{}
148+
149+
for _, rule := range r.Target.Spec.InitialRuleSet.Egress {
150+
rules.Egress = append(rules.Egress, &models.V1FirewallEgressRule{
151+
Comment: rule.Comment,
152+
Ports: rule.Ports,
153+
Protocol: string(rule.Protocol),
154+
To: rule.To,
155+
})
156+
}
157+
158+
for _, rule := range r.Target.Spec.InitialRuleSet.Ingress {
159+
rules.Ingress = append(rules.Ingress, &models.V1FirewallIngressRule{
160+
Comment: rule.Comment,
161+
From: rule.From,
162+
Ports: rule.Ports,
163+
Protocol: string(rule.Protocol),
164+
})
165+
}
166+
}
167+
145168
createRequest := &models.V1FirewallCreateRequest{
146-
Description: "created by firewall-controller-manager",
147-
Name: r.Target.Name,
148-
Hostname: r.Target.Name,
149-
Sizeid: &r.Target.Spec.Size,
150-
Projectid: &r.Target.Spec.Project,
151-
Partitionid: &r.Target.Spec.Partition,
152-
Imageid: &r.Target.Spec.Image,
153-
SSHPubKeys: r.Target.Spec.SSHPublicKeys,
154-
Networks: networks,
155-
UserData: r.Target.Spec.Userdata,
156-
Tags: tags,
169+
Description: "created by firewall-controller-manager",
170+
Name: r.Target.Name,
171+
Hostname: r.Target.Name,
172+
Sizeid: &r.Target.Spec.Size,
173+
Projectid: &r.Target.Spec.Project,
174+
Partitionid: &r.Target.Spec.Partition,
175+
Imageid: &r.Target.Spec.Image,
176+
SSHPubKeys: r.Target.Spec.SSHPublicKeys,
177+
Networks: networks,
178+
UserData: r.Target.Spec.Userdata,
179+
Tags: tags,
180+
FirewallRules: rules,
157181
}
158182

159183
resp, err := c.c.GetMetal().Firewall().AllocateFirewall(firewall.NewAllocateFirewallParams().WithBody(createRequest).WithContext(r.Ctx), nil)

0 commit comments

Comments
 (0)