Skip to content

Commit 4ea5509

Browse files
committed
Add vmsize clients based on armclient
1 parent c86d1ec commit 4ea5509

File tree

8 files changed

+457
-0
lines changed

8 files changed

+457
-0
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
2+
3+
go_library(
4+
name = "go_default_library",
5+
srcs = [
6+
"azure_virtualmachinesizeclient.go",
7+
"doc.go",
8+
"interface.go",
9+
],
10+
importmap = "k8s.io/kubernetes/vendor/k8s.io/legacy-cloud-providers/azure/clients/virtualmachinesizeclient",
11+
importpath = "k8s.io/legacy-cloud-providers/azure/clients/virtualmachinesizeclient",
12+
visibility = ["//visibility:public"],
13+
deps = [
14+
"//staging/src/k8s.io/client-go/util/flowcontrol:go_default_library",
15+
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients:go_default_library",
16+
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/armclient:go_default_library",
17+
"//staging/src/k8s.io/legacy-cloud-providers/azure/metrics:go_default_library",
18+
"//staging/src/k8s.io/legacy-cloud-providers/azure/retry:go_default_library",
19+
"//vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2019-06-01/network:go_default_library",
20+
"//vendor/github.com/Azure/go-autorest/autorest:go_default_library",
21+
"//vendor/github.com/Azure/go-autorest/autorest/azure:go_default_library",
22+
"//vendor/github.com/Azure/go-autorest/autorest/to:go_default_library",
23+
"//vendor/k8s.io/klog:go_default_library",
24+
],
25+
)
26+
27+
go_test(
28+
name = "go_default_test",
29+
srcs = ["azure_virtualmachinesizeclient_test.go"],
30+
embed = [":go_default_library"],
31+
deps = [
32+
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients:go_default_library",
33+
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/armclient:go_default_library",
34+
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/armclient/mockarmclient:go_default_library",
35+
"//vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2019-06-01/network:go_default_library",
36+
"//vendor/github.com/Azure/go-autorest/autorest:go_default_library",
37+
"//vendor/github.com/Azure/go-autorest/autorest/to:go_default_library",
38+
"//vendor/github.com/golang/mock/gomock:go_default_library",
39+
"//vendor/github.com/stretchr/testify/assert:go_default_library",
40+
],
41+
)
42+
43+
filegroup(
44+
name = "package-srcs",
45+
srcs = glob(["**"]),
46+
tags = ["automanaged"],
47+
visibility = ["//visibility:private"],
48+
)
49+
50+
filegroup(
51+
name = "all-srcs",
52+
srcs = [
53+
":package-srcs",
54+
"//staging/src/k8s.io/legacy-cloud-providers/azure/clients/virtualmachinesizeclient/mockvirtualmachinesizeclient:all-srcs",
55+
],
56+
tags = ["automanaged"],
57+
visibility = ["//visibility:public"],
58+
)
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
// +build !providerless
2+
3+
/*
4+
Copyright 2020 The Kubernetes Authors.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
package vmsizeclient
20+
21+
import (
22+
"context"
23+
"fmt"
24+
"net/http"
25+
"time"
26+
27+
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-07-01/compute"
28+
"github.com/Azure/go-autorest/autorest"
29+
"github.com/Azure/go-autorest/autorest/azure"
30+
31+
"k8s.io/client-go/util/flowcontrol"
32+
"k8s.io/klog"
33+
azclients "k8s.io/legacy-cloud-providers/azure/clients"
34+
"k8s.io/legacy-cloud-providers/azure/clients/armclient"
35+
"k8s.io/legacy-cloud-providers/azure/metrics"
36+
"k8s.io/legacy-cloud-providers/azure/retry"
37+
)
38+
39+
var _ Interface = &Client{}
40+
41+
// Client implements VirtualMachineSize client Interface.
42+
type Client struct {
43+
armClient armclient.Interface
44+
subscriptionID string
45+
46+
// Rate limiting configures.
47+
rateLimiterReader flowcontrol.RateLimiter
48+
rateLimiterWriter flowcontrol.RateLimiter
49+
50+
// ARM throttling configures.
51+
RetryAfterReader time.Time
52+
RetryAfterWriter time.Time
53+
}
54+
55+
// New creates a new VirtualMachineSize client with ratelimiting.
56+
func New(config *azclients.ClientConfig) *Client {
57+
baseURI := config.ResourceManagerEndpoint
58+
authorizer := autorest.NewBearerAuthorizer(config.ServicePrincipalToken)
59+
armClient := armclient.New(authorizer, baseURI, "", APIVersion, config.Location, config.Backoff)
60+
rateLimiterReader, rateLimiterWriter := azclients.NewRateLimiter(config.RateLimitConfig)
61+
62+
klog.V(2).Infof("Azure VirtualMachineSizesClient (read ops) using rate limit config: QPS=%g, bucket=%d",
63+
config.RateLimitConfig.CloudProviderRateLimitQPS,
64+
config.RateLimitConfig.CloudProviderRateLimitBucket)
65+
klog.V(2).Infof("Azure VirtualMachineSizesClient (write ops) using rate limit config: QPS=%g, bucket=%d",
66+
config.RateLimitConfig.CloudProviderRateLimitQPSWrite,
67+
config.RateLimitConfig.CloudProviderRateLimitBucketWrite)
68+
69+
client := &Client{
70+
armClient: armClient,
71+
rateLimiterReader: rateLimiterReader,
72+
rateLimiterWriter: rateLimiterWriter,
73+
subscriptionID: config.SubscriptionID,
74+
}
75+
76+
return client
77+
}
78+
79+
// List gets compute.VirtualMachineSizeListResult.
80+
func (c *Client) List(ctx context.Context, location string) (compute.VirtualMachineSizeListResult, *retry.Error) {
81+
mc := metrics.NewMetricContext("vmsizes", "list", "", c.subscriptionID, "")
82+
83+
// Report errors if the client is rate limited.
84+
if !c.rateLimiterReader.TryAccept() {
85+
mc.RateLimitedCount()
86+
return compute.VirtualMachineSizeListResult{}, retry.GetRateLimitError(false, "VMSizesList")
87+
}
88+
89+
// Report errors if the client is throttled.
90+
if c.RetryAfterReader.After(time.Now()) {
91+
mc.ThrottledCount()
92+
rerr := retry.GetThrottlingError("VMSizesList", "client throttled", c.RetryAfterReader)
93+
return compute.VirtualMachineSizeListResult{}, rerr
94+
}
95+
96+
result, rerr := c.listVirtualMachineSizes(ctx, location)
97+
mc.Observe(rerr.Error())
98+
if rerr != nil {
99+
if rerr.IsThrottled() {
100+
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
101+
c.RetryAfterReader = rerr.RetryAfter
102+
}
103+
104+
return result, rerr
105+
}
106+
107+
return result, nil
108+
}
109+
110+
// listVirtualMachineSizes gets compute.VirtualMachineSizeListResult.
111+
func (c *Client) listVirtualMachineSizes(ctx context.Context, location string) (compute.VirtualMachineSizeListResult, *retry.Error) {
112+
resourceID := fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Compute/locations/%s/vmSizes",
113+
autorest.Encode("path", c.subscriptionID),
114+
autorest.Encode("path", location),
115+
)
116+
117+
result := compute.VirtualMachineSizeListResult{}
118+
response, rerr := c.armClient.GetResource(ctx, resourceID, "")
119+
defer c.armClient.CloseResponse(ctx, response)
120+
if rerr != nil {
121+
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmsize.list.request", resourceID, rerr.Error())
122+
return result, rerr
123+
}
124+
125+
err := autorest.Respond(
126+
response,
127+
azure.WithErrorUnlessStatusCode(http.StatusOK),
128+
autorest.ByUnmarshallingJSON(&result))
129+
if err != nil {
130+
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmsize.list.respond", resourceID, err)
131+
return result, retry.GetError(response, err)
132+
}
133+
134+
result.Response = autorest.Response{Response: response}
135+
return result, nil
136+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// +build !providerless
2+
3+
/*
4+
Copyright 2020 The Kubernetes Authors.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
package vmsizeclient
20+
21+
import (
22+
"bytes"
23+
"context"
24+
"io/ioutil"
25+
"net/http"
26+
"testing"
27+
28+
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-07-01/compute"
29+
"github.com/Azure/go-autorest/autorest"
30+
"github.com/golang/mock/gomock"
31+
"github.com/stretchr/testify/assert"
32+
33+
azclients "k8s.io/legacy-cloud-providers/azure/clients"
34+
"k8s.io/legacy-cloud-providers/azure/clients/armclient"
35+
"k8s.io/legacy-cloud-providers/azure/clients/armclient/mockarmclient"
36+
)
37+
38+
func TestListNotFound(t *testing.T) {
39+
ctrl := gomock.NewController(t)
40+
defer ctrl.Finish()
41+
42+
resourceID := "/subscriptions/subscriptionID/providers/Microsoft.Compute/locations/eastus/vmSizes"
43+
response := &http.Response{
44+
StatusCode: http.StatusNotFound,
45+
Body: ioutil.NopCloser(bytes.NewReader([]byte("{}"))),
46+
}
47+
armClient := mockarmclient.NewMockInterface(ctrl)
48+
armClient.EXPECT().GetResource(gomock.Any(), resourceID, "").Return(response, nil).Times(1)
49+
armClient.EXPECT().CloseResponse(gomock.Any(), gomock.Any()).Times(1)
50+
51+
vmsizeClient := getTestVMSizeClient(armClient)
52+
expected := compute.VirtualMachineSizeListResult{Response: autorest.Response{}}
53+
result, rerr := vmsizeClient.List(context.TODO(), "eastus")
54+
assert.Equal(t, expected, result)
55+
assert.NotNil(t, rerr)
56+
assert.Equal(t, http.StatusNotFound, rerr.HTTPStatusCode)
57+
}
58+
59+
func TestListInternalError(t *testing.T) {
60+
ctrl := gomock.NewController(t)
61+
defer ctrl.Finish()
62+
63+
resourceID := "/subscriptions/subscriptionID/providers/Microsoft.Compute/locations/eastus/vmSizes"
64+
response := &http.Response{
65+
StatusCode: http.StatusInternalServerError,
66+
Body: ioutil.NopCloser(bytes.NewReader([]byte("{}"))),
67+
}
68+
armClient := mockarmclient.NewMockInterface(ctrl)
69+
armClient.EXPECT().GetResource(gomock.Any(), resourceID, "").Return(response, nil).Times(1)
70+
armClient.EXPECT().CloseResponse(gomock.Any(), gomock.Any()).Times(1)
71+
72+
vmsizeClient := getTestVMSizeClient(armClient)
73+
expected := compute.VirtualMachineSizeListResult{Response: autorest.Response{}}
74+
result, rerr := vmsizeClient.List(context.TODO(), "eastus")
75+
assert.Equal(t, expected, result)
76+
assert.NotNil(t, rerr)
77+
assert.Equal(t, http.StatusInternalServerError, rerr.HTTPStatusCode)
78+
}
79+
80+
func getTestVMSizeClient(armClient armclient.Interface) *Client {
81+
rateLimiterReader, rateLimiterWriter := azclients.NewRateLimiter(&azclients.RateLimitConfig{})
82+
return &Client{
83+
armClient: armClient,
84+
subscriptionID: "subscriptionID",
85+
rateLimiterReader: rateLimiterReader,
86+
rateLimiterWriter: rateLimiterWriter,
87+
}
88+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// +build !providerless
2+
3+
/*
4+
Copyright 2020 The Kubernetes Authors.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
// Package vmsizeclient implements the client for VirtualMachineSizes.
20+
package vmsizeclient // import "k8s.io/legacy-cloud-providers/azure/clients/vmsizeclient"
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// +build !providerless
2+
3+
/*
4+
Copyright 2020 The Kubernetes Authors.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
package vmsizeclient
20+
21+
import (
22+
"context"
23+
24+
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-07-01/compute"
25+
"k8s.io/legacy-cloud-providers/azure/retry"
26+
)
27+
28+
const (
29+
// APIVersion is the API version for compute.
30+
APIVersion = "2019-07-01"
31+
)
32+
33+
// Interface is the client interface for VirtualMachineSizes.
34+
// Don't forget to run the following command to generate the mock client:
35+
// mockgen -source=$GOPATH/src/k8s.io/kubernetes/staging/src/k8s.io/legacy-cloud-providers/azure/clients/vmsizeclient/interface.go -package=mockvmsizeclient Interface > $GOPATH/src/k8s.io/kubernetes/staging/src/k8s.io/legacy-cloud-providers/azure/clients/vmsizeclient/mockvmsizeclient/interface.go
36+
type Interface interface {
37+
// List gets compute.VirtualMachineSizeListResult.
38+
List(ctx context.Context, location string) (result compute.VirtualMachineSizeListResult, rerr *retry.Error)
39+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
load("@io_bazel_rules_go//go:def.bzl", "go_library")
2+
3+
go_library(
4+
name = "go_default_library",
5+
srcs = [
6+
"doc.go",
7+
"interface.go",
8+
],
9+
importmap = "k8s.io/kubernetes/vendor/k8s.io/legacy-cloud-providers/azure/clients/virtualmachinesizeclient/mockvirtualmachinesizeclient",
10+
importpath = "k8s.io/legacy-cloud-providers/azure/clients/virtualmachinesizeclient/mockvirtualmachinesizeclient",
11+
visibility = ["//visibility:public"],
12+
deps = [
13+
"//staging/src/k8s.io/legacy-cloud-providers/azure/retry:go_default_library",
14+
"//vendor/github.com/Azure/azure-sdk-for-go/services/network/mgmt/2019-06-01/network:go_default_library",
15+
"//vendor/github.com/golang/mock/gomock:go_default_library",
16+
],
17+
)
18+
19+
filegroup(
20+
name = "package-srcs",
21+
srcs = glob(["**"]),
22+
tags = ["automanaged"],
23+
visibility = ["//visibility:private"],
24+
)
25+
26+
filegroup(
27+
name = "all-srcs",
28+
srcs = [":package-srcs"],
29+
tags = ["automanaged"],
30+
visibility = ["//visibility:public"],
31+
)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// +build !providerless
2+
3+
/*
4+
Copyright 2020 The Kubernetes Authors.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
*/
18+
19+
// Package mockvmsizeclient implements the mock client for VirtualMachineSizes.
20+
package mockvmsizeclient // import "k8s.io/legacy-cloud-providers/azure/clients/virtualmachinesizeclient/mockvmsizeclient"

0 commit comments

Comments
 (0)