Skip to content

Commit e04e034

Browse files
committed
Enable public MEC on CAPZ
1 parent 4fc2041 commit e04e034

File tree

60 files changed

+2033
-76
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+2033
-76
lines changed

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ create-aks-cluster: $(KUSTOMIZE) $(ENVSUBST) $(KUBECTL) ## Create a aks cluster.
344344
create-cluster: ## Create a workload development Kubernetes cluster on Azure in a kind management cluster.
345345
EXP_CLUSTER_RESOURCE_SET=true \
346346
EXP_MACHINE_POOL=true \
347+
EXP_EDGEZONE=true \
347348
$(MAKE) create-management-cluster \
348349
create-workload-cluster
349350

@@ -712,7 +713,7 @@ kind-create: $(KUBECTL) ## Create capz kind cluster if needed.
712713

713714
.PHONY: tilt-up
714715
tilt-up: install-tools kind-create ## Start tilt and build kind cluster if needed.
715-
CLUSTER_TOPOLOGY=true EXP_CLUSTER_RESOURCE_SET=true EXP_MACHINE_POOL=true EXP_KUBEADM_BOOTSTRAP_FORMAT_IGNITION=true tilt up
716+
CLUSTER_TOPOLOGY=true EXP_CLUSTER_RESOURCE_SET=true EXP_MACHINE_POOL=true EXP_KUBEADM_BOOTSTRAP_FORMAT_IGNITION=true EXP_EDGEZONE=true tilt up
716717

717718
.PHONY: delete-cluster
718719
delete-cluster: delete-workload-cluster ## Deletes the example kind cluster "capz".

api/v1alpha3/azurecluster_conversion.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ func (src *AzureCluster) ConvertTo(dstRaw conversion.Hub) error {
116116
// Restore list of virtual network peerings
117117
dst.Spec.NetworkSpec.Vnet.Peerings = restored.Spec.NetworkSpec.Vnet.Peerings
118118

119+
// Restore ExtendedLocation properties
120+
dst.Spec.ExtendedLocation = restored.Spec.ExtendedLocation
121+
119122
return nil
120123
}
121124

api/v1alpha4/azurecluster_conversion.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ func (src *AzureCluster) ConvertTo(dstRaw conversion.Hub) error {
4141
// Restore list of virtual network peerings
4242
dst.Spec.NetworkSpec.Vnet.Peerings = restored.Spec.NetworkSpec.Vnet.Peerings
4343

44+
// Restore ExtendedLocation properties
45+
dst.Spec.ExtendedLocation = restored.Spec.ExtendedLocation
46+
4447
// Restore API Server LB IP tags.
4548
for _, restoredFrontendIP := range restored.Spec.NetworkSpec.APIServerLB.FrontendIPs {
4649
for i, dstFrontendIP := range dst.Spec.NetworkSpec.APIServerLB.FrontendIPs {

api/v1beta1/azurecluster_validation.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"k8s.io/apimachinery/pkg/runtime/schema"
2828
"k8s.io/apimachinery/pkg/util/validation/field"
2929
"k8s.io/utils/pointer"
30+
"sigs.k8s.io/cluster-api-provider-azure/feature"
3031
)
3132

3233
const (
@@ -96,6 +97,11 @@ func (c *AzureCluster) validateClusterSpec(old *AzureCluster) field.ErrorList {
9697
allErrs = append(allErrs, validateCloudProviderConfigOverrides(c.Spec.CloudProviderConfigOverrides, oldCloudProviderConfigOverrides,
9798
field.NewPath("spec").Child("cloudProviderConfigOverrides"))...)
9899

100+
// If ClusterSpec has non-nil ExtendedLocation field but not enable EdgeZone feature gate flag, ClusterSpec validation failed.
101+
if !feature.Gates.Enabled(feature.EdgeZone) && c.Spec.ExtendedLocation != nil {
102+
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "ExtendedLocation"), "can be set only if the EdgeZone feature flag is enabled"))
103+
}
104+
99105
if err := validateBastionSpec(c.Spec.BastionSpec, field.NewPath("spec").Child("azureBastion").Child("bastionSpec")); err != nil {
100106
allErrs = append(allErrs, err)
101107
}

api/v1beta1/azurecluster_validation_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,3 +1505,27 @@ func TestServiceEndpointsLackRequiredFieldLocations(t *testing.T) {
15051505
g.Expect(errs[0].Error()).To(ContainSubstring("locations are required for all service endpoints"))
15061506
})
15071507
}
1508+
1509+
func TestClusterWithExtendedLocationInvalid(t *testing.T) {
1510+
g := NewWithT(t)
1511+
1512+
type test struct {
1513+
name string
1514+
cluster *AzureCluster
1515+
}
1516+
1517+
testCase := test{
1518+
name: "azurecluster spec with extended location but not enable EdgeZone feature gate flag",
1519+
cluster: createValidCluster(),
1520+
}
1521+
1522+
testCase.cluster.Spec.ExtendedLocation = &ExtendedLocationSpec{
1523+
Name: "rr4",
1524+
Type: "EdgeZone",
1525+
}
1526+
1527+
t.Run(testCase.name, func(t *testing.T) {
1528+
err := testCase.cluster.validateClusterSpec(nil)
1529+
g.Expect(err).NotTo(BeNil())
1530+
})
1531+
}

