Skip to content
This repository was archived by the owner on Jun 13, 2025. It is now read-only.

Commit 5c3c814

Browse files
committed
Add support for security groups
1 parent 40630ee commit 5c3c814

17 files changed

+947
-94
lines changed

api/v1beta1/scalewaycluster_types.go

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package v1beta1
22

33
import (
4+
"fmt"
5+
"strconv"
6+
"strings"
7+
8+
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
9+
"github.com/scaleway/scaleway-sdk-go/scw"
410
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
511
clusterv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1"
612
)
@@ -47,6 +53,181 @@ type NetworkSpec struct {
4753
// already has an attached Public Gateway.
4854
// +optional
4955
PublicGateway *PublicGatewaySpec `json:"publicGateway,omitempty"`
56+
57+
// A list of security groups that will be created in all zones of the region
58+
// of the cluster. A security group can be referenced by its name in the
59+
// ScalewayMachine object. If a security group is in use by at least one
60+
// machine, it MUST NOT be removed from this list: remove the machines first.
61+
SecurityGroups []SecurityGroup `json:"securityGroups,omitempty"`
62+
}
63+
64+
// SecurityGroup contains a name and inbound/outbound policies.
65+
type SecurityGroup struct {
66+
// Name of the security group. Must be unique in a list of security groups.
67+
Name string `json:"name"`
68+
69+
// Inbound policy. If not set, all inbound traffic is allowed.
70+
// +optional
71+
Inbound *SecurityGroupPolicy `json:"inbound,omitempty"`
72+
73+
// Oubound policy. If not set, all outbound traffic is allowed.
74+
// +optional
75+
Outbound *SecurityGroupPolicy `json:"outbound,omitempty"`
76+
}
77+
78+
// SecurityGroupPolicy defines a policy for inbound or outbound traffic.
79+
type SecurityGroupPolicy struct {
80+
// Default policy. If unset, defaults to "Accept".
81+
// +optional
82+
Default *SecurityGroupAction `json:"default,omitempty"`
83+
84+
// A list of rules for this policy.
85+
// +optional
86+
Rules []SecurityGroupRule `json:"rules,omitempty"`
87+
}
88+
89+
// SecurityGroupRule is a rule for the security group policy.
90+
type SecurityGroupRule struct {
91+
// Action to apply when the rule matches a packet.
92+
Action SecurityGroupAction `json:"action"`
93+
94+
// Protocol family this rule applies to. Can be ANY, TCP, UDP or ICMP.
95+
// If unset, defaults to ANY.
96+
// +optional
97+
Protocol *SecurityGroupProtocol `json:"protocol,omitempty"`
98+
99+
// Port or range of ports this rule applies to. Not applicable for ICMP or ANY.
100+
// +optional
101+
Ports *PortOrPortRange `json:"ports,omitempty"`
102+
103+
// IP range this rule applies to. Defaults to 0.0.0.0/0.
104+
// +optional
105+
IPRange *string `json:"ipRange,omitempty"`
106+
}
107+
108+
// PortOrPortRange is a string representation of a port or a port range (e.g. 0-1024).
109+
type PortOrPortRange string
110+
111+
// ToRange returns the range of ports, with the first return value being the lower
112+
// port (called "from") and the second return value being the higher port (called
113+
// "to"). If only a single port is set, the higher port is nil.
114+
func (p *PortOrPortRange) ToRange() (*uint32, *uint32, error) {
115+
if p == nil {
116+
return nil, nil, nil
117+
}
118+
119+
s := strings.Split(string(*p), "-")
120+
121+
switch len(s) {
122+
case 1:
123+
n, err := strconv.Atoi(s[0])
124+
if err != nil {
125+
return nil, nil, fmt.Errorf("port is not a valid number: %w", err)
126+
}
127+
128+
return scw.Uint32Ptr(uint32(n)), nil, nil
129+
case 2:
130+
from, err := strconv.Atoi(s[0])
131+
if err != nil {
132+
return nil, nil, fmt.Errorf("'from' port is not a valid number: %w", err)
133+
}
134+
135+
to, err := strconv.Atoi(s[1])
136+
if err != nil {
137+
return nil, nil, fmt.Errorf("'to' port is not a valid number: %w", err)
138+
}
139+
140+
if to < from {
141+
return nil, nil, fmt.Errorf("invalid port range: 'from' is higher than 'to'")
142+
}
143+
144+
return scw.Uint32Ptr(uint32(from)), scw.Uint32Ptr(uint32(to)), nil
145+
default:
146+
return nil, nil, fmt.Errorf("port or port range is not correctly formatted")
147+
}
148+
}
149+
150+
// SecurityGroupProtocol is a network protocol.
151+
type SecurityGroupProtocol string
152+
153+
const (
154+
// SecurityGroupProtocolANY matches a packet of any protocol.
155+
SecurityGroupProtocolANY SecurityGroupProtocol = "ANY"
156+
// SecurityGroupProtocolTCP matches a TCP packet.
157+
SecurityGroupProtocolTCP SecurityGroupProtocol = "TCP"
158+
// SecurityGroupProtocolUDP matches an UDP packet.
159+
SecurityGroupProtocolUDP SecurityGroupProtocol = "UDP"
160+
// SecurityGroupProtocolICMP matches an ICMP packet.
161+
SecurityGroupProtocolICMP SecurityGroupProtocol = "ICMP"
162+
)
163+
164+
// ToInstance returns the instance SecurityGroupRuleProtocol that matches the
165+
// SecurityGroupProtocol value of the pointer receiver. Defaults to SecurityGroupRuleProtocolANY
166+
// if the value is nil.
167+
func (s *SecurityGroupProtocol) ToInstance() (instance.SecurityGroupRuleProtocol, error) {
168+
if s == nil {
169+
return instance.SecurityGroupRuleProtocolANY, nil
170+
}
171+
172+
switch *s {
173+
case SecurityGroupProtocolANY:
174+
return instance.SecurityGroupRuleProtocolANY, nil
175+
case SecurityGroupProtocolTCP:
176+
return instance.SecurityGroupRuleProtocolTCP, nil
177+
case SecurityGroupProtocolUDP:
178+
return instance.SecurityGroupRuleProtocolUDP, nil
179+
case SecurityGroupProtocolICMP:
180+
return instance.SecurityGroupRuleProtocolICMP, nil
181+
default:
182+
return "", fmt.Errorf("unknown security group protocol: %s", *s)
183+
}
184+
}
185+
186+
// SecurityGroupAction is an action to apply when a packet matches a rule. It can
187+
// also be used as a default policy.
188+
type SecurityGroupAction string
189+
190+
const (
191+
// SecurityGroupActionDrop drops all matching packets.
192+
SecurityGroupActionDrop SecurityGroupAction = "Drop"
193+
// SecurityGroupActionAccept accepts all matching packets.
194+
SecurityGroupActionAccept SecurityGroupAction = "Accept"
195+
)
196+
197+
// ToInstancePolicy returns the instance SecurityGroupPolicy that matches the
198+
// SecurityGroupAction value of the pointer receiver. Defaults to SecurityGroupPolicyAccept
199+
// if the value is nil.
200+
func (s *SecurityGroupAction) ToInstancePolicy() (instance.SecurityGroupPolicy, error) {
201+
if s == nil {
202+
return instance.SecurityGroupPolicyAccept, nil
203+
}
204+
205+
switch *s {
206+
case SecurityGroupActionAccept:
207+
return instance.SecurityGroupPolicyAccept, nil
208+
case SecurityGroupActionDrop:
209+
return instance.SecurityGroupPolicyDrop, nil
210+
default:
211+
return "", fmt.Errorf("unknown action: %s", *s)
212+
}
213+
}
214+
215+
// ToInstancePolicy returns the instance SecurityGroupRuleAction that matches the
216+
// SecurityGroupAction value of the pointer receiver. Defaults to SecurityGroupRuleActionAccept
217+
// if the value is nil.
218+
func (s *SecurityGroupAction) ToInstanceAction() (instance.SecurityGroupRuleAction, error) {
219+
if s == nil {
220+
return instance.SecurityGroupRuleActionAccept, nil
221+
}
222+
223+
switch *s {
224+
case SecurityGroupActionAccept:
225+
return instance.SecurityGroupRuleActionAccept, nil
226+
case SecurityGroupActionDrop:
227+
return instance.SecurityGroupRuleActionDrop, nil
228+
default:
229+
return "", fmt.Errorf("unknown action: %s", *s)
230+
}
50231
}
51232

52233
// PrivateNetworkSpec defines Private Network settings for the cluster.

0 commit comments

Comments
 (0)