diff --git a/docs/book/src/clusteropenstack/configuration.md b/docs/book/src/clusteropenstack/configuration.md index cb9e20360a..193720927e 100644 --- a/docs/book/src/clusteropenstack/configuration.md +++ b/docs/book/src/clusteropenstack/configuration.md @@ -565,6 +565,7 @@ permitted from anywhere, as with the default rules). We can add security group rules that authorize traffic from all nodes via `allNodesSecurityGroupRules`. It takes a list of security groups rules that should be applied to selected nodes. The following rule fields are mutually exclusive: `remoteManagedGroups`, `remoteGroupID` and `remoteIPPrefix`. +If none of these fields are set, the rule will have a remote IP prefix of `0.0.0.0/0` per Neutron default. Valid values for `remoteManagedGroups` are `controlplane`, `worker` and `bastion`. diff --git a/docs/book/src/topics/crd-changes/v1alpha7-to-v1beta1.md b/docs/book/src/topics/crd-changes/v1alpha7-to-v1beta1.md index 600e164fef..57e37e580b 100644 --- a/docs/book/src/topics/crd-changes/v1alpha7-to-v1beta1.md +++ b/docs/book/src/topics/crd-changes/v1alpha7-to-v1beta1.md @@ -394,6 +394,9 @@ The field `managedSecurityGroups` is now a pointer to a `ManagedSecurityGroups` Also, we can now add security group rules that authorize traffic from all nodes via `allNodesSecurityGroupRules`. It takes a list of security groups rules that should be applied to selected nodes. The following rule fields are mutually exclusive: `remoteManagedGroups`, `remoteGroupID` and `remoteIPPrefix`. +If none of these fields are set, the rule will have a remote IP prefix of `0.0.0.0/0` per Neutron default. + +```yaml Valid values for `remoteManagedGroups` are `controlplane`, `worker` and `bastion`. Also, `OpenStackCluster.Spec.AllowAllInClusterTraffic` moved under `ManagedSecurityGroups`. diff --git a/pkg/cloud/services/networking/securitygroups.go b/pkg/cloud/services/networking/securitygroups.go index cc41b9423b..5863adc262 100644 --- a/pkg/cloud/services/networking/securitygroups.go +++ b/pkg/cloud/services/networking/securitygroups.go @@ -297,10 +297,6 @@ func getAllNodesRules(remoteManagedGroups map[string]string, allNodesSecurityGro // validateRemoteManagedGroups validates that the remoteManagedGroups target existing managed security groups. func validateRemoteManagedGroups(remoteManagedGroups map[string]string, ruleRemoteManagedGroups []infrav1.ManagedSecurityGroupName) error { - if len(ruleRemoteManagedGroups) == 0 { - return fmt.Errorf("remoteManagedGroups is required") - } - for _, group := range ruleRemoteManagedGroups { if _, ok := remoteManagedGroups[group.String()]; !ok { return fmt.Errorf("remoteManagedGroups: %s is not a valid remote managed security group", group) diff --git a/pkg/cloud/services/networking/securitygroups_test.go b/pkg/cloud/services/networking/securitygroups_test.go index a1b0103a07..0db4bc3a8d 100644 --- a/pkg/cloud/services/networking/securitygroups_test.go +++ b/pkg/cloud/services/networking/securitygroups_test.go @@ -49,19 +49,14 @@ func TestValidateRemoteManagedGroups(t *testing.T) { wantErr: true, }, { - name: "Valid rule with missing remoteManagedGroups", + name: "Valid rule with no remoteManagedGroups", rule: infrav1.SecurityGroupRuleSpec{ - PortRangeMin: ptr.To(22), - PortRangeMax: ptr.To(22), - Protocol: ptr.To("tcp"), + PortRangeMin: ptr.To(22), + PortRangeMax: ptr.To(22), + Protocol: ptr.To("tcp"), + RemoteIPPrefix: ptr.To("0.0.0.0/0"), }, - remoteManagedGroups: map[string]string{ - "self": "self", - "controlplane": "1", - "worker": "2", - "bastion": "3", - }, - wantErr: true, + wantErr: false, }, { name: "Valid rule with remoteManagedGroups", @@ -171,6 +166,70 @@ func TestGetAllNodesRules(t *testing.T) { }, }, }, + { + name: "Valid remoteIPPrefix in a rule", + remoteManagedGroups: map[string]string{ + "controlplane": "1", + "worker": "2", + }, + allNodesSecurityGroupRules: []infrav1.SecurityGroupRuleSpec{ + { + Protocol: ptr.To("tcp"), + PortRangeMin: ptr.To(22), + PortRangeMax: ptr.To(22), + RemoteIPPrefix: ptr.To("0.0.0.0/0"), + }, + }, + wantRules: []resolvedSecurityGroupRuleSpec{ + { + Protocol: "tcp", + PortRangeMin: 22, + PortRangeMax: 22, + RemoteIPPrefix: "0.0.0.0/0", + }, + }, + }, + { + name: "Valid allNodesSecurityGroupRules with no remote parameter", + remoteManagedGroups: map[string]string{ + "controlplane": "1", + "worker": "2", + }, + allNodesSecurityGroupRules: []infrav1.SecurityGroupRuleSpec{ + { + Protocol: ptr.To("tcp"), + PortRangeMin: ptr.To(22), + PortRangeMax: ptr.To(22), + }, + }, + wantRules: []resolvedSecurityGroupRuleSpec{ + { + Protocol: "tcp", + PortRangeMin: 22, + PortRangeMax: 22, + }, + }, + wantErr: false, + }, + { + name: "Invalid allNodesSecurityGroupRules with bastion while remoteManagedGroups does not have bastion", + remoteManagedGroups: map[string]string{ + "controlplane": "1", + "worker": "2", + }, + allNodesSecurityGroupRules: []infrav1.SecurityGroupRuleSpec{ + { + Protocol: ptr.To("tcp"), + PortRangeMin: ptr.To(22), + PortRangeMax: ptr.To(22), + RemoteManagedGroups: []infrav1.ManagedSecurityGroupName{ + "bastion", + }, + }, + }, + wantRules: nil, + wantErr: true, + }, { name: "Invalid allNodesSecurityGroupRules with wrong remoteManagedGroups", remoteManagedGroups: map[string]string{