Skip to content

Commit

Permalink
Create spec, service, tests, and docs for virtual network peering
Browse files Browse the repository at this point in the history
  • Loading branch information
Jont828 committed Oct 11, 2021
1 parent 742cedf commit ea34709
Show file tree
Hide file tree
Showing 33 changed files with 2,027 additions and 134 deletions.
3 changes: 3 additions & 0 deletions api/v1alpha3/azurecluster_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ func (src *AzureCluster) ConvertTo(dstRaw conversion.Hub) error { // nolint

dst.Status.LongRunningOperationStates = restored.Status.LongRunningOperationStates

// Restore list of virtual network peerings
dst.Spec.NetworkSpec.Vnet.Peerings = restored.Spec.NetworkSpec.Vnet.Peerings

return nil
}

Expand Down
1 change: 1 addition & 0 deletions api/v1alpha3/zz_generated.conversion.go

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

39 changes: 37 additions & 2 deletions api/v1alpha4/azurecluster_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,45 @@ limitations under the License.
package v1alpha4

import (
apiconversion "k8s.io/apimachinery/pkg/conversion"
utilconversion "sigs.k8s.io/cluster-api/util/conversion"

infrav1beta1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/conversion"
)

// ConvertTo converts this AzureCluster to the Hub version (v1beta1).
func (src *AzureCluster) ConvertTo(dstRaw conversion.Hub) error { // nolint
dst := dstRaw.(*infrav1beta1.AzureCluster)
return Convert_v1alpha4_AzureCluster_To_v1beta1_AzureCluster(src, dst, nil)
if err := Convert_v1alpha4_AzureCluster_To_v1beta1_AzureCluster(src, dst, nil); err != nil {
return err
}

// Manually restore data.
restored := &infrav1beta1.AzureCluster{}
if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok {
return err
}

// Restore list of virtual network peerings
dst.Spec.NetworkSpec.Vnet.Peerings = restored.Spec.NetworkSpec.Vnet.Peerings

return nil
}

// ConvertFrom converts from the Hub version (v1beta1) to this version.
func (dst *AzureCluster) ConvertFrom(srcRaw conversion.Hub) error { // nolint
src := srcRaw.(*infrav1beta1.AzureCluster)
return Convert_v1beta1_AzureCluster_To_v1alpha4_AzureCluster(src, dst, nil)
if err := Convert_v1beta1_AzureCluster_To_v1alpha4_AzureCluster(src, dst, nil); err != nil {
return err
}

// Preserve Hub data on down-conversion.
if err := utilconversion.MarshalData(src, dst); err != nil {
return err
}

return nil
}

// ConvertTo converts this AzureClusterList to the Hub version (v1beta1).
Expand All @@ -44,3 +69,13 @@ func (dst *AzureClusterList) ConvertFrom(srcRaw conversion.Hub) error { // nolin
src := srcRaw.(*infrav1beta1.AzureClusterList)
return Convert_v1beta1_AzureClusterList_To_v1alpha4_AzureClusterList(src, dst, nil)
}

// Convert_v1beta1_VnetSpec_To_v1alpha4_VnetSpec.
func Convert_v1beta1_VnetSpec_To_v1alpha4_VnetSpec(in *infrav1beta1.VnetSpec, out *VnetSpec, s apiconversion.Scope) error { //nolint
return autoConvert_v1beta1_VnetSpec_To_v1alpha4_VnetSpec(in, out, s)
}

// Convert_v1alpha4_VnetSpec_To_v1beta1_VnetSpec is an autogenerated conversion function.
func Convert_v1alpha4_VnetSpec_To_v1beta1_VnetSpec(in *VnetSpec, out *infrav1beta1.VnetSpec, s apiconversion.Scope) error {
return autoConvert_v1alpha4_VnetSpec_To_v1beta1_VnetSpec(in, out, s)
}
15 changes: 3 additions & 12 deletions api/v1alpha4/zz_generated.conversion.go

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

9 changes: 9 additions & 0 deletions api/v1beta1/azurecluster_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func (c *AzureCluster) setNetworkSpecDefaults() {
c.setVnetDefaults()
c.setBastionDefaults()
c.setSubnetDefaults()
c.setVnetPeeringDefaults()
c.setAPIServerLBDefaults()
c.setNodeOutboundLBDefaults()
c.setControlPlaneOutboundLBDefaults()
Expand Down Expand Up @@ -147,6 +148,14 @@ func (c *AzureCluster) setSubnetDefaults() {
}
}

func (c *AzureCluster) setVnetPeeringDefaults() {
for i, peering := range c.Spec.NetworkSpec.Vnet.Peerings {
if peering.ResourceGroup == "" {
c.Spec.NetworkSpec.Vnet.Peerings[i].ResourceGroup = c.Spec.ResourceGroup
}
}
}

