Skip to content

Commit

Permalink
Merge pull request #1299 from CecileRobertMichon/egress-rules
Browse files Browse the repository at this point in the history
Add support for custom egress rules
  • Loading branch information
k8s-ci-robot authored Apr 13, 2021
2 parents 75fe165 + 715d5fd commit f8cbcda
Show file tree
Hide file tree
Showing 18 changed files with 378 additions and 265 deletions.
74 changes: 55 additions & 19 deletions api/v1alpha3/azurecluster_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (

apiconversion "k8s.io/apimachinery/pkg/conversion"
infrav1alpha4 "sigs.k8s.io/cluster-api-provider-azure/api/v1alpha4"
v1alpha4 "sigs.k8s.io/cluster-api-provider-azure/api/v1alpha4"
apiv1alpha3 "sigs.k8s.io/cluster-api/api/v1alpha3"
apiv1alpha4 "sigs.k8s.io/cluster-api/api/v1alpha4"
"sigs.k8s.io/controller-runtime/pkg/conversion"
Expand Down Expand Up @@ -58,6 +57,24 @@ func (src *AzureCluster) ConvertTo(dstRaw conversion.Hub) error { // nolint
dst.Spec.NetworkSpec.APIServerLB.FrontendIPsCount = restored.Spec.NetworkSpec.APIServerLB.FrontendIPsCount
dst.Spec.NetworkSpec.NodeOutboundLB = restored.Spec.NetworkSpec.NodeOutboundLB

// Here we manually restore outbound security rules. Since v1alpha3 only supports ingress ("Inbound") rules, all v1alpha4 outbound rules are dropped when an AzureCluster
// is converted to v1alpha3. We loop through all security group rules. For all previously existing outbound rules we restore the full rule.
for _, restoredSubnet := range restored.Spec.NetworkSpec.Subnets {
for i, dstSubnet := range dst.Spec.NetworkSpec.Subnets {
if dstSubnet.Name == restoredSubnet.Name {
var restoredOutboundRules []infrav1alpha4.SecurityRule
for _, restoredSecurityRule := range restoredSubnet.SecurityGroup.SecurityRules {
if restoredSecurityRule.Direction != infrav1alpha4.SecurityRuleDirectionInbound {
// For non-inbound rules which are only supported starting in v1alpha4, we restore the entire rule.
restoredOutboundRules = append(restoredOutboundRules, restoredSecurityRule)
}
}
dst.Spec.NetworkSpec.Subnets[i].SecurityGroup.SecurityRules = append(dst.Spec.NetworkSpec.Subnets[i].SecurityGroup.SecurityRules, restoredOutboundRules...)
break
}
}
}

return nil
}

Expand Down Expand Up @@ -195,26 +212,28 @@ func Convert_v1alpha4_SecurityGroup_To_v1alpha3_SecurityGroup(in *infrav1alpha4.
out.ID = in.ID
out.Name = in.Name

out.IngressRules = make(IngressRules, len(in.IngressRules))
for i := range in.IngressRules {
out.IngressRules[i] = IngressRule{}
if err := Convert_v1alpha4_IngressRule_To_v1alpha3_IngressRule(&in.IngressRules[i], &out.IngressRules[i], s); err != nil {
return err
out.IngressRules = make(IngressRules, 0)
for i, rule := range in.SecurityRules {
if rule.Direction == infrav1alpha4.SecurityRuleDirectionInbound { // only inbound rules are supported in v1alpha3.
out.IngressRules[i] = IngressRule{}
if err := Convert_v1alpha4_SecurityRule_To_v1alpha3_IngressRule(&in.SecurityRules[i], &out.IngressRules[i], s); err != nil {
return err
}
}
}

out.Tags = *(*Tags)(unsafe.Pointer(&in.Tags))
return nil
}

func Convert_v1alpha3_SecurityGroup_To_v1alpha4_SecurityGroup(in *SecurityGroup, out *infrav1alpha4.SecurityGroup, s apiconversion.Scope) error {
func Convert_v1alpha3_SecurityGroup_To_v1alpha4_SecurityGroup(in *SecurityGroup, out *infrav1alpha4.SecurityGroup, s apiconversion.Scope) error { //nolint
out.ID = in.ID
out.Name = in.Name

out.IngressRules = make(infrav1alpha4.IngressRules, len(in.IngressRules))
out.SecurityRules = make(infrav1alpha4.SecurityRules, len(in.IngressRules))
for i := range in.IngressRules {
out.IngressRules[i] = infrav1alpha4.IngressRule{}
if err := Convert_v1alpha3_IngressRule_To_v1alpha4_IngressRule(&in.IngressRules[i], &out.IngressRules[i], s); err != nil {
out.SecurityRules[i] = infrav1alpha4.SecurityRule{}
if err := Convert_v1alpha3_IngressRule_To_v1alpha4_SecurityRule(&in.IngressRules[i], &out.SecurityRules[i], s); err != nil {
return err
}
}
Expand All @@ -223,18 +242,35 @@ func Convert_v1alpha3_SecurityGroup_To_v1alpha4_SecurityGroup(in *SecurityGroup,
return nil
}

// Convert_v1alpha3_IngressRule_To_v1alpha4_IngressRule
func Convert_v1alpha3_IngressRule_To_v1alpha4_IngressRule(in *IngressRule, out *infrav1alpha4.IngressRule, s apiconversion.Scope) error {
return autoConvert_v1alpha3_IngressRule_To_v1alpha4_IngressRule(in, out, s)
// Convert_v1alpha3_IngressRule_To_v1alpha4_SecurityRule
func Convert_v1alpha3_IngressRule_To_v1alpha4_SecurityRule(in *IngressRule, out *infrav1alpha4.SecurityRule, _ apiconversion.Scope) error { //nolint
out.Name = in.Name
out.Description = in.Description
out.Protocol = infrav1alpha4.SecurityGroupProtocol(in.Protocol)
out.Priority = in.Priority
out.SourcePorts = in.SourcePorts
out.DestinationPorts = in.DestinationPorts
out.Source = in.Source
out.Destination = in.Destination
out.Direction = infrav1alpha4.SecurityRuleDirectionInbound // all v1alpha3 rules are inbound.
return nil
}

// Convert_v1alpha4_IngressRule_To_v1alpha3_IngressRule
func Convert_v1alpha4_IngressRule_To_v1alpha3_IngressRule(in *infrav1alpha4.IngressRule, out *IngressRule, s apiconversion.Scope) error {
return autoConvert_v1alpha4_IngressRule_To_v1alpha3_IngressRule(in, out, s)
// Convert_v1alpha4_SecurityRule_To_v1alpha3_IngressRule
func Convert_v1alpha4_SecurityRule_To_v1alpha3_IngressRule(in *infrav1alpha4.SecurityRule, out *IngressRule, _ apiconversion.Scope) error { //nolint
out.Name = in.Name
out.Description = in.Description
out.Protocol = SecurityGroupProtocol(in.Protocol)
out.Priority = in.Priority
out.SourcePorts = in.SourcePorts
out.DestinationPorts = in.DestinationPorts
out.Source = in.Source
out.Destination = in.Destination
return nil
}

// Convert_v1alpha4_ManagedDisk_To_v1alpha3_ManagedDisk converts between api versions
func Convert_v1alpha4_ManagedDisk_To_v1alpha3_ManagedDisk(in *v1alpha4.ManagedDisk, out *ManagedDisk, s apiconversion.Scope) error {
func Convert_v1alpha4_ManagedDisk_To_v1alpha3_ManagedDisk(in *infrav1alpha4.ManagedDisk, out *ManagedDisk, s apiconversion.Scope) error {
return autoConvert_v1alpha4_ManagedDisk_To_v1alpha3_ManagedDisk(in, out, s)
}

Expand All @@ -249,11 +285,11 @@ func Convert_v1alpha4_APIEndpoint_To_v1alpha3_APIEndpoint(in *apiv1alpha4.APIEnd
}

// Convert_v1alpha3_VnetSpec_To_v1alpha4_VnetSpec is an autogenerated conversion function.
func Convert_v1alpha3_VnetSpec_To_v1alpha4_VnetSpec(in *VnetSpec, out *v1alpha4.VnetSpec, s apiconversion.Scope) error {
func Convert_v1alpha3_VnetSpec_To_v1alpha4_VnetSpec(in *VnetSpec, out *infrav1alpha4.VnetSpec, s apiconversion.Scope) error {
return autoConvert_v1alpha3_VnetSpec_To_v1alpha4_VnetSpec(in, out, s)
}

// Convert_v1alpha4_LoadBalancerSpec_To_v1alpha3_LoadBalancerSpec is an autogenerated conversion function.
func Convert_v1alpha4_LoadBalancerSpec_To_v1alpha3_LoadBalancerSpec(in *v1alpha4.LoadBalancerSpec, out *LoadBalancerSpec, s apiconversion.Scope) error {
func Convert_v1alpha4_LoadBalancerSpec_To_v1alpha3_LoadBalancerSpec(in *infrav1alpha4.LoadBalancerSpec, out *LoadBalancerSpec, s apiconversion.Scope) error {
return autoConvert_v1alpha4_LoadBalancerSpec_To_v1alpha3_LoadBalancerSpec(in, out, s)
}
3 changes: 1 addition & 2 deletions api/v1alpha3/conversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@ limitations under the License.
package v1alpha3

import (
"testing"

fuzz "github.com/google/gofuzz"
. "github.com/onsi/gomega"
"testing"

"k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
"k8s.io/apimachinery/pkg/runtime"
Expand Down
62 changes: 9 additions & 53 deletions api/v1alpha3/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions api/v1alpha4/azurecluster_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ func (c *AzureCluster) setSubnetDefaults() {
if cpSubnet.SecurityGroup.Name == "" {
cpSubnet.SecurityGroup.Name = generateControlPlaneSecurityGroupName(c.ObjectMeta.Name)
}
setSecurityRuleDefaults(&cpSubnet.SecurityGroup)

if nodeSubnet.Name == "" {
nodeSubnet.Name = generateNodeSubnetName(c.ObjectMeta.Name)
Expand All @@ -104,6 +105,7 @@ func (c *AzureCluster) setSubnetDefaults() {
if nodeSubnet.SecurityGroup.Name == "" {
nodeSubnet.SecurityGroup.Name = generateNodeSecurityGroupName(c.ObjectMeta.Name)
}
setSecurityRuleDefaults(&nodeSubnet.SecurityGroup)
if nodeSubnet.RouteTable.Name == "" {
nodeSubnet.RouteTable.Name = generateNodeRouteTableName(c.ObjectMeta.Name)
}
Expand All @@ -112,6 +114,14 @@ func (c *AzureCluster) setSubnetDefaults() {
c.Spec.NetworkSpec.UpdateNodeSubnet(nodeSubnet)
}

func setSecurityRuleDefaults(sg *SecurityGroup) {
for i := range sg.SecurityRules {
if sg.SecurityRules[i].Direction == "" {
sg.SecurityRules[i].Direction = SecurityRuleDirectionInbound
}
}
}

func (c *AzureCluster) setAPIServerLBDefaults() {
lb := &c.Spec.NetworkSpec.APIServerLB
if lb.Type == "" {
Expand Down
74 changes: 74 additions & 0 deletions api/v1alpha4/azurecluster_default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"reflect"
"testing"

"github.com/Azure/go-autorest/autorest/to"

"k8s.io/utils/pointer"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -527,6 +529,78 @@ func TestSubnetDefaults(t *testing.T) {
},
},
},
{
name: "subnets with custom security group",
cluster: &AzureCluster{
ObjectMeta: v1.ObjectMeta{
Name: "cluster-test",
},
Spec: AzureClusterSpec{
NetworkSpec: NetworkSpec{
Subnets: Subnets{
{
Name: "cluster-test-controlplane-subnet",
Role: "control-plane",
SecurityGroup: SecurityGroup{
Name: "my-custom-sg",
SecurityRules: []SecurityRule{
{
Name: "allow_port_50000",
Description: "allow port 50000",
Protocol: "*",
Priority: 2202,
SourcePorts: to.StringPtr("*"),
DestinationPorts: to.StringPtr("*"),
Source: to.StringPtr("*"),
Destination: to.StringPtr("*"),
},
},
},
},
},
},
},
},
output: &AzureCluster{
ObjectMeta: v1.ObjectMeta{
Name: "cluster-test",
},
Spec: AzureClusterSpec{
NetworkSpec: NetworkSpec{
Subnets: Subnets{
{
Name: "cluster-test-controlplane-subnet",
Role: "control-plane",
CIDRBlocks: []string{DefaultControlPlaneSubnetCIDR},
SecurityGroup: SecurityGroup{
Name: "my-custom-sg",
SecurityRules: []SecurityRule{
{
Name: "allow_port_50000",
Description: "allow port 50000",
Protocol: "*",
Priority: 2202,
SourcePorts: to.StringPtr("*"),
DestinationPorts: to.StringPtr("*"),
Source: to.StringPtr("*"),
Destination: to.StringPtr("*"),
Direction: SecurityRuleDirectionInbound,
},
},
},
},
{
Role: SubnetNode,
Name: "cluster-test-node-subnet",
CIDRBlocks: []string{DefaultNodeSubnetCIDR},
SecurityGroup: SecurityGroup{Name: "cluster-test-node-nsg"},
RouteTable: RouteTable{Name: "cluster-test-node-routetable"},
},
},
},
},
},
},
}

for _, c := range cases {
Expand Down
Loading

0 comments on commit f8cbcda

Please sign in to comment.