api/v1beta1/azurecluster_webhook_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,18 @@ func TestAzureCluster_ValidateCreate(t *testing.T) {
9494
}(),
9595
wantErr: true,
9696
},
97+
{
98+
name: "azurecluster with ExtendedLocation and false EdgeZone feature flag",
99+
cluster: func() *AzureCluster {
100+
cluster := createValidCluster()
101+
cluster.Spec.ExtendedLocation = &ExtendedLocationSpec{
102+
Name: "rr4",
103+
Type: "EdgeZone",
104+
}
105+
return cluster
106+
}(),
107+
wantErr: true,
108+
},
97109
}
98110
for _, tc := range tests {
99111
t.Run(tc.name, func(t *testing.T) {

api/v1beta1/types_class.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ type AzureClusterClassSpec struct {
2525

2626
Location string `json:"location"`
2727

28+
// ExtendedLocation is an optional set of ExtendedLocation properties for clusters on Azure public MEC.
29+
// +optional
30+
ExtendedLocation *ExtendedLocationSpec `json:"extendedLocation,omitempty"`
31+
2832
// AdditionalTags is an optional set of tags to add to Azure resources managed by the Azure provider, in addition to the
2933
// ones added by default.
3034
// +optional
@@ -52,6 +56,16 @@ type AzureClusterClassSpec struct {
5256
CloudProviderConfigOverrides *CloudProviderConfigOverrides `json:"cloudProviderConfigOverrides,omitempty"`
5357
}
5458

59+
// ExtendedLocationSpec defines the ExtendedLocation properties to enable CAPZ for Azure public MEC.
60+
type ExtendedLocationSpec struct {
61+
// Name defines the name for the extended location.
62+
Name string `json:"name"`
63+
64+
// Type defines the type for the extended location.
65+
// +kubebuilder:validation:Enum=EdgeZone
66+
Type string `json:"type"`
67+
}
68+
5569
// NetworkClassSpec defines the NetworkSpec properties that may be shared across several Azure clusters.
5670
type NetworkClassSpec struct {
5771
// PrivateDNSZoneName defines the zone name for the Azure Private DNS.

api/v1beta1/zz_generated.deepcopy.go

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
Copyright 2023 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package converters
18+
19+
import (
20+
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2021-11-01/compute"
21+
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-08-01/network"
22+
"github.com/Azure/go-autorest/autorest/to"
23+
infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
24+
)
25+
26+
// ExtendedLocationToNetworkSDK converts infrav1.ExtendedLocationSpec to network.ExtendedLocation.
27+
func ExtendedLocationToNetworkSDK(src *infrav1.ExtendedLocationSpec) *network.ExtendedLocation {
28+
if src == nil {
29+
return nil
30+
}
31+
return &network.ExtendedLocation{
32+
Name: to.StringPtr(src.Name),
33+
Type: network.ExtendedLocationTypes(src.Type),
34+
}
35+
}
36+
37+
// ExtendedLocationToComputeSDK converts infrav1.ExtendedLocationSpec to compute.ExtendedLocation.
38+
func ExtendedLocationToComputeSDK(src *infrav1.ExtendedLocationSpec) *compute.ExtendedLocation {
39+
if src == nil {
40+
return nil
41+
}
42+
return &compute.ExtendedLocation{
43+
Name: to.StringPtr(src.Name),
44+
Type: compute.ExtendedLocationTypes(src.Type),
45+
}
46+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
Copyright 2023 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package converters
18+
19+
import (
20+
"reflect"
21+
"testing"
22+
23+
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2021-11-01/compute"
24+
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-08-01/network"
25+
"github.com/Azure/go-autorest/autorest/to"
26+
infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
27+
)
28+
29+
func TestExtendedLocationToNetworkSDK(t *testing.T) {
30+
tests := []struct {
31+
name string
32+
args *infrav1.ExtendedLocationSpec
33+
want *network.ExtendedLocation
34+
}{
35+
{
36+
name: "normal extendedLocation instance",
37+
args: &infrav1.ExtendedLocationSpec{
38+
Name: "value",
39+
Type: "Edge",
40+
},
41+
want: &network.ExtendedLocation{
42+
Name: to.StringPtr("value"),
43+
Type: network.ExtendedLocationTypes("Edge"),
44+
},
45+
},
46+
{
47+
name: "nil extendedLocation properties",
48+
args: nil,
49+
want: nil,
50+
},
51+
}
52+
for _, tt := range tests {
53+
t.Run(tt.name, func(t *testing.T) {
54+
if got := ExtendedLocationToNetworkSDK(tt.args); !reflect.DeepEqual(got, tt.want) {
55+
t.Errorf("ExtendedLocationToNetworkSDK() = %v, want %v", got, tt.want)
56+
}
57+
})
58+
}
59+
}
60+
61+
func TestExtendedLocationToComputeSDK(t *testing.T) {
62+
tests := []struct {
63+
name string
64+
args *infrav1.ExtendedLocationSpec
65+
want *compute.ExtendedLocation
66+
}{
67+
{
68+
name: "normal extendedLocation instance",
69+
args: &infrav1.ExtendedLocationSpec{
70+
Name: "value",
71+
Type: "Edge",
72+
},
73+
want: &compute.ExtendedLocation{
74+
Name: to.StringPtr("value"),
75+
Type: compute.ExtendedLocationTypes("Edge"),
76+
},
77+
},
78+
{
79+
name: "nil extendedLocation properties",
80+
args: nil,
81+
want: nil,
82+
},
83+
}
84+
for _, tt := range tests {
85+
t.Run(tt.name, func(t *testing.T) {
86+
if got := ExtendedLocationToComputeSDK(tt.args); !reflect.DeepEqual(got, tt.want) {
87+
t.Errorf("ExtendedLocationToComputeSDK() = %v, want %v", got, tt.want)
88+
}
89+
})
90+
}
91+
}

0 commit comments

Comments
 (0)