Skip to content

Commit

Permalink
Merge pull request #3857 from mboersma/sdk-v2-aks
Browse files Browse the repository at this point in the history
Convert managedclusters service to SDKv2
  • Loading branch information
k8s-ci-robot authored Aug 30, 2023
2 parents e9b10cd + 6f22051 commit 02ca989
Show file tree
Hide file tree
Showing 25 changed files with 771 additions and 645 deletions.
14 changes: 7 additions & 7 deletions api/v1beta1/azuremanagedmachinepool_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"context"
"testing"

"github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2022-03-01/containerservice"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4"
. "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -289,7 +289,7 @@ func TestAzureManagedMachinePoolUpdatingWebhook(t *testing.T) {
SKU: "StandardD2S_V3",
OSDiskSizeGB: ptr.To[int32](512),
MaxPods: ptr.To[int32](24),
OsDiskType: ptr.To(string(containerservice.OSDiskTypeEphemeral)),
OsDiskType: ptr.To(string(armcontainerservice.OSDiskTypeEphemeral)),
},
},
old: &AzureManagedMachinePool{
Expand All @@ -298,7 +298,7 @@ func TestAzureManagedMachinePoolUpdatingWebhook(t *testing.T) {
SKU: "StandardD2S_V3",
OSDiskSizeGB: ptr.To[int32](512),
MaxPods: ptr.To[int32](24),
OsDiskType: ptr.To(string(containerservice.OSDiskTypeManaged)),
OsDiskType: ptr.To(string(armcontainerservice.OSDiskTypeManaged)),
},
},
wantErr: true,
Expand Down Expand Up @@ -392,7 +392,7 @@ func TestAzureManagedMachinePoolUpdatingWebhook(t *testing.T) {
SKU: "StandardD2S_V3",
OSDiskSizeGB: ptr.To[int32](512),
MaxPods: ptr.To[int32](30),
OsDiskType: ptr.To(string(containerservice.OSDiskTypeManaged)),
OsDiskType: ptr.To(string(armcontainerservice.OSDiskTypeManaged)),
},
},
old: &AzureManagedMachinePool{
Expand All @@ -401,7 +401,7 @@ func TestAzureManagedMachinePoolUpdatingWebhook(t *testing.T) {
SKU: "StandardD2S_V3",
OSDiskSizeGB: ptr.To[int32](512),
MaxPods: ptr.To[int32](30),
OsDiskType: ptr.To(string(containerservice.OSDiskTypeManaged)),
OsDiskType: ptr.To(string(armcontainerservice.OSDiskTypeManaged)),
},
},
wantErr: false,
Expand Down Expand Up @@ -638,7 +638,7 @@ func TestAzureManagedMachinePool_ValidateCreate(t *testing.T) {
ammp: &AzureManagedMachinePool{
Spec: AzureManagedMachinePoolSpec{
MaxPods: ptr.To[int32](249),
OsDiskType: ptr.To(string(containerservice.OSDiskTypeManaged)),
OsDiskType: ptr.To(string(armcontainerservice.OSDiskTypeManaged)),
},
},
wantErr: false,
Expand Down Expand Up @@ -1292,7 +1292,7 @@ func getKnownValidAzureManagedMachinePool() *AzureManagedMachinePool {
return &AzureManagedMachinePool{
Spec: AzureManagedMachinePoolSpec{
MaxPods: ptr.To[int32](30),
OsDiskType: ptr.To(string(containerservice.OSDiskTypeEphemeral)),
OsDiskType: ptr.To(string(armcontainerservice.OSDiskTypeEphemeral)),
},
}
}
Expand Down
14 changes: 7 additions & 7 deletions azure/converters/managedagentpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@ limitations under the License.
package converters

import (
"github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2022-03-01/containerservice"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4"
)

// AgentPoolToManagedClusterAgentPoolProfile converts a AgentPoolSpec to an Azure SDK ManagedClusterAgentPoolProfile used in managedcluster reconcile.
func AgentPoolToManagedClusterAgentPoolProfile(pool containerservice.AgentPool) containerservice.ManagedClusterAgentPoolProfile {
properties := pool.ManagedClusterAgentPoolProfileProperties
agentPool := containerservice.ManagedClusterAgentPoolProfile{
func AgentPoolToManagedClusterAgentPoolProfile(pool armcontainerservice.AgentPool) armcontainerservice.ManagedClusterAgentPoolProfile {
properties := pool.Properties
agentPool := armcontainerservice.ManagedClusterAgentPoolProfile{
Name: pool.Name, // Note: if converting from agentPoolSpec.Parameters(), this field will not be set
VMSize: properties.VMSize,
OsType: properties.OsType,
OsDiskSizeGB: properties.OsDiskSizeGB,
OSType: properties.OSType,
OSDiskSizeGB: properties.OSDiskSizeGB,
Count: properties.Count,
Type: properties.Type,
OrchestratorVersion: properties.OrchestratorVersion,
Expand All @@ -39,7 +39,7 @@ func AgentPoolToManagedClusterAgentPoolProfile(pool containerservice.AgentPool)
NodeTaints: properties.NodeTaints,
AvailabilityZones: properties.AvailabilityZones,
MaxPods: properties.MaxPods,
OsDiskType: properties.OsDiskType,
OSDiskType: properties.OSDiskType,
NodeLabels: properties.NodeLabels,
EnableUltraSSD: properties.EnableUltraSSD,
EnableNodePublicIP: properties.EnableNodePublicIP,
Expand Down
43 changes: 21 additions & 22 deletions azure/converters/managedagentpool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,38 +19,37 @@ package converters
import (
"testing"

"github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2022-03-01/containerservice"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4"
. "github.com/onsi/gomega"
"k8s.io/utils/ptr"
"sigs.k8s.io/cluster-api-provider-azure/azure"
)

func Test_AgentPoolToManagedClusterAgentPoolProfile(t *testing.T) {
cases := []struct {
name string
pool containerservice.AgentPool
expect func(*GomegaWithT, containerservice.ManagedClusterAgentPoolProfile)
pool armcontainerservice.AgentPool
expect func(*GomegaWithT, armcontainerservice.ManagedClusterAgentPoolProfile)
}{
{
name: "Should set all values correctly",
pool: containerservice.AgentPool{
pool: armcontainerservice.AgentPool{
Name: ptr.To("agentpool1"),
ManagedClusterAgentPoolProfileProperties: &containerservice.ManagedClusterAgentPoolProfileProperties{
Properties: &armcontainerservice.ManagedClusterAgentPoolProfileProperties{
VMSize: ptr.To("Standard_D2s_v3"),
OsType: azure.LinuxOS,
OsDiskSizeGB: ptr.To[int32](100),
OSType: ptr.To(armcontainerservice.OSTypeLinux),
OSDiskSizeGB: ptr.To[int32](100),
Count: ptr.To[int32](2),
Type: containerservice.AgentPoolTypeVirtualMachineScaleSets,
Type: ptr.To(armcontainerservice.AgentPoolTypeVirtualMachineScaleSets),
OrchestratorVersion: ptr.To("1.22.6"),
VnetSubnetID: ptr.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-123/providers/Microsoft.Network/virtualNetworks/vnet-123/subnets/subnet-123"),
Mode: containerservice.AgentPoolModeUser,
Mode: ptr.To(armcontainerservice.AgentPoolModeUser),
EnableAutoScaling: ptr.To(true),
MaxCount: ptr.To[int32](5),
MinCount: ptr.To[int32](2),
NodeTaints: &[]string{"key1=value1:NoSchedule"},
AvailabilityZones: &[]string{"zone1"},
NodeTaints: []*string{ptr.To("key1=value1:NoSchedule")},
AvailabilityZones: []*string{ptr.To("zone1")},
MaxPods: ptr.To[int32](60),
OsDiskType: containerservice.OSDiskTypeManaged,
OSDiskType: ptr.To(armcontainerservice.OSDiskTypeManaged),
NodeLabels: map[string]*string{
"custom": ptr.To("default"),
},
Expand All @@ -61,24 +60,24 @@ func Test_AgentPoolToManagedClusterAgentPoolProfile(t *testing.T) {
},
},

expect: func(g *GomegaWithT, result containerservice.ManagedClusterAgentPoolProfile) {
g.Expect(result).To(Equal(containerservice.ManagedClusterAgentPoolProfile{
expect: func(g *GomegaWithT, result armcontainerservice.ManagedClusterAgentPoolProfile) {
g.Expect(result).To(Equal(armcontainerservice.ManagedClusterAgentPoolProfile{
Name: ptr.To("agentpool1"),
VMSize: ptr.To("Standard_D2s_v3"),
OsType: azure.LinuxOS,
OsDiskSizeGB: ptr.To[int32](100),
OSType: ptr.To(armcontainerservice.OSTypeLinux),
OSDiskSizeGB: ptr.To[int32](100),
Count: ptr.To[int32](2),
Type: containerservice.AgentPoolTypeVirtualMachineScaleSets,
Type: ptr.To(armcontainerservice.AgentPoolTypeVirtualMachineScaleSets),
OrchestratorVersion: ptr.To("1.22.6"),
VnetSubnetID: ptr.To("/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-123/providers/Microsoft.Network/virtualNetworks/vnet-123/subnets/subnet-123"),
Mode: containerservice.AgentPoolModeUser,
Mode: ptr.To(armcontainerservice.AgentPoolModeUser),
EnableAutoScaling: ptr.To(true),
MaxCount: ptr.To[int32](5),
MinCount: ptr.To[int32](2),
NodeTaints: &[]string{"key1=value1:NoSchedule"},
AvailabilityZones: &[]string{"zone1"},
NodeTaints: []*string{ptr.To("key1=value1:NoSchedule")},
AvailabilityZones: []*string{ptr.To("zone1")},
MaxPods: ptr.To[int32](60),
OsDiskType: containerservice.OSDiskTypeManaged,
OSDiskType: ptr.To(armcontainerservice.OSDiskTypeManaged),
NodeLabels: map[string]*string{
"custom": ptr.To("default"),
},
Expand Down
23 changes: 22 additions & 1 deletion azure/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ func UserAgent() string {
}

// ARMClientOptions returns default ARM client options for CAPZ SDK v2 requests.
func ARMClientOptions(azureEnvironment string) (*arm.ClientOptions, error) {
func ARMClientOptions(azureEnvironment string, extraPolicies ...policy.Policy) (*arm.ClientOptions, error) {
opts := &arm.ClientOptions{}

switch azureEnvironment {
Expand All @@ -357,6 +357,7 @@ func ARMClientOptions(azureEnvironment string) (*arm.ClientOptions, error) {
correlationIDPolicy{},
userAgentPolicy{},
}
opts.PerCallPolicies = append(opts.PerCallPolicies, extraPolicies...)
opts.Retry.MaxRetries = -1 // Less than zero means one try and no retries.

return opts, nil
Expand Down Expand Up @@ -384,6 +385,26 @@ func (p userAgentPolicy) Do(req *policy.Request) (*http.Response, error) {
return req.Next()
}

// CustomPutPatchHeaderPolicy adds custom headers to a PUT or PATCH request.
// It implements the policy.Policy interface.
type CustomPutPatchHeaderPolicy struct {
Getter ResourceSpecGetter
}

// Do adds any custom headers to a PUT or PATCH request.
func (p CustomPutPatchHeaderPolicy) Do(req *policy.Request) (*http.Response, error) {
if req.Raw().Method == http.MethodPut || req.Raw().Method == http.MethodPatch {
headerSpec, ok := p.Getter.(ResourceSpecGetterWithHeaders)
if ok {
for key, element := range headerSpec.CustomHeaders() {
req.Raw().Header.Set(key, element)
}
}
}

return req.Next()
}

// SetAutoRestClientDefaults set authorizer and user agent for autorest client.
func SetAutoRestClientDefaults(c *autorest.Client, auth autorest.Authorizer) {
c.Authorizer = auth
Expand Down
86 changes: 86 additions & 0 deletions azure/defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/Azure/go-autorest/autorest"
. "github.com/onsi/gomega"
"go.uber.org/mock/gomock"
"sigs.k8s.io/cluster-api-provider-azure/azure/mock_azure"
"sigs.k8s.io/cluster-api-provider-azure/util/tele"
)

Expand Down Expand Up @@ -118,6 +120,90 @@ func TestPerCallPolicies(t *testing.T) {
g.Expect(resp.StatusCode).To(Equal(http.StatusOK))
}

func TestCustomPutPatchHeaderPolicy(t *testing.T) {
testHeaders := map[string]string{
"X-Test-Header": "test-value",
"X-Test-Header2": "test-value2",
}
testcases := []struct {
name string
method string
headers map[string]string
expected map[string]string
}{
{
name: "should add custom headers to PUT request",
method: http.MethodPut,
headers: testHeaders,
expected: testHeaders,
},
{
name: "should add custom headers to PATCH request",
method: http.MethodPatch,
headers: testHeaders,
expected: testHeaders,
},
{
name: "should skip empty custom headers for PUT request",
method: http.MethodPut,
},
{
name: "should skip empty custom headers for PATCH request",
method: http.MethodPatch,
},
{
name: "should skip empty custom headers for GET request",
method: http.MethodGet,
},
{
name: "should not add custom headers to GET request",
method: http.MethodGet,
headers: testHeaders,
},
{
name: "should not add custom headers to POST request",
method: http.MethodPost,
headers: testHeaders,
},
}
for _, tc := range testcases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
g := NewWithT(t)

mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

// This server will check that custom headers are set correctly.
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
for k, v := range tc.expected {
g.Expect(r.Header.Get(k)).To(Equal(v))
}
fmt.Fprintf(w, "Hello, %s", r.Proto)
}))
defer server.Close()

// Create options with a custom PUT/PATCH header per-call policy
getterMock := mock_azure.NewMockResourceSpecGetterWithHeaders(mockCtrl)
getterMock.EXPECT().CustomHeaders().Return(tc.headers).AnyTimes()
opts, err := ARMClientOptions("", CustomPutPatchHeaderPolicy{Getter: getterMock})
g.Expect(err).NotTo(HaveOccurred())

// Create a request
req, err := runtime.NewRequest(context.Background(), tc.method, server.URL)
g.Expect(err).NotTo(HaveOccurred())

// Create a pipeline and send the request to the test server for validation.
pipeline := defaultTestPipeline(opts.PerCallPolicies)
resp, err := pipeline.Do(req)
g.Expect(err).NotTo(HaveOccurred())
defer resp.Body.Close()
g.Expect(resp.StatusCode).To(Equal(http.StatusOK))
})
}
}

func defaultTestPipeline(policies []policy.Policy) runtime.Pipeline {
return runtime.NewPipeline(
"testmodule",
Expand Down
22 changes: 22 additions & 0 deletions azure/pointers.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,28 @@ func StringSlice(s *[]string) []string {
return nil
}

// PtrSlice returns a slice of pointers from a pointer to a slice. It returns nil if the
// pointer is nil or the slice pointed to is empty.
func PtrSlice[T any](p *[]T) []*T {
if p == nil || len(*p) == 0 {
return nil
}
s := make([]*T, 0, len(*p))
for _, v := range *p {
s = append(s, ptr.To(v))
}
return s
}

// AliasOrNil returns a pointer to a string-derived type from a passed string pointer,
// or nil if the pointer is nil or an empty string.
func AliasOrNil[T ~string](s *string) *T {
if s == nil || *s == "" {
return nil
}
return ptr.To(T(*s))
}

// StringMapPtr converts a map[string]string into a map[string]*string. It returns nil if the map is nil.
func StringMapPtr(m map[string]string) map[string]*string {
if m == nil {
Expand Down
Loading

0 comments on commit 02ca989

Please sign in to comment.