func setSecurityRuleDefaults(sg *SecurityGroup) {
for i := range sg.SecurityRules {
if sg.SecurityRules[i].Direction == "" {
Expand Down
118 changes: 118 additions & 0 deletions api/v1beta1/azurecluster_default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,124 @@ func TestSubnetDefaults(t *testing.T) {
}
}

func TestVnetPeeringDefaults(t *testing.T) {
cases := []struct {
name string
cluster *AzureCluster
output *AzureCluster
}{
{
name: "no peering",
cluster: &AzureCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "cluster-test",
},
Spec: AzureClusterSpec{
NetworkSpec: NetworkSpec{},
},
},
output: &AzureCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "cluster-test",
},
Spec: AzureClusterSpec{
NetworkSpec: NetworkSpec{},
},
},
},
{
name: "peering with resource group",
cluster: &AzureCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "cluster-test",
},
Spec: AzureClusterSpec{
ResourceGroup: "cluster-test",
NetworkSpec: NetworkSpec{
Vnet: VnetSpec{
Peerings: VnetPeerings{
{
RemoteVnetName: "my-vnet",
ResourceGroup: "cluster-test",
},
},
},
},
},
},
output: &AzureCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "cluster-test",
},
Spec: AzureClusterSpec{
ResourceGroup: "cluster-test",
NetworkSpec: NetworkSpec{
Vnet: VnetSpec{
Peerings: VnetPeerings{
{
RemoteVnetName: "my-vnet",
ResourceGroup: "cluster-test",
},
},
},
},
},
},
},
{
name: "peering without resource group",
cluster: &AzureCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "cluster-test",
},
Spec: AzureClusterSpec{
ResourceGroup: "cluster-test",
NetworkSpec: NetworkSpec{
Vnet: VnetSpec{
Peerings: VnetPeerings{
{
RemoteVnetName: "my-vnet",
},
},
},
},
},
},
output: &AzureCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "cluster-test",
},
Spec: AzureClusterSpec{
ResourceGroup: "cluster-test",
NetworkSpec: NetworkSpec{
Vnet: VnetSpec{
Peerings: VnetPeerings{
{
RemoteVnetName: "my-vnet",
ResourceGroup: "cluster-test",
},
},
},
},
},
},
},
}

for _, c := range cases {
tc := c
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
tc.cluster.setVnetPeeringDefaults()
if !reflect.DeepEqual(tc.cluster, tc.output) {
expected, _ := json.MarshalIndent(tc.output, "", "\t")
actual, _ := json.MarshalIndent(tc.cluster, "", "\t")
t.Errorf("Expected %s, got %s", string(expected), string(actual))
}
})
}
}

func TestAPIServerLBDefaults(t *testing.T) {
cases := []struct {
name string
Expand Down
17 changes: 17 additions & 0 deletions api/v1beta1/azurecluster_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ func validateNetworkSpec(networkSpec NetworkSpec, old NetworkSpec, fldPath *fiel
allErrs = append(allErrs, validateVnetCIDR(networkSpec.Vnet.CIDRBlocks, fldPath.Child("cidrBlocks"))...)

allErrs = append(allErrs, validateSubnets(networkSpec.Subnets, networkSpec.Vnet, fldPath.Child("subnets"))...)

allErrs = append(allErrs, validateVnetPeerings(networkSpec.Vnet.Peerings, fldPath.Child("peerings"))...)
}

var cidrBlocks []string
Expand Down Expand Up @@ -256,6 +258,21 @@ func validateVnetCIDR(vnetCIDRBlocks []string, fldPath *field.Path) field.ErrorL
return allErrs
}

// validateVnetPeerings validates a list of virtual network peerings.
func validateVnetPeerings(peerings VnetPeerings, fldPath *field.Path) field.ErrorList {
var allErrs field.ErrorList
vnetIdentifiers := make(map[string]bool, len(peerings))

for _, peering := range peerings {
vnetIdentifier := peering.ResourceGroup + "/" + peering.RemoteVnetName
if _, ok := vnetIdentifiers[vnetIdentifier]; ok {
allErrs = append(allErrs, field.Duplicate(fldPath, vnetIdentifier))
}
vnetIdentifiers[vnetIdentifier] = true
}
return allErrs
}

// validateLoadBalancerName validates the Name of a Load Balancer.
func validateLoadBalancerName(name string, fldPath *field.Path) *field.Error {
if success, _ := regexp.Match(loadBalancerRegex, []byte(name)); !success {
Expand Down
17 changes: 17 additions & 0 deletions api/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,28 @@ type VnetSpec struct {
// +optional
CIDRBlocks []string `json:"cidrBlocks,omitempty"`

// Peerings defines a list of peerings of the newly created virtual network with existing virtual networks.
// +optional
Peerings VnetPeerings `json:"peerings,omitempty"`

// Tags is a collection of tags describing the resource.
// +optional
Tags Tags `json:"tags,omitempty"`
}

// VnetPeeringSpec specifies an existing remote virtual network to peer with the AzureCluster's virtual network.
type VnetPeeringSpec struct {
// ResourceGroup is the resource group name of the remote virtual network.
// +optional
ResourceGroup string `json:"resourceGroup,omitempty"`

// RemoteVnetName defines name of the remote virtual network.
RemoteVnetName string `json:"remoteVnetName"`
}

// VnetPeerings is a slice of VnetPeering.
type VnetPeerings []VnetPeeringSpec

// IsManaged returns true if the vnet is managed.
func (v *VnetSpec) IsManaged(clusterName string) bool {
return v.ID == "" || v.Tags.HasOwned(clusterName)
Expand Down
39 changes: 39 additions & 0 deletions api/v1beta1/zz_generated.deepcopy.go

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

5 changes: 5 additions & 0 deletions azure/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,11 @@ func GenerateDataDiskName(machineName, nameSuffix string) string {
return fmt.Sprintf("%s_%s", machineName, nameSuffix)
}

// GenerateVnetPeeringName generates the name for a peering between two vnets.
func GenerateVnetPeeringName(sourceVnetName string, remoteVnetName string) string {
return fmt.Sprintf("%s-To-%s", sourceVnetName, remoteVnetName)
}

// GenerateAvailabilitySetName generates the name of a availability set based on the cluster name and the node group.
// node group identifies the set of nodes that belong to this availability set:
// For control plane nodes, this will be `control-plane`.
Expand Down
Loading

0 comments on commit ea34709

Please sign in to comment.