Merge pull request #4689 from gandhipr/prachigandhi-Fix-invalidMetadataUrl-add-getSubscriptionIdFromInstanceMetadata
FixBug-invalidMetadataUrl-add-getSubscriptionIdFromInstanceMetadata
This commit is contained in:
commit
c22e6f1a54
|
|
@ -23,6 +23,7 @@ import (
|
|||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -31,6 +32,7 @@ import (
|
|||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"k8s.io/klog/v2"
|
||||
azclients "sigs.k8s.io/cloud-provider-azure/pkg/azureclients"
|
||||
providerazure "sigs.k8s.io/cloud-provider-azure/pkg/provider"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
|
|
@ -38,7 +40,7 @@ const (
|
|||
// The path of deployment parameters for standard vm.
|
||||
deploymentParametersPath = "/var/lib/azure/azuredeploy.parameters.json"
|
||||
|
||||
metadataURL = "http://169.254.169.254/metadata/instance"
|
||||
imdsServerURL = "http://169.254.169.254"
|
||||
|
||||
// backoff
|
||||
backoffRetriesDefault = 6
|
||||
|
|
@ -146,7 +148,6 @@ func BuildAzureConfig(configReader io.Reader) (*Config, error) {
|
|||
cfg.Cloud = os.Getenv("ARM_CLOUD")
|
||||
cfg.Location = os.Getenv("LOCATION")
|
||||
cfg.ResourceGroup = os.Getenv("ARM_RESOURCE_GROUP")
|
||||
cfg.SubscriptionID = os.Getenv("ARM_SUBSCRIPTION_ID")
|
||||
cfg.TenantID = os.Getenv("ARM_TENANT_ID")
|
||||
cfg.AADClientID = os.Getenv("ARM_CLIENT_ID")
|
||||
cfg.AADClientSecret = os.Getenv("ARM_CLIENT_SECRET")
|
||||
|
|
@ -157,6 +158,12 @@ func BuildAzureConfig(configReader io.Reader) (*Config, error) {
|
|||
cfg.ClusterName = os.Getenv("AZURE_CLUSTER_NAME")
|
||||
cfg.NodeResourceGroup = os.Getenv("AZURE_NODE_RESOURCE_GROUP")
|
||||
|
||||
subscriptionID, err := getSubscriptionIdFromInstanceMetadata()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cfg.SubscriptionID = subscriptionID
|
||||
|
||||
useManagedIdentityExtensionFromEnv := os.Getenv("ARM_USE_MANAGED_IDENTITY_EXTENSION")
|
||||
if len(useManagedIdentityExtensionFromEnv) > 0 {
|
||||
cfg.UseManagedIdentityExtension, err = strconv.ParseBool(useManagedIdentityExtensionFromEnv)
|
||||
|
|
@ -473,3 +480,22 @@ func (cfg *Config) validate() error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getSubscriptionId reads the Subscription ID from the instance metadata.
|
||||
func getSubscriptionIdFromInstanceMetadata() (string, error) {
|
||||
subscriptionID, present := os.LookupEnv("ARM_SUBSCRIPTION_ID")
|
||||
if !present {
|
||||
metadataService, err := providerazure.NewInstanceMetadataService(imdsServerURL)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
metadata, err := metadataService.GetMetadata(0)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return metadata.Compute.SubscriptionID, nil
|
||||
}
|
||||
return subscriptionID, nil
|
||||
}
|
||||
|
|
|
|||
9
cluster-autoscaler/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns/CHANGELOG.md
generated
vendored
Normal file
9
cluster-autoscaler/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns/CHANGELOG.md
generated
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Change History
|
||||
|
||||
## Additive Changes
|
||||
|
||||
### New Funcs
|
||||
|
||||
1. PrivateZoneProperties.MarshalJSON() ([]byte, error)
|
||||
1. ProxyResource.MarshalJSON() ([]byte, error)
|
||||
1. Resource.MarshalJSON() ([]byte, error)
|
||||
11
cluster-autoscaler/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns/_meta.json
generated
vendored
Normal file
11
cluster-autoscaler/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns/_meta.json
generated
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"commit": "3c764635e7d442b3e74caf593029fcd440b3ef82",
|
||||
"readme": "/_/azure-rest-api-specs/specification/privatedns/resource-manager/readme.md",
|
||||
"tag": "package-2018-09",
|
||||
"use": "@microsoft.azure/autorest.go@2.1.183",
|
||||
"repository_url": "https://github.com/Azure/azure-rest-api-specs.git",
|
||||
"autorest_command": "autorest --use=@microsoft.azure/autorest.go@2.1.183 --tag=package-2018-09 --go-sdk-folder=/_/azure-sdk-for-go --go --verbose --use-onever --version=V2 --go.license-header=MICROSOFT_MIT_NO_VERSION /_/azure-rest-api-specs/specification/privatedns/resource-manager/readme.md",
|
||||
"additional_properties": {
|
||||
"additional_options": "--go --verbose --use-onever --version=V2 --go.license-header=MICROSOFT_MIT_NO_VERSION"
|
||||
}
|
||||
}
|
||||
41
cluster-autoscaler/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns/client.go
generated
vendored
Normal file
41
cluster-autoscaler/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns/client.go
generated
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// Package privatedns implements the Azure ARM Privatedns service API version 2018-09-01.
|
||||
//
|
||||
// The Private DNS Management Client.
|
||||
package privatedns
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
//
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultBaseURI is the default URI used for the service Privatedns
|
||||
DefaultBaseURI = "https://management.azure.com"
|
||||
)
|
||||
|
||||
// BaseClient is the base client for Privatedns.
|
||||
type BaseClient struct {
|
||||
autorest.Client
|
||||
BaseURI string
|
||||
SubscriptionID string
|
||||
}
|
||||
|
||||
// New creates an instance of the BaseClient client.
|
||||
func New(subscriptionID string) BaseClient {
|
||||
return NewWithBaseURI(DefaultBaseURI, subscriptionID)
|
||||
}
|
||||
|
||||
// NewWithBaseURI creates an instance of the BaseClient client using a custom endpoint. Use this when interacting with
|
||||
// an Azure cloud that uses a non-standard base URI (sovereign clouds, Azure stack).
|
||||
func NewWithBaseURI(baseURI string, subscriptionID string) BaseClient {
|
||||
return BaseClient{
|
||||
Client: autorest.NewClientWithUserAgent(UserAgent()),
|
||||
BaseURI: baseURI,
|
||||
SubscriptionID: subscriptionID,
|
||||
}
|
||||
}
|
||||
72
cluster-autoscaler/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns/enums.go
generated
vendored
Normal file
72
cluster-autoscaler/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns/enums.go
generated
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
package privatedns
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
//
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
// ProvisioningState enumerates the values for provisioning state.
|
||||
type ProvisioningState string
|
||||
|
||||
const (
|
||||
// Canceled ...
|
||||
Canceled ProvisioningState = "Canceled"
|
||||
// Creating ...
|
||||
Creating ProvisioningState = "Creating"
|
||||
// Deleting ...
|
||||
Deleting ProvisioningState = "Deleting"
|
||||
// Failed ...
|
||||
Failed ProvisioningState = "Failed"
|
||||
// Succeeded ...
|
||||
Succeeded ProvisioningState = "Succeeded"
|
||||
// Updating ...
|
||||
Updating ProvisioningState = "Updating"
|
||||
)
|
||||
|
||||
// PossibleProvisioningStateValues returns an array of possible values for the ProvisioningState const type.
|
||||
func PossibleProvisioningStateValues() []ProvisioningState {
|
||||
return []ProvisioningState{Canceled, Creating, Deleting, Failed, Succeeded, Updating}
|
||||
}
|
||||
|
||||
// RecordType enumerates the values for record type.
|
||||
type RecordType string
|
||||
|
||||
const (
|
||||
// A ...
|
||||
A RecordType = "A"
|
||||
// AAAA ...
|
||||
AAAA RecordType = "AAAA"
|
||||
// CNAME ...
|
||||
CNAME RecordType = "CNAME"
|
||||
// MX ...
|
||||
MX RecordType = "MX"
|
||||
// PTR ...
|
||||
PTR RecordType = "PTR"
|
||||
// SOA ...
|
||||
SOA RecordType = "SOA"
|
||||
// SRV ...
|
||||
SRV RecordType = "SRV"
|
||||
// TXT ...
|
||||
TXT RecordType = "TXT"
|
||||
)
|
||||
|
||||
// PossibleRecordTypeValues returns an array of possible values for the RecordType const type.
|
||||
func PossibleRecordTypeValues() []RecordType {
|
||||
return []RecordType{A, AAAA, CNAME, MX, PTR, SOA, SRV, TXT}
|
||||
}
|
||||
|
||||
// VirtualNetworkLinkState enumerates the values for virtual network link state.
|
||||
type VirtualNetworkLinkState string
|
||||
|
||||
const (
|
||||
// Completed ...
|
||||
Completed VirtualNetworkLinkState = "Completed"
|
||||
// InProgress ...
|
||||
InProgress VirtualNetworkLinkState = "InProgress"
|
||||
)
|
||||
|
||||
// PossibleVirtualNetworkLinkStateValues returns an array of possible values for the VirtualNetworkLinkState const type.
|
||||
func PossibleVirtualNetworkLinkStateValues() []VirtualNetworkLinkState {
|
||||
return []VirtualNetworkLinkState{Completed, InProgress}
|
||||
}
|
||||
1350
cluster-autoscaler/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns/models.go
generated
vendored
Normal file
1350
cluster-autoscaler/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns/models.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
611
cluster-autoscaler/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns/privatezones.go
generated
vendored
Normal file
611
cluster-autoscaler/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns/privatezones.go
generated
vendored
Normal file
|
|
@ -0,0 +1,611 @@
|
|||
package privatedns
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
//
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/tracing"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// PrivateZonesClient is the the Private DNS Management Client.
|
||||
type PrivateZonesClient struct {
|
||||
BaseClient
|
||||
}
|
||||
|
||||
// NewPrivateZonesClient creates an instance of the PrivateZonesClient client.
|
||||
func NewPrivateZonesClient(subscriptionID string) PrivateZonesClient {
|
||||
return NewPrivateZonesClientWithBaseURI(DefaultBaseURI, subscriptionID)
|
||||
}
|
||||
|
||||
// NewPrivateZonesClientWithBaseURI creates an instance of the PrivateZonesClient client using a custom endpoint. Use
|
||||
// this when interacting with an Azure cloud that uses a non-standard base URI (sovereign clouds, Azure stack).
|
||||
func NewPrivateZonesClientWithBaseURI(baseURI string, subscriptionID string) PrivateZonesClient {
|
||||
return PrivateZonesClient{NewWithBaseURI(baseURI, subscriptionID)}
|
||||
}
|
||||
|
||||
// CreateOrUpdate creates or updates a Private DNS zone. Does not modify Links to virtual networks or DNS records
|
||||
// within the zone.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group.
|
||||
// privateZoneName - the name of the Private DNS zone (without a terminating dot).
|
||||
// parameters - parameters supplied to the CreateOrUpdate operation.
|
||||
// ifMatch - the ETag of the Private DNS zone. Omit this value to always overwrite the current zone. Specify
|
||||
// the last-seen ETag value to prevent accidentally overwriting any concurrent changes.
|
||||
// ifNoneMatch - set to '*' to allow a new Private DNS zone to be created, but to prevent updating an existing
|
||||
// zone. Other values will be ignored.
|
||||
func (client PrivateZonesClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, privateZoneName string, parameters PrivateZone, ifMatch string, ifNoneMatch string) (result PrivateZonesCreateOrUpdateFuture, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/PrivateZonesClient.CreateOrUpdate")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.FutureAPI != nil && result.FutureAPI.Response() != nil {
|
||||
sc = result.FutureAPI.Response().StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, privateZoneName, parameters, ifMatch, ifNoneMatch)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "CreateOrUpdate", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.CreateOrUpdateSender(req)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "CreateOrUpdate", nil, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// CreateOrUpdatePreparer prepares the CreateOrUpdate request.
|
||||
func (client PrivateZonesClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, privateZoneName string, parameters PrivateZone, ifMatch string, ifNoneMatch string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"privateZoneName": autorest.Encode("path", privateZoneName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2018-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPut(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
if len(ifMatch) > 0 {
|
||||
preparer = autorest.DecoratePreparer(preparer,
|
||||
autorest.WithHeader("If-Match", autorest.String(ifMatch)))
|
||||
}
|
||||
if len(ifNoneMatch) > 0 {
|
||||
preparer = autorest.DecoratePreparer(preparer,
|
||||
autorest.WithHeader("If-None-Match", autorest.String(ifNoneMatch)))
|
||||
}
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client PrivateZonesClient) CreateOrUpdateSender(req *http.Request) (future PrivateZonesCreateOrUpdateFuture, err error) {
|
||||
var resp *http.Response
|
||||
resp, err = client.Send(req, azure.DoRetryWithRegistration(client.Client))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var azf azure.Future
|
||||
azf, err = azure.NewFutureFromResponse(resp)
|
||||
future.FutureAPI = &azf
|
||||
future.Result = future.result
|
||||
return
|
||||
}
|
||||
|
||||
// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client PrivateZonesClient) CreateOrUpdateResponder(resp *http.Response) (result PrivateZone, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated, http.StatusAccepted),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// Delete deletes a Private DNS zone. WARNING: All DNS records in the zone will also be deleted. This operation cannot
|
||||
// be undone. Private DNS zone cannot be deleted unless all virtual network links to it are removed.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group.
|
||||
// privateZoneName - the name of the Private DNS zone (without a terminating dot).
|
||||
// ifMatch - the ETag of the Private DNS zone. Omit this value to always delete the current zone. Specify the
|
||||
// last-seen ETag value to prevent accidentally deleting any concurrent changes.
|
||||
func (client PrivateZonesClient) Delete(ctx context.Context, resourceGroupName string, privateZoneName string, ifMatch string) (result PrivateZonesDeleteFuture, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/PrivateZonesClient.Delete")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.FutureAPI != nil && result.FutureAPI.Response() != nil {
|
||||
sc = result.FutureAPI.Response().StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
req, err := client.DeletePreparer(ctx, resourceGroupName, privateZoneName, ifMatch)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "Delete", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.DeleteSender(req)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "Delete", nil, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// DeletePreparer prepares the Delete request.
|
||||
func (client PrivateZonesClient) DeletePreparer(ctx context.Context, resourceGroupName string, privateZoneName string, ifMatch string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"privateZoneName": autorest.Encode("path", privateZoneName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2018-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsDelete(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
if len(ifMatch) > 0 {
|
||||
preparer = autorest.DecoratePreparer(preparer,
|
||||
autorest.WithHeader("If-Match", autorest.String(ifMatch)))
|
||||
}
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// DeleteSender sends the Delete request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client PrivateZonesClient) DeleteSender(req *http.Request) (future PrivateZonesDeleteFuture, err error) {
|
||||
var resp *http.Response
|
||||
resp, err = client.Send(req, azure.DoRetryWithRegistration(client.Client))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var azf azure.Future
|
||||
azf, err = azure.NewFutureFromResponse(resp)
|
||||
future.FutureAPI = &azf
|
||||
future.Result = future.result
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteResponder handles the response to the Delete request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client PrivateZonesClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent),
|
||||
autorest.ByClosing())
|
||||
result.Response = resp
|
||||
return
|
||||
}
|
||||
|
||||
// Get gets a Private DNS zone. Retrieves the zone properties, but not the virtual networks links or the record sets
|
||||
// within the zone.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group.
|
||||
// privateZoneName - the name of the Private DNS zone (without a terminating dot).
|
||||
func (client PrivateZonesClient) Get(ctx context.Context, resourceGroupName string, privateZoneName string) (result PrivateZone, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/PrivateZonesClient.Get")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.Response.Response != nil {
|
||||
sc = result.Response.Response.StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
req, err := client.GetPreparer(ctx, resourceGroupName, privateZoneName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "Get", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.GetSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "Get", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.GetResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "Get", resp, "Failure responding to request")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GetPreparer prepares the Get request.
|
||||
func (client PrivateZonesClient) GetPreparer(ctx context.Context, resourceGroupName string, privateZoneName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"privateZoneName": autorest.Encode("path", privateZoneName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2018-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// GetSender sends the Get request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client PrivateZonesClient) GetSender(req *http.Request) (*http.Response, error) {
|
||||
return client.Send(req, azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// GetResponder handles the response to the Get request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client PrivateZonesClient) GetResponder(resp *http.Response) (result PrivateZone, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// List lists the Private DNS zones in all resource groups in a subscription.
|
||||
// Parameters:
|
||||
// top - the maximum number of Private DNS zones to return. If not specified, returns up to 100 zones.
|
||||
func (client PrivateZonesClient) List(ctx context.Context, top *int32) (result PrivateZoneListResultPage, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/PrivateZonesClient.List")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.pzlr.Response.Response != nil {
|
||||
sc = result.pzlr.Response.Response.StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
result.fn = client.listNextResults
|
||||
req, err := client.ListPreparer(ctx, top)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "List", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.ListSender(req)
|
||||
if err != nil {
|
||||
result.pzlr.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "List", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result.pzlr, err = client.ListResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "List", resp, "Failure responding to request")
|
||||
return
|
||||
}
|
||||
if result.pzlr.hasNextLink() && result.pzlr.IsEmpty() {
|
||||
err = result.NextWithContext(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ListPreparer prepares the List request.
|
||||
func (client PrivateZonesClient) ListPreparer(ctx context.Context, top *int32) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2018-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
if top != nil {
|
||||
queryParameters["$top"] = autorest.Encode("query", *top)
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Network/privateDnsZones", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// ListSender sends the List request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client PrivateZonesClient) ListSender(req *http.Request) (*http.Response, error) {
|
||||
return client.Send(req, azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// ListResponder handles the response to the List request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client PrivateZonesClient) ListResponder(resp *http.Response) (result PrivateZoneListResult, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// listNextResults retrieves the next set of results, if any.
|
||||
func (client PrivateZonesClient) listNextResults(ctx context.Context, lastResults PrivateZoneListResult) (result PrivateZoneListResult, err error) {
|
||||
req, err := lastResults.privateZoneListResultPreparer(ctx)
|
||||
if err != nil {
|
||||
return result, autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "listNextResults", nil, "Failure preparing next results request")
|
||||
}
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
resp, err := client.ListSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "listNextResults", resp, "Failure sending next results request")
|
||||
}
|
||||
result, err = client.ListResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "listNextResults", resp, "Failure responding to next results request")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ListComplete enumerates all values, automatically crossing page boundaries as required.
|
||||
func (client PrivateZonesClient) ListComplete(ctx context.Context, top *int32) (result PrivateZoneListResultIterator, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/PrivateZonesClient.List")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.Response().Response.Response != nil {
|
||||
sc = result.page.Response().Response.Response.StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
result.page, err = client.List(ctx, top)
|
||||
return
|
||||
}
|
||||
|
||||
// ListByResourceGroup lists the Private DNS zones within a resource group.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group.
|
||||
// top - the maximum number of record sets to return. If not specified, returns up to 100 record sets.
|
||||
func (client PrivateZonesClient) ListByResourceGroup(ctx context.Context, resourceGroupName string, top *int32) (result PrivateZoneListResultPage, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/PrivateZonesClient.ListByResourceGroup")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.pzlr.Response.Response != nil {
|
||||
sc = result.pzlr.Response.Response.StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
result.fn = client.listByResourceGroupNextResults
|
||||
req, err := client.ListByResourceGroupPreparer(ctx, resourceGroupName, top)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "ListByResourceGroup", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.ListByResourceGroupSender(req)
|
||||
if err != nil {
|
||||
result.pzlr.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "ListByResourceGroup", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result.pzlr, err = client.ListByResourceGroupResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "ListByResourceGroup", resp, "Failure responding to request")
|
||||
return
|
||||
}
|
||||
if result.pzlr.hasNextLink() && result.pzlr.IsEmpty() {
|
||||
err = result.NextWithContext(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ListByResourceGroupPreparer prepares the ListByResourceGroup request.
|
||||
func (client PrivateZonesClient) ListByResourceGroupPreparer(ctx context.Context, resourceGroupName string, top *int32) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2018-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
if top != nil {
|
||||
queryParameters["$top"] = autorest.Encode("query", *top)
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client PrivateZonesClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) {
|
||||
return client.Send(req, azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client PrivateZonesClient) ListByResourceGroupResponder(resp *http.Response) (result PrivateZoneListResult, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// listByResourceGroupNextResults retrieves the next set of results, if any.
|
||||
func (client PrivateZonesClient) listByResourceGroupNextResults(ctx context.Context, lastResults PrivateZoneListResult) (result PrivateZoneListResult, err error) {
|
||||
req, err := lastResults.privateZoneListResultPreparer(ctx)
|
||||
if err != nil {
|
||||
return result, autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "listByResourceGroupNextResults", nil, "Failure preparing next results request")
|
||||
}
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
resp, err := client.ListByResourceGroupSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "listByResourceGroupNextResults", resp, "Failure sending next results request")
|
||||
}
|
||||
result, err = client.ListByResourceGroupResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "listByResourceGroupNextResults", resp, "Failure responding to next results request")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ListByResourceGroupComplete enumerates all values, automatically crossing page boundaries as required.
|
||||
func (client PrivateZonesClient) ListByResourceGroupComplete(ctx context.Context, resourceGroupName string, top *int32) (result PrivateZoneListResultIterator, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/PrivateZonesClient.ListByResourceGroup")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.Response().Response.Response != nil {
|
||||
sc = result.page.Response().Response.Response.StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
result.page, err = client.ListByResourceGroup(ctx, resourceGroupName, top)
|
||||
return
|
||||
}
|
||||
|
||||
// Update updates a Private DNS zone. Does not modify virtual network links or DNS records within the zone.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group.
|
||||
// privateZoneName - the name of the Private DNS zone (without a terminating dot).
|
||||
// parameters - parameters supplied to the Update operation.
|
||||
// ifMatch - the ETag of the Private DNS zone. Omit this value to always overwrite the current zone. Specify
|
||||
// the last-seen ETag value to prevent accidentally overwriting any concurrent changes.
|
||||
func (client PrivateZonesClient) Update(ctx context.Context, resourceGroupName string, privateZoneName string, parameters PrivateZone, ifMatch string) (result PrivateZonesUpdateFuture, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/PrivateZonesClient.Update")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.FutureAPI != nil && result.FutureAPI.Response() != nil {
|
||||
sc = result.FutureAPI.Response().StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
req, err := client.UpdatePreparer(ctx, resourceGroupName, privateZoneName, parameters, ifMatch)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "Update", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.UpdateSender(req)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.PrivateZonesClient", "Update", nil, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// UpdatePreparer prepares the Update request.
|
||||
func (client PrivateZonesClient) UpdatePreparer(ctx context.Context, resourceGroupName string, privateZoneName string, parameters PrivateZone, ifMatch string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"privateZoneName": autorest.Encode("path", privateZoneName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2018-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPatch(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
if len(ifMatch) > 0 {
|
||||
preparer = autorest.DecoratePreparer(preparer,
|
||||
autorest.WithHeader("If-Match", autorest.String(ifMatch)))
|
||||
}
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// UpdateSender sends the Update request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client PrivateZonesClient) UpdateSender(req *http.Request) (future PrivateZonesUpdateFuture, err error) {
|
||||
var resp *http.Response
|
||||
resp, err = client.Send(req, azure.DoRetryWithRegistration(client.Client))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var azf azure.Future
|
||||
azf, err = azure.NewFutureFromResponse(resp)
|
||||
future.FutureAPI = &azf
|
||||
future.Result = future.result
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateResponder handles the response to the Update request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client PrivateZonesClient) UpdateResponder(resp *http.Response) (result PrivateZone, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
640
cluster-autoscaler/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns/recordsets.go
generated
vendored
Normal file
640
cluster-autoscaler/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns/recordsets.go
generated
vendored
Normal file
|
|
@ -0,0 +1,640 @@
|
|||
package privatedns
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
//
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/tracing"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// RecordSetsClient is the the Private DNS Management Client.
|
||||
type RecordSetsClient struct {
|
||||
BaseClient
|
||||
}
|
||||
|
||||
// NewRecordSetsClient creates an instance of the RecordSetsClient client.
|
||||
func NewRecordSetsClient(subscriptionID string) RecordSetsClient {
|
||||
return NewRecordSetsClientWithBaseURI(DefaultBaseURI, subscriptionID)
|
||||
}
|
||||
|
||||
// NewRecordSetsClientWithBaseURI creates an instance of the RecordSetsClient client using a custom endpoint. Use this
|
||||
// when interacting with an Azure cloud that uses a non-standard base URI (sovereign clouds, Azure stack).
|
||||
func NewRecordSetsClientWithBaseURI(baseURI string, subscriptionID string) RecordSetsClient {
|
||||
return RecordSetsClient{NewWithBaseURI(baseURI, subscriptionID)}
|
||||
}
|
||||
|
||||
// CreateOrUpdate creates or updates a record set within a Private DNS zone.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group.
|
||||
// privateZoneName - the name of the Private DNS zone (without a terminating dot).
|
||||
// recordType - the type of DNS record in this record set. Record sets of type SOA can be updated but not
|
||||
// created (they are created when the Private DNS zone is created).
|
||||
// relativeRecordSetName - the name of the record set, relative to the name of the zone.
|
||||
// parameters - parameters supplied to the CreateOrUpdate operation.
|
||||
// ifMatch - the ETag of the record set. Omit this value to always overwrite the current record set. Specify
|
||||
// the last-seen ETag value to prevent accidentally overwriting any concurrent changes.
|
||||
// ifNoneMatch - set to '*' to allow a new record set to be created, but to prevent updating an existing record
|
||||
// set. Other values will be ignored.
|
||||
func (client RecordSetsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, relativeRecordSetName string, parameters RecordSet, ifMatch string, ifNoneMatch string) (result RecordSet, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.CreateOrUpdate")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.Response.Response != nil {
|
||||
sc = result.Response.Response.StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, privateZoneName, recordType, relativeRecordSetName, parameters, ifMatch, ifNoneMatch)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "CreateOrUpdate", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.CreateOrUpdateSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "CreateOrUpdate", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.CreateOrUpdateResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "CreateOrUpdate", resp, "Failure responding to request")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// CreateOrUpdatePreparer prepares the CreateOrUpdate request.
|
||||
func (client RecordSetsClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, relativeRecordSetName string, parameters RecordSet, ifMatch string, ifNoneMatch string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"privateZoneName": autorest.Encode("path", privateZoneName),
|
||||
"recordType": autorest.Encode("path", recordType),
|
||||
"relativeRecordSetName": relativeRecordSetName,
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2018-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPut(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/{recordType}/{relativeRecordSetName}", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
if len(ifMatch) > 0 {
|
||||
preparer = autorest.DecoratePreparer(preparer,
|
||||
autorest.WithHeader("If-Match", autorest.String(ifMatch)))
|
||||
}
|
||||
if len(ifNoneMatch) > 0 {
|
||||
preparer = autorest.DecoratePreparer(preparer,
|
||||
autorest.WithHeader("If-None-Match", autorest.String(ifNoneMatch)))
|
||||
}
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client RecordSetsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) {
|
||||
return client.Send(req, azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client RecordSetsClient) CreateOrUpdateResponder(resp *http.Response) (result RecordSet, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// Delete deletes a record set from a Private DNS zone. This operation cannot be undone.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group.
|
||||
// privateZoneName - the name of the Private DNS zone (without a terminating dot).
|
||||
// recordType - the type of DNS record in this record set. Record sets of type SOA cannot be deleted (they are
|
||||
// deleted when the Private DNS zone is deleted).
|
||||
// relativeRecordSetName - the name of the record set, relative to the name of the zone.
|
||||
// ifMatch - the ETag of the record set. Omit this value to always delete the current record set. Specify the
|
||||
// last-seen ETag value to prevent accidentally deleting any concurrent changes.
|
||||
func (client RecordSetsClient) Delete(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, relativeRecordSetName string, ifMatch string) (result autorest.Response, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.Delete")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.Response != nil {
|
||||
sc = result.Response.StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
req, err := client.DeletePreparer(ctx, resourceGroupName, privateZoneName, recordType, relativeRecordSetName, ifMatch)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "Delete", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.DeleteSender(req)
|
||||
if err != nil {
|
||||
result.Response = resp
|
||||
err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "Delete", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.DeleteResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "Delete", resp, "Failure responding to request")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// DeletePreparer prepares the Delete request.
|
||||
func (client RecordSetsClient) DeletePreparer(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, relativeRecordSetName string, ifMatch string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"privateZoneName": autorest.Encode("path", privateZoneName),
|
||||
"recordType": autorest.Encode("path", recordType),
|
||||
"relativeRecordSetName": relativeRecordSetName,
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2018-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsDelete(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/{recordType}/{relativeRecordSetName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
if len(ifMatch) > 0 {
|
||||
preparer = autorest.DecoratePreparer(preparer,
|
||||
autorest.WithHeader("If-Match", autorest.String(ifMatch)))
|
||||
}
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// DeleteSender sends the Delete request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client RecordSetsClient) DeleteSender(req *http.Request) (*http.Response, error) {
|
||||
return client.Send(req, azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// DeleteResponder handles the response to the Delete request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client RecordSetsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent),
|
||||
autorest.ByClosing())
|
||||
result.Response = resp
|
||||
return
|
||||
}
|
||||
|
||||
// Get gets a record set.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group.
|
||||
// privateZoneName - the name of the Private DNS zone (without a terminating dot).
|
||||
// recordType - the type of DNS record in this record set.
|
||||
// relativeRecordSetName - the name of the record set, relative to the name of the zone.
|
||||
func (client RecordSetsClient) Get(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, relativeRecordSetName string) (result RecordSet, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.Get")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.Response.Response != nil {
|
||||
sc = result.Response.Response.StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
req, err := client.GetPreparer(ctx, resourceGroupName, privateZoneName, recordType, relativeRecordSetName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "Get", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.GetSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "Get", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.GetResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "Get", resp, "Failure responding to request")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GetPreparer prepares the Get request.
|
||||
func (client RecordSetsClient) GetPreparer(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, relativeRecordSetName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"privateZoneName": autorest.Encode("path", privateZoneName),
|
||||
"recordType": autorest.Encode("path", recordType),
|
||||
"relativeRecordSetName": relativeRecordSetName,
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2018-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/{recordType}/{relativeRecordSetName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// GetSender sends the Get request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client RecordSetsClient) GetSender(req *http.Request) (*http.Response, error) {
|
||||
return client.Send(req, azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// GetResponder handles the response to the Get request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client RecordSetsClient) GetResponder(resp *http.Response) (result RecordSet, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// List lists all record sets in a Private DNS zone.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group.
|
||||
// privateZoneName - the name of the Private DNS zone (without a terminating dot).
|
||||
// top - the maximum number of record sets to return. If not specified, returns up to 100 record sets.
|
||||
// recordsetnamesuffix - the suffix label of the record set name to be used to filter the record set
|
||||
// enumeration. If this parameter is specified, the returned enumeration will only contain records that end
|
||||
// with ".<recordsetnamesuffix>".
|
||||
func (client RecordSetsClient) List(ctx context.Context, resourceGroupName string, privateZoneName string, top *int32, recordsetnamesuffix string) (result RecordSetListResultPage, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.List")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.rslr.Response.Response != nil {
|
||||
sc = result.rslr.Response.Response.StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
result.fn = client.listNextResults
|
||||
req, err := client.ListPreparer(ctx, resourceGroupName, privateZoneName, top, recordsetnamesuffix)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "List", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.ListSender(req)
|
||||
if err != nil {
|
||||
result.rslr.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "List", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result.rslr, err = client.ListResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "List", resp, "Failure responding to request")
|
||||
return
|
||||
}
|
||||
if result.rslr.hasNextLink() && result.rslr.IsEmpty() {
|
||||
err = result.NextWithContext(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ListPreparer prepares the List request.
|
||||
func (client RecordSetsClient) ListPreparer(ctx context.Context, resourceGroupName string, privateZoneName string, top *int32, recordsetnamesuffix string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"privateZoneName": autorest.Encode("path", privateZoneName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2018-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
if top != nil {
|
||||
queryParameters["$top"] = autorest.Encode("query", *top)
|
||||
}
|
||||
if len(recordsetnamesuffix) > 0 {
|
||||
queryParameters["$recordsetnamesuffix"] = autorest.Encode("query", recordsetnamesuffix)
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/ALL", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// ListSender sends the List request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client RecordSetsClient) ListSender(req *http.Request) (*http.Response, error) {
|
||||
return client.Send(req, azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// ListResponder handles the response to the List request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client RecordSetsClient) ListResponder(resp *http.Response) (result RecordSetListResult, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// listNextResults retrieves the next set of results, if any.
|
||||
func (client RecordSetsClient) listNextResults(ctx context.Context, lastResults RecordSetListResult) (result RecordSetListResult, err error) {
|
||||
req, err := lastResults.recordSetListResultPreparer(ctx)
|
||||
if err != nil {
|
||||
return result, autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "listNextResults", nil, "Failure preparing next results request")
|
||||
}
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
resp, err := client.ListSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "listNextResults", resp, "Failure sending next results request")
|
||||
}
|
||||
result, err = client.ListResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "listNextResults", resp, "Failure responding to next results request")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ListComplete enumerates all values, automatically crossing page boundaries as required.
|
||||
func (client RecordSetsClient) ListComplete(ctx context.Context, resourceGroupName string, privateZoneName string, top *int32, recordsetnamesuffix string) (result RecordSetListResultIterator, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.List")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.Response().Response.Response != nil {
|
||||
sc = result.page.Response().Response.Response.StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
result.page, err = client.List(ctx, resourceGroupName, privateZoneName, top, recordsetnamesuffix)
|
||||
return
|
||||
}
|
||||
|
||||
// ListByType lists the record sets of a specified type in a Private DNS zone.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group.
|
||||
// privateZoneName - the name of the Private DNS zone (without a terminating dot).
|
||||
// recordType - the type of record sets to enumerate.
|
||||
// top - the maximum number of record sets to return. If not specified, returns up to 100 record sets.
|
||||
// recordsetnamesuffix - the suffix label of the record set name to be used to filter the record set
|
||||
// enumeration. If this parameter is specified, the returned enumeration will only contain records that end
|
||||
// with ".<recordsetnamesuffix>".
|
||||
func (client RecordSetsClient) ListByType(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, top *int32, recordsetnamesuffix string) (result RecordSetListResultPage, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.ListByType")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.rslr.Response.Response != nil {
|
||||
sc = result.rslr.Response.Response.StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
result.fn = client.listByTypeNextResults
|
||||
req, err := client.ListByTypePreparer(ctx, resourceGroupName, privateZoneName, recordType, top, recordsetnamesuffix)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "ListByType", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.ListByTypeSender(req)
|
||||
if err != nil {
|
||||
result.rslr.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "ListByType", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result.rslr, err = client.ListByTypeResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "ListByType", resp, "Failure responding to request")
|
||||
return
|
||||
}
|
||||
if result.rslr.hasNextLink() && result.rslr.IsEmpty() {
|
||||
err = result.NextWithContext(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ListByTypePreparer prepares the ListByType request.
|
||||
func (client RecordSetsClient) ListByTypePreparer(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, top *int32, recordsetnamesuffix string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"privateZoneName": autorest.Encode("path", privateZoneName),
|
||||
"recordType": autorest.Encode("path", recordType),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2018-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
if top != nil {
|
||||
queryParameters["$top"] = autorest.Encode("query", *top)
|
||||
}
|
||||
if len(recordsetnamesuffix) > 0 {
|
||||
queryParameters["$recordsetnamesuffix"] = autorest.Encode("query", recordsetnamesuffix)
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/{recordType}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// ListByTypeSender sends the ListByType request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client RecordSetsClient) ListByTypeSender(req *http.Request) (*http.Response, error) {
|
||||
return client.Send(req, azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// ListByTypeResponder handles the response to the ListByType request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client RecordSetsClient) ListByTypeResponder(resp *http.Response) (result RecordSetListResult, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// listByTypeNextResults retrieves the next set of results, if any.
|
||||
func (client RecordSetsClient) listByTypeNextResults(ctx context.Context, lastResults RecordSetListResult) (result RecordSetListResult, err error) {
|
||||
req, err := lastResults.recordSetListResultPreparer(ctx)
|
||||
if err != nil {
|
||||
return result, autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "listByTypeNextResults", nil, "Failure preparing next results request")
|
||||
}
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
resp, err := client.ListByTypeSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "listByTypeNextResults", resp, "Failure sending next results request")
|
||||
}
|
||||
result, err = client.ListByTypeResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "listByTypeNextResults", resp, "Failure responding to next results request")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ListByTypeComplete enumerates all values, automatically crossing page boundaries as required.
|
||||
func (client RecordSetsClient) ListByTypeComplete(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, top *int32, recordsetnamesuffix string) (result RecordSetListResultIterator, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.ListByType")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.Response().Response.Response != nil {
|
||||
sc = result.page.Response().Response.Response.StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
result.page, err = client.ListByType(ctx, resourceGroupName, privateZoneName, recordType, top, recordsetnamesuffix)
|
||||
return
|
||||
}
|
||||
|
||||
// Update updates a record set within a Private DNS zone.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group.
|
||||
// privateZoneName - the name of the Private DNS zone (without a terminating dot).
|
||||
// recordType - the type of DNS record in this record set.
|
||||
// relativeRecordSetName - the name of the record set, relative to the name of the zone.
|
||||
// parameters - parameters supplied to the Update operation.
|
||||
// ifMatch - the ETag of the record set. Omit this value to always overwrite the current record set. Specify
|
||||
// the last-seen ETag value to prevent accidentally overwriting concurrent changes.
|
||||
func (client RecordSetsClient) Update(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, relativeRecordSetName string, parameters RecordSet, ifMatch string) (result RecordSet, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/RecordSetsClient.Update")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.Response.Response != nil {
|
||||
sc = result.Response.Response.StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
req, err := client.UpdatePreparer(ctx, resourceGroupName, privateZoneName, recordType, relativeRecordSetName, parameters, ifMatch)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "Update", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.UpdateSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "Update", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.UpdateResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.RecordSetsClient", "Update", resp, "Failure responding to request")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// UpdatePreparer prepares the Update request.
|
||||
func (client RecordSetsClient) UpdatePreparer(ctx context.Context, resourceGroupName string, privateZoneName string, recordType RecordType, relativeRecordSetName string, parameters RecordSet, ifMatch string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"privateZoneName": autorest.Encode("path", privateZoneName),
|
||||
"recordType": autorest.Encode("path", recordType),
|
||||
"relativeRecordSetName": relativeRecordSetName,
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2018-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPatch(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/{recordType}/{relativeRecordSetName}", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
if len(ifMatch) > 0 {
|
||||
preparer = autorest.DecoratePreparer(preparer,
|
||||
autorest.WithHeader("If-Match", autorest.String(ifMatch)))
|
||||
}
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// UpdateSender sends the Update request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client RecordSetsClient) UpdateSender(req *http.Request) (*http.Response, error) {
|
||||
return client.Send(req, azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// UpdateResponder handles the response to the Update request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client RecordSetsClient) UpdateResponder(resp *http.Response) (result RecordSet, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
19
cluster-autoscaler/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns/version.go
generated
vendored
Normal file
19
cluster-autoscaler/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns/version.go
generated
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
package privatedns
|
||||
|
||||
import "github.com/Azure/azure-sdk-for-go/version"
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
//
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
// UserAgent returns the UserAgent string to use when sending http.Requests.
|
||||
func UserAgent() string {
|
||||
return "Azure-SDK-For-Go/" + Version() + " privatedns/2018-09-01"
|
||||
}
|
||||
|
||||
// Version returns the semantic version (see http://semver.org) of the client.
|
||||
func Version() string {
|
||||
return version.Number
|
||||
}
|
||||
506
cluster-autoscaler/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns/virtualnetworklinks.go
generated
vendored
Normal file
506
cluster-autoscaler/vendor/github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns/virtualnetworklinks.go
generated
vendored
Normal file
|
|
@ -0,0 +1,506 @@
|
|||
package privatedns
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
//
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/tracing"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// VirtualNetworkLinksClient is the the Private DNS Management Client.
|
||||
type VirtualNetworkLinksClient struct {
|
||||
BaseClient
|
||||
}
|
||||
|
||||
// NewVirtualNetworkLinksClient creates an instance of the VirtualNetworkLinksClient client.
|
||||
func NewVirtualNetworkLinksClient(subscriptionID string) VirtualNetworkLinksClient {
|
||||
return NewVirtualNetworkLinksClientWithBaseURI(DefaultBaseURI, subscriptionID)
|
||||
}
|
||||
|
||||
// NewVirtualNetworkLinksClientWithBaseURI creates an instance of the VirtualNetworkLinksClient client using a custom
|
||||
// endpoint. Use this when interacting with an Azure cloud that uses a non-standard base URI (sovereign clouds, Azure
|
||||
// stack).
|
||||
func NewVirtualNetworkLinksClientWithBaseURI(baseURI string, subscriptionID string) VirtualNetworkLinksClient {
|
||||
return VirtualNetworkLinksClient{NewWithBaseURI(baseURI, subscriptionID)}
|
||||
}
|
||||
|
||||
// CreateOrUpdate creates or updates a virtual network link to the specified Private DNS zone.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group.
|
||||
// privateZoneName - the name of the Private DNS zone (without a terminating dot).
|
||||
// virtualNetworkLinkName - the name of the virtual network link.
|
||||
// parameters - parameters supplied to the CreateOrUpdate operation.
|
||||
// ifMatch - the ETag of the virtual network link to the Private DNS zone. Omit this value to always overwrite
|
||||
// the current virtual network link. Specify the last-seen ETag value to prevent accidentally overwriting any
|
||||
// concurrent changes.
|
||||
// ifNoneMatch - set to '*' to allow a new virtual network link to the Private DNS zone to be created, but to
|
||||
// prevent updating an existing link. Other values will be ignored.
|
||||
func (client VirtualNetworkLinksClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string, parameters VirtualNetworkLink, ifMatch string, ifNoneMatch string) (result VirtualNetworkLinksCreateOrUpdateFuture, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkLinksClient.CreateOrUpdate")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.FutureAPI != nil && result.FutureAPI.Response() != nil {
|
||||
sc = result.FutureAPI.Response().StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, privateZoneName, virtualNetworkLinkName, parameters, ifMatch, ifNoneMatch)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "CreateOrUpdate", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.CreateOrUpdateSender(req)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "CreateOrUpdate", nil, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// CreateOrUpdatePreparer prepares the CreateOrUpdate request.
|
||||
func (client VirtualNetworkLinksClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string, parameters VirtualNetworkLink, ifMatch string, ifNoneMatch string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"privateZoneName": autorest.Encode("path", privateZoneName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
"virtualNetworkLinkName": autorest.Encode("path", virtualNetworkLinkName),
|
||||
}
|
||||
|
||||
const APIVersion = "2018-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPut(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/virtualNetworkLinks/{virtualNetworkLinkName}", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
if len(ifMatch) > 0 {
|
||||
preparer = autorest.DecoratePreparer(preparer,
|
||||
autorest.WithHeader("If-Match", autorest.String(ifMatch)))
|
||||
}
|
||||
if len(ifNoneMatch) > 0 {
|
||||
preparer = autorest.DecoratePreparer(preparer,
|
||||
autorest.WithHeader("If-None-Match", autorest.String(ifNoneMatch)))
|
||||
}
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client VirtualNetworkLinksClient) CreateOrUpdateSender(req *http.Request) (future VirtualNetworkLinksCreateOrUpdateFuture, err error) {
|
||||
var resp *http.Response
|
||||
resp, err = client.Send(req, azure.DoRetryWithRegistration(client.Client))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var azf azure.Future
|
||||
azf, err = azure.NewFutureFromResponse(resp)
|
||||
future.FutureAPI = &azf
|
||||
future.Result = future.result
|
||||
return
|
||||
}
|
||||
|
||||
// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client VirtualNetworkLinksClient) CreateOrUpdateResponder(resp *http.Response) (result VirtualNetworkLink, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated, http.StatusAccepted),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// Delete deletes a virtual network link to the specified Private DNS zone. WARNING: In case of a registration virtual
|
||||
// network, all auto-registered DNS records in the zone for the virtual network will also be deleted. This operation
|
||||
// cannot be undone.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group.
|
||||
// privateZoneName - the name of the Private DNS zone (without a terminating dot).
|
||||
// virtualNetworkLinkName - the name of the virtual network link.
|
||||
// ifMatch - the ETag of the virtual network link to the Private DNS zone. Omit this value to always delete the
|
||||
// current zone. Specify the last-seen ETag value to prevent accidentally deleting any concurrent changes.
|
||||
func (client VirtualNetworkLinksClient) Delete(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string, ifMatch string) (result VirtualNetworkLinksDeleteFuture, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkLinksClient.Delete")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.FutureAPI != nil && result.FutureAPI.Response() != nil {
|
||||
sc = result.FutureAPI.Response().StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
req, err := client.DeletePreparer(ctx, resourceGroupName, privateZoneName, virtualNetworkLinkName, ifMatch)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "Delete", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.DeleteSender(req)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "Delete", nil, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// DeletePreparer prepares the Delete request.
|
||||
func (client VirtualNetworkLinksClient) DeletePreparer(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string, ifMatch string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"privateZoneName": autorest.Encode("path", privateZoneName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
"virtualNetworkLinkName": autorest.Encode("path", virtualNetworkLinkName),
|
||||
}
|
||||
|
||||
const APIVersion = "2018-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsDelete(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/virtualNetworkLinks/{virtualNetworkLinkName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
if len(ifMatch) > 0 {
|
||||
preparer = autorest.DecoratePreparer(preparer,
|
||||
autorest.WithHeader("If-Match", autorest.String(ifMatch)))
|
||||
}
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// DeleteSender sends the Delete request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client VirtualNetworkLinksClient) DeleteSender(req *http.Request) (future VirtualNetworkLinksDeleteFuture, err error) {
|
||||
var resp *http.Response
|
||||
resp, err = client.Send(req, azure.DoRetryWithRegistration(client.Client))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var azf azure.Future
|
||||
azf, err = azure.NewFutureFromResponse(resp)
|
||||
future.FutureAPI = &azf
|
||||
future.Result = future.result
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteResponder handles the response to the Delete request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client VirtualNetworkLinksClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent),
|
||||
autorest.ByClosing())
|
||||
result.Response = resp
|
||||
return
|
||||
}
|
||||
|
||||
// Get gets a virtual network link to the specified Private DNS zone.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group.
|
||||
// privateZoneName - the name of the Private DNS zone (without a terminating dot).
|
||||
// virtualNetworkLinkName - the name of the virtual network link.
|
||||
func (client VirtualNetworkLinksClient) Get(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string) (result VirtualNetworkLink, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkLinksClient.Get")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.Response.Response != nil {
|
||||
sc = result.Response.Response.StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
req, err := client.GetPreparer(ctx, resourceGroupName, privateZoneName, virtualNetworkLinkName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "Get", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.GetSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "Get", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.GetResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "Get", resp, "Failure responding to request")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GetPreparer prepares the Get request.
|
||||
func (client VirtualNetworkLinksClient) GetPreparer(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"privateZoneName": autorest.Encode("path", privateZoneName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
"virtualNetworkLinkName": autorest.Encode("path", virtualNetworkLinkName),
|
||||
}
|
||||
|
||||
const APIVersion = "2018-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/virtualNetworkLinks/{virtualNetworkLinkName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// GetSender sends the Get request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client VirtualNetworkLinksClient) GetSender(req *http.Request) (*http.Response, error) {
|
||||
return client.Send(req, azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// GetResponder handles the response to the Get request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client VirtualNetworkLinksClient) GetResponder(resp *http.Response) (result VirtualNetworkLink, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// List lists the virtual network links to the specified Private DNS zone.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group.
|
||||
// privateZoneName - the name of the Private DNS zone (without a terminating dot).
|
||||
// top - the maximum number of virtual network links to return. If not specified, returns up to 100 virtual
|
||||
// network links.
|
||||
func (client VirtualNetworkLinksClient) List(ctx context.Context, resourceGroupName string, privateZoneName string, top *int32) (result VirtualNetworkLinkListResultPage, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkLinksClient.List")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.vnllr.Response.Response != nil {
|
||||
sc = result.vnllr.Response.Response.StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
result.fn = client.listNextResults
|
||||
req, err := client.ListPreparer(ctx, resourceGroupName, privateZoneName, top)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "List", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.ListSender(req)
|
||||
if err != nil {
|
||||
result.vnllr.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "List", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result.vnllr, err = client.ListResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "List", resp, "Failure responding to request")
|
||||
return
|
||||
}
|
||||
if result.vnllr.hasNextLink() && result.vnllr.IsEmpty() {
|
||||
err = result.NextWithContext(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ListPreparer prepares the List request.
|
||||
func (client VirtualNetworkLinksClient) ListPreparer(ctx context.Context, resourceGroupName string, privateZoneName string, top *int32) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"privateZoneName": autorest.Encode("path", privateZoneName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2018-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
if top != nil {
|
||||
queryParameters["$top"] = autorest.Encode("query", *top)
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/virtualNetworkLinks", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// ListSender sends the List request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client VirtualNetworkLinksClient) ListSender(req *http.Request) (*http.Response, error) {
|
||||
return client.Send(req, azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// ListResponder handles the response to the List request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client VirtualNetworkLinksClient) ListResponder(resp *http.Response) (result VirtualNetworkLinkListResult, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// listNextResults retrieves the next set of results, if any.
|
||||
func (client VirtualNetworkLinksClient) listNextResults(ctx context.Context, lastResults VirtualNetworkLinkListResult) (result VirtualNetworkLinkListResult, err error) {
|
||||
req, err := lastResults.virtualNetworkLinkListResultPreparer(ctx)
|
||||
if err != nil {
|
||||
return result, autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "listNextResults", nil, "Failure preparing next results request")
|
||||
}
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
resp, err := client.ListSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "listNextResults", resp, "Failure sending next results request")
|
||||
}
|
||||
result, err = client.ListResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "listNextResults", resp, "Failure responding to next results request")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ListComplete enumerates all values, automatically crossing page boundaries as required.
|
||||
func (client VirtualNetworkLinksClient) ListComplete(ctx context.Context, resourceGroupName string, privateZoneName string, top *int32) (result VirtualNetworkLinkListResultIterator, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkLinksClient.List")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.Response().Response.Response != nil {
|
||||
sc = result.page.Response().Response.Response.StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
result.page, err = client.List(ctx, resourceGroupName, privateZoneName, top)
|
||||
return
|
||||
}
|
||||
|
||||
// Update updates a virtual network link to the specified Private DNS zone.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group.
|
||||
// privateZoneName - the name of the Private DNS zone (without a terminating dot).
|
||||
// virtualNetworkLinkName - the name of the virtual network link.
|
||||
// parameters - parameters supplied to the Update operation.
|
||||
// ifMatch - the ETag of the virtual network link to the Private DNS zone. Omit this value to always overwrite
|
||||
// the current virtual network link. Specify the last-seen ETag value to prevent accidentally overwriting any
|
||||
// concurrent changes.
|
||||
func (client VirtualNetworkLinksClient) Update(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string, parameters VirtualNetworkLink, ifMatch string) (result VirtualNetworkLinksUpdateFuture, err error) {
|
||||
if tracing.IsEnabled() {
|
||||
ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkLinksClient.Update")
|
||||
defer func() {
|
||||
sc := -1
|
||||
if result.FutureAPI != nil && result.FutureAPI.Response() != nil {
|
||||
sc = result.FutureAPI.Response().StatusCode
|
||||
}
|
||||
tracing.EndSpan(ctx, sc, err)
|
||||
}()
|
||||
}
|
||||
req, err := client.UpdatePreparer(ctx, resourceGroupName, privateZoneName, virtualNetworkLinkName, parameters, ifMatch)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "Update", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.UpdateSender(req)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "privatedns.VirtualNetworkLinksClient", "Update", nil, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// UpdatePreparer prepares the Update request.
|
||||
func (client VirtualNetworkLinksClient) UpdatePreparer(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string, parameters VirtualNetworkLink, ifMatch string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"privateZoneName": autorest.Encode("path", privateZoneName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
"virtualNetworkLinkName": autorest.Encode("path", virtualNetworkLinkName),
|
||||
}
|
||||
|
||||
const APIVersion = "2018-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPatch(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/privateDnsZones/{privateZoneName}/virtualNetworkLinks/{virtualNetworkLinkName}", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
if len(ifMatch) > 0 {
|
||||
preparer = autorest.DecoratePreparer(preparer,
|
||||
autorest.WithHeader("If-Match", autorest.String(ifMatch)))
|
||||
}
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// UpdateSender sends the Update request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client VirtualNetworkLinksClient) UpdateSender(req *http.Request) (future VirtualNetworkLinksUpdateFuture, err error) {
|
||||
var resp *http.Response
|
||||
resp, err = client.Send(req, azure.DoRetryWithRegistration(client.Client))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var azf azure.Future
|
||||
azf, err = azure.NewFutureFromResponse(resp)
|
||||
future.FutureAPI = &azf
|
||||
future.Result = future.result
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateResponder handles the response to the Update request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client VirtualNetworkLinksClient) UpdateResponder(resp *http.Response) (result VirtualNetworkLink, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/2019-05-01/con
|
|||
github.com/Azure/azure-sdk-for-go/services/containerservice/mgmt/2020-04-01/containerservice
|
||||
github.com/Azure/azure-sdk-for-go/services/network/mgmt/2019-06-01/network
|
||||
github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network
|
||||
github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns
|
||||
github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2017-05-10/resources
|
||||
github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2019-06-01/storage
|
||||
github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2021-02-01/storage
|
||||
|
|
@ -173,8 +174,6 @@ github.com/containerd/containerd/api/types
|
|||
github.com/containerd/containerd/api/types/task
|
||||
# github.com/containerd/ttrpc v1.0.2
|
||||
github.com/containerd/ttrpc
|
||||
# github.com/containernetworking/cni v0.8.1
|
||||
## explicit
|
||||
# github.com/coreos/go-semver v0.3.0
|
||||
github.com/coreos/go-semver/semver
|
||||
# github.com/coreos/go-systemd/v22 v22.3.2
|
||||
|
|
@ -1803,23 +1802,50 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client
|
|||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client
|
||||
# sigs.k8s.io/cloud-provider-azure v1.23.2
|
||||
## explicit
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/auth
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/armclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/containerserviceclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/containerserviceclient/mockcontainerserviceclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/deploymentclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/diskclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/diskclient/mockdiskclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/fileclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/interfaceclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/interfaceclient/mockinterfaceclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/loadbalancerclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/loadbalancerclient/mockloadbalancerclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/privatednsclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/privatednszonegroupclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/privateendpointclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/publicipclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/publicipclient/mockpublicipclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routeclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routeclient/mockrouteclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routetableclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routetableclient/mockroutetableclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/securitygroupclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/securitygroupclient/mocksecuritygroupclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/snapshotclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/snapshotclient/mocksnapshotclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/storageaccountclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/storageaccountclient/mockstorageaccountclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/subnetclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/subnetclient/mocksubnetclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/virtualnetworklinksclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmasclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmclient/mockvmclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmsizeclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmssclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmssclient/mockvmssclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmssvmclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmssvmclient/mockvmssvmclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azureclients/zoneclient
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/cache
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/consts
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/metrics
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/provider
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/retry
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/version
|
||||
# sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2
|
||||
|
|
|
|||
290
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/auth/azure_auth.go
generated
vendored
Normal file
290
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/auth/azure_auth.go
generated
vendored
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest/adal"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
|
||||
"golang.org/x/crypto/pkcs12"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/consts"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrorNoAuth indicates that no credentials are provided.
|
||||
ErrorNoAuth = fmt.Errorf("no credentials provided for Azure cloud provider")
|
||||
)
|
||||
|
||||
// AzureAuthConfig holds auth related part of cloud config
|
||||
type AzureAuthConfig struct {
|
||||
// The cloud environment identifier. Takes values from https://github.com/Azure/go-autorest/blob/ec5f4903f77ed9927ac95b19ab8e44ada64c1356/autorest/azure/environments.go#L13
|
||||
Cloud string `json:"cloud,omitempty" yaml:"cloud,omitempty"`
|
||||
// The AAD Tenant ID for the Subscription that the cluster is deployed in
|
||||
TenantID string `json:"tenantId,omitempty" yaml:"tenantId,omitempty"`
|
||||
// The ClientID for an AAD application with RBAC access to talk to Azure RM APIs
|
||||
AADClientID string `json:"aadClientId,omitempty" yaml:"aadClientId,omitempty"`
|
||||
// The ClientSecret for an AAD application with RBAC access to talk to Azure RM APIs
|
||||
AADClientSecret string `json:"aadClientSecret,omitempty" yaml:"aadClientSecret,omitempty" datapolicy:"token"`
|
||||
// The path of a client certificate for an AAD application with RBAC access to talk to Azure RM APIs
|
||||
AADClientCertPath string `json:"aadClientCertPath,omitempty" yaml:"aadClientCertPath,omitempty"`
|
||||
// The password of the client certificate for an AAD application with RBAC access to talk to Azure RM APIs
|
||||
AADClientCertPassword string `json:"aadClientCertPassword,omitempty" yaml:"aadClientCertPassword,omitempty" datapolicy:"password"`
|
||||
// Use managed service identity for the virtual machine to access Azure ARM APIs
|
||||
UseManagedIdentityExtension bool `json:"useManagedIdentityExtension,omitempty" yaml:"useManagedIdentityExtension,omitempty"`
|
||||
// UserAssignedIdentityID contains the Client ID of the user assigned MSI which is assigned to the underlying VMs. If empty the user assigned identity is not used.
|
||||
// More details of the user assigned identity can be found at: https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/overview
|
||||
// For the user assigned identity specified here to be used, the UseManagedIdentityExtension has to be set to true.
|
||||
UserAssignedIdentityID string `json:"userAssignedIdentityID,omitempty" yaml:"userAssignedIdentityID,omitempty"`
|
||||
// The ID of the Azure Subscription that the cluster is deployed in
|
||||
SubscriptionID string `json:"subscriptionId,omitempty" yaml:"subscriptionId,omitempty"`
|
||||
// IdentitySystem indicates the identity provider. Relevant only to hybrid clouds (Azure Stack).
|
||||
// Allowed values are 'azure_ad' (default), 'adfs'.
|
||||
IdentitySystem string `json:"identitySystem,omitempty" yaml:"identitySystem,omitempty"`
|
||||
// ResourceManagerEndpoint is the cloud's resource manager endpoint. If set, cloud provider queries this endpoint
|
||||
// in order to generate an autorest.Environment instance instead of using one of the pre-defined Environments.
|
||||
ResourceManagerEndpoint string `json:"resourceManagerEndpoint,omitempty" yaml:"resourceManagerEndpoint,omitempty"`
|
||||
// The AAD Tenant ID for the Subscription that the network resources are deployed in
|
||||
NetworkResourceTenantID string `json:"networkResourceTenantID,omitempty" yaml:"networkResourceTenantID,omitempty"`
|
||||
// The ID of the Azure Subscription that the network resources are deployed in
|
||||
NetworkResourceSubscriptionID string `json:"networkResourceSubscriptionID,omitempty" yaml:"networkResourceSubscriptionID,omitempty"`
|
||||
}
|
||||
|
||||
// GetServicePrincipalToken creates a new service principal token based on the configuration.
|
||||
//
|
||||
// By default, the cluster and its network resources are deployed in the same AAD Tenant and Subscription,
|
||||
// and all azure clients use this method to fetch Service Principal Token.
|
||||
//
|
||||
// If NetworkResourceTenantID and NetworkResourceSubscriptionID are specified to have different values than TenantID and SubscriptionID, network resources are deployed in different AAD Tenant and Subscription than those for the cluster,
|
||||
// than only azure clients except VM/VMSS and network resource ones use this method to fetch Token.
|
||||
// For tokens for VM/VMSS and network resource ones, please check GetMultiTenantServicePrincipalToken and GetNetworkResourceServicePrincipalToken.
|
||||
func GetServicePrincipalToken(config *AzureAuthConfig, env *azure.Environment, resource string) (*adal.ServicePrincipalToken, error) {
|
||||
var tenantID string
|
||||
if strings.EqualFold(config.IdentitySystem, consts.ADFSIdentitySystem) {
|
||||
tenantID = consts.ADFSIdentitySystem
|
||||
} else {
|
||||
tenantID = config.TenantID
|
||||
}
|
||||
|
||||
if resource == "" {
|
||||
resource = env.ServiceManagementEndpoint
|
||||
}
|
||||
|
||||
if config.UseManagedIdentityExtension {
|
||||
klog.V(2).Infoln("azure: using managed identity extension to retrieve access token")
|
||||
msiEndpoint, err := adal.GetMSIVMEndpoint()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting the managed service identity endpoint: %w", err)
|
||||
}
|
||||
if len(config.UserAssignedIdentityID) > 0 {
|
||||
klog.V(4).Info("azure: using User Assigned MSI ID to retrieve access token")
|
||||
return adal.NewServicePrincipalTokenFromMSIWithUserAssignedID(msiEndpoint,
|
||||
resource,
|
||||
config.UserAssignedIdentityID)
|
||||
}
|
||||
klog.V(4).Info("azure: using System Assigned MSI to retrieve access token")
|
||||
return adal.NewServicePrincipalTokenFromMSI(
|
||||
msiEndpoint,
|
||||
resource)
|
||||
}
|
||||
|
||||
oauthConfig, err := adal.NewOAuthConfigWithAPIVersion(env.ActiveDirectoryEndpoint, tenantID, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating the OAuth config: %w", err)
|
||||
}
|
||||
|
||||
if len(config.AADClientSecret) > 0 {
|
||||
klog.V(2).Infoln("azure: using client_id+client_secret to retrieve access token")
|
||||
return adal.NewServicePrincipalToken(
|
||||
*oauthConfig,
|
||||
config.AADClientID,
|
||||
config.AADClientSecret,
|
||||
resource)
|
||||
}
|
||||
|
||||
if len(config.AADClientCertPath) > 0 && len(config.AADClientCertPassword) > 0 {
|
||||
klog.V(2).Infoln("azure: using jwt client_assertion (client_cert+client_private_key) to retrieve access token")
|
||||
certData, err := ioutil.ReadFile(config.AADClientCertPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("reading the client certificate from file %s: %w", config.AADClientCertPath, err)
|
||||
}
|
||||
certificate, privateKey, err := decodePkcs12(certData, config.AADClientCertPassword)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding the client certificate: %w", err)
|
||||
}
|
||||
return adal.NewServicePrincipalTokenFromCertificate(
|
||||
*oauthConfig,
|
||||
config.AADClientID,
|
||||
certificate,
|
||||
privateKey,
|
||||
resource)
|
||||
}
|
||||
|
||||
return nil, ErrorNoAuth
|
||||
}
|
||||
|
||||
// GetMultiTenantServicePrincipalToken is used when (and only when) NetworkResourceTenantID and NetworkResourceSubscriptionID are specified to have different values than TenantID and SubscriptionID.
|
||||
//
|
||||
// In that scenario, network resources are deployed in different AAD Tenant and Subscription than those for the cluster,
|
||||
// and this method creates a new multi-tenant service principal token based on the configuration.
|
||||
//
|
||||
// PrimaryToken of the returned multi-tenant token is for the AAD Tenant specified by TenantID, and AuxiliaryToken of the returned multi-tenant token is for the AAD Tenant specified by NetworkResourceTenantID.
|
||||
//
|
||||
// Azure VM/VMSS clients use this multi-tenant token, in order to operate those VM/VMSS in AAD Tenant specified by TenantID, and meanwhile in their payload they are referencing network resources (e.g. Load Balancer, Network Security Group, etc.) in AAD Tenant specified by NetworkResourceTenantID.
|
||||
func GetMultiTenantServicePrincipalToken(config *AzureAuthConfig, env *azure.Environment) (*adal.MultiTenantServicePrincipalToken, error) {
|
||||
err := config.checkConfigWhenNetworkResourceInDifferentTenant()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("got error getting multi-tenant service principal token: %w", err)
|
||||
}
|
||||
|
||||
multiTenantOAuthConfig, err := adal.NewMultiTenantOAuthConfig(
|
||||
env.ActiveDirectoryEndpoint, config.TenantID, []string{config.NetworkResourceTenantID}, adal.OAuthOptions{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating the multi-tenant OAuth config: %w", err)
|
||||
}
|
||||
|
||||
if len(config.AADClientSecret) > 0 {
|
||||
klog.V(2).Infoln("azure: using client_id+client_secret to retrieve multi-tenant access token")
|
||||
return adal.NewMultiTenantServicePrincipalToken(
|
||||
multiTenantOAuthConfig,
|
||||
config.AADClientID,
|
||||
config.AADClientSecret,
|
||||
env.ServiceManagementEndpoint)
|
||||
}
|
||||
|
||||
if len(config.AADClientCertPath) > 0 && len(config.AADClientCertPassword) > 0 {
|
||||
return nil, fmt.Errorf("AAD Application client certificate authentication is not supported in getting multi-tenant service principal token")
|
||||
}
|
||||
|
||||
return nil, ErrorNoAuth
|
||||
}
|
||||
|
||||
// GetNetworkResourceServicePrincipalToken is used when (and only when) NetworkResourceTenantID and NetworkResourceSubscriptionID are specified to have different values than TenantID and SubscriptionID.
|
||||
//
|
||||
// In that scenario, network resources are deployed in different AAD Tenant and Subscription than those for the cluster,
|
||||
// and this method creates a new service principal token for network resources tenant based on the configuration.
|
||||
//
|
||||
// Azure network resource (Load Balancer, Public IP, Route Table, Network Security Group and their sub level resources) clients use this multi-tenant token, in order to operate resources in AAD Tenant specified by NetworkResourceTenantID.
|
||||
func GetNetworkResourceServicePrincipalToken(config *AzureAuthConfig, env *azure.Environment) (*adal.ServicePrincipalToken, error) {
|
||||
err := config.checkConfigWhenNetworkResourceInDifferentTenant()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("got error(%w) in getting network resources service principal token", err)
|
||||
}
|
||||
|
||||
oauthConfig, err := adal.NewOAuthConfigWithAPIVersion(env.ActiveDirectoryEndpoint, config.NetworkResourceTenantID, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating the OAuth config for network resources tenant: %w", err)
|
||||
}
|
||||
|
||||
if len(config.AADClientSecret) > 0 {
|
||||
klog.V(2).Infoln("azure: using client_id+client_secret to retrieve access token for network resources tenant")
|
||||
return adal.NewServicePrincipalToken(
|
||||
*oauthConfig,
|
||||
config.AADClientID,
|
||||
config.AADClientSecret,
|
||||
env.ServiceManagementEndpoint)
|
||||
}
|
||||
|
||||
if len(config.AADClientCertPath) > 0 && len(config.AADClientCertPassword) > 0 {
|
||||
return nil, fmt.Errorf("AAD Application client certificate authentication is not supported in getting network resources service principal token")
|
||||
}
|
||||
|
||||
return nil, ErrorNoAuth
|
||||
}
|
||||
|
||||
// ParseAzureEnvironment returns the azure environment.
|
||||
// If 'resourceManagerEndpoint' is set, the environment is computed by querying the cloud's resource manager endpoint.
|
||||
// Otherwise, a pre-defined Environment is looked up by name.
|
||||
func ParseAzureEnvironment(cloudName, resourceManagerEndpoint, identitySystem string) (*azure.Environment, error) {
|
||||
var env azure.Environment
|
||||
var err error
|
||||
if resourceManagerEndpoint != "" {
|
||||
klog.V(4).Infof("Loading environment from resource manager endpoint: %s", resourceManagerEndpoint)
|
||||
nameOverride := azure.OverrideProperty{Key: azure.EnvironmentName, Value: cloudName}
|
||||
env, err = azure.EnvironmentFromURL(resourceManagerEndpoint, nameOverride)
|
||||
if err == nil {
|
||||
azureStackOverrides(&env, resourceManagerEndpoint, identitySystem)
|
||||
}
|
||||
} else if cloudName == "" {
|
||||
klog.V(4).Info("Using public cloud environment")
|
||||
env = azure.PublicCloud
|
||||
} else {
|
||||
klog.V(4).Infof("Using %s environment", cloudName)
|
||||
env, err = azure.EnvironmentFromName(cloudName)
|
||||
}
|
||||
return &env, err
|
||||
}
|
||||
|
||||
// UsesNetworkResourceInDifferentTenantOrSubscription determines whether the AzureAuthConfig indicates to use network resources in different AAD Tenant and Subscription than those for the cluster
|
||||
// Return true when one of NetworkResourceTenantID and NetworkResourceSubscriptionID are specified
|
||||
// and equal to one defined in global configs
|
||||
func (config *AzureAuthConfig) UsesNetworkResourceInDifferentTenantOrSubscription() bool {
|
||||
return (len(config.NetworkResourceTenantID) > 0 && !strings.EqualFold(config.NetworkResourceTenantID, config.TenantID)) ||
|
||||
(len(config.NetworkResourceSubscriptionID) > 0 && !strings.EqualFold(config.NetworkResourceSubscriptionID, config.SubscriptionID))
|
||||
}
|
||||
|
||||
// decodePkcs12 decodes a PKCS#12 client certificate by extracting the public certificate and
|
||||
// the private RSA key
|
||||
func decodePkcs12(pkcs []byte, password string) (*x509.Certificate, *rsa.PrivateKey, error) {
|
||||
privateKey, certificate, err := pkcs12.Decode(pkcs, password)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("decoding the PKCS#12 client certificate: %w", err)
|
||||
}
|
||||
rsaPrivateKey, isRsaKey := privateKey.(*rsa.PrivateKey)
|
||||
if !isRsaKey {
|
||||
return nil, nil, fmt.Errorf("PKCS#12 certificate must contain a RSA private key")
|
||||
}
|
||||
|
||||
return certificate, rsaPrivateKey, nil
|
||||
}
|
||||
|
||||
// azureStackOverrides ensures that the Environment matches what AKSe currently generates for Azure Stack
|
||||
func azureStackOverrides(env *azure.Environment, resourceManagerEndpoint, identitySystem string) {
|
||||
env.ManagementPortalURL = strings.Replace(resourceManagerEndpoint, "https://management.", "https://portal.", -1)
|
||||
env.ServiceManagementEndpoint = env.TokenAudience
|
||||
env.ResourceManagerVMDNSSuffix = strings.Replace(resourceManagerEndpoint, "https://management.", "cloudapp.", -1)
|
||||
env.ResourceManagerVMDNSSuffix = strings.TrimSuffix(env.ResourceManagerVMDNSSuffix, "/")
|
||||
if strings.EqualFold(identitySystem, consts.ADFSIdentitySystem) {
|
||||
env.ActiveDirectoryEndpoint = strings.TrimSuffix(env.ActiveDirectoryEndpoint, "/")
|
||||
env.ActiveDirectoryEndpoint = strings.TrimSuffix(env.ActiveDirectoryEndpoint, "adfs")
|
||||
}
|
||||
}
|
||||
|
||||
// checkConfigWhenNetworkResourceInDifferentTenant checks configuration for the scenario of using network resource in different tenant
|
||||
func (config *AzureAuthConfig) checkConfigWhenNetworkResourceInDifferentTenant() error {
|
||||
if !config.UsesNetworkResourceInDifferentTenantOrSubscription() {
|
||||
return fmt.Errorf("NetworkResourceTenantID and NetworkResourceSubscriptionID must be configured")
|
||||
}
|
||||
|
||||
if strings.EqualFold(config.IdentitySystem, consts.ADFSIdentitySystem) {
|
||||
return fmt.Errorf("ADFS identity system is not supported")
|
||||
}
|
||||
|
||||
if config.UseManagedIdentityExtension {
|
||||
return fmt.Errorf("managed identity is not supported")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/auth/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/auth/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package auth provides a general library to authorize Azure ARM clients.
|
||||
package auth // import "sigs.k8s.io/cloud-provider-azure/pkg/auth"
|
||||
459
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/deploymentclient/azure_deploymentclient.go
generated
vendored
Normal file
459
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/deploymentclient/azure_deploymentclient.go
generated
vendored
Normal file
|
|
@ -0,0 +1,459 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package deploymentclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2017-05-10/resources"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
azclients "sigs.k8s.io/cloud-provider-azure/pkg/azureclients"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/armclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/metrics"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
var _ Interface = &Client{}
|
||||
|
||||
// Client implements ContainerService client Interface.
|
||||
type Client struct {
|
||||
armClient armclient.Interface
|
||||
subscriptionID string
|
||||
|
||||
// Rate limiting configures.
|
||||
rateLimiterReader flowcontrol.RateLimiter
|
||||
rateLimiterWriter flowcontrol.RateLimiter
|
||||
|
||||
// ARM throttling configures.
|
||||
RetryAfterReader time.Time
|
||||
RetryAfterWriter time.Time
|
||||
}
|
||||
|
||||
// New creates a new ContainerServiceClient client with ratelimiting.
|
||||
func New(config *azclients.ClientConfig) *Client {
|
||||
baseURI := config.ResourceManagerEndpoint
|
||||
authorizer := config.Authorizer
|
||||
armClient := armclient.New(authorizer, *config, baseURI, APIVersion)
|
||||
rateLimiterReader, rateLimiterWriter := azclients.NewRateLimiter(config.RateLimitConfig)
|
||||
|
||||
if azclients.RateLimitEnabled(config.RateLimitConfig) {
|
||||
klog.V(2).Infof("Azure DeploymentClient (read ops) using rate limit config: QPS=%g, bucket=%d",
|
||||
config.RateLimitConfig.CloudProviderRateLimitQPS,
|
||||
config.RateLimitConfig.CloudProviderRateLimitBucket)
|
||||
klog.V(2).Infof("Azure DeploymentClient (write ops) using rate limit config: QPS=%g, bucket=%d",
|
||||
config.RateLimitConfig.CloudProviderRateLimitQPSWrite,
|
||||
config.RateLimitConfig.CloudProviderRateLimitBucketWrite)
|
||||
}
|
||||
|
||||
client := &Client{
|
||||
armClient: armClient,
|
||||
rateLimiterReader: rateLimiterReader,
|
||||
rateLimiterWriter: rateLimiterWriter,
|
||||
subscriptionID: config.SubscriptionID,
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
// Get gets a deployment
|
||||
func (c *Client) Get(ctx context.Context, resourceGroupName string, deploymentName string) (resources.DeploymentExtended, *retry.Error) {
|
||||
mc := metrics.NewMetricContext("deployments", "get", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterReader.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return resources.DeploymentExtended{}, retry.GetRateLimitError(false, "GetDeployment")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterReader.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("GetDeployment", "client throttled", c.RetryAfterReader)
|
||||
return resources.DeploymentExtended{}, rerr
|
||||
}
|
||||
|
||||
result, rerr := c.getDeployment(ctx, resourceGroupName, deploymentName)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterReader = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// getDeployment gets a deployment.
|
||||
func (c *Client) getDeployment(ctx context.Context, resourceGroupName string, deploymentName string) (resources.DeploymentExtended, *retry.Error) {
|
||||
resourceID := armclient.GetResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Resources/deployments",
|
||||
deploymentName,
|
||||
)
|
||||
result := resources.DeploymentExtended{}
|
||||
|
||||
response, rerr := c.armClient.GetResource(ctx, resourceID, "")
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "deployment.get.request", resourceID, rerr.Error())
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
err := autorest.Respond(
|
||||
response,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "deployment.get.respond", resourceID, err)
|
||||
return result, retry.GetError(response, err)
|
||||
}
|
||||
|
||||
result.Response = autorest.Response{Response: response}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// List gets a list of deployments in the resource group.
|
||||
func (c *Client) List(ctx context.Context, resourceGroupName string) ([]resources.DeploymentExtended, *retry.Error) {
|
||||
mc := metrics.NewMetricContext("deployments", "list", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterReader.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return nil, retry.GetRateLimitError(false, "ListDeployment")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterReader.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("ListDeployment", "client throttled", c.RetryAfterReader)
|
||||
return nil, rerr
|
||||
}
|
||||
|
||||
result, rerr := c.listDeployment(ctx, resourceGroupName)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterReader = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// listDeployment gets a list of deployments in the resource group.
|
||||
func (c *Client) listDeployment(ctx context.Context, resourceGroupName string) ([]resources.DeploymentExtended, *retry.Error) {
|
||||
resourceID := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Resources/deployments",
|
||||
autorest.Encode("path", c.subscriptionID),
|
||||
autorest.Encode("path", resourceGroupName))
|
||||
result := make([]resources.DeploymentExtended, 0)
|
||||
page := &DeploymentResultPage{}
|
||||
page.fn = c.listNextResults
|
||||
|
||||
resp, rerr := c.armClient.GetResource(ctx, resourceID, "")
|
||||
defer c.armClient.CloseResponse(ctx, resp)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "deployment.list.request", resourceID, rerr.Error())
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
var err error
|
||||
page.dplr, err = c.listResponder(resp)
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "deployment.list.respond", resourceID, err)
|
||||
return result, retry.GetError(resp, err)
|
||||
}
|
||||
|
||||
for {
|
||||
result = append(result, page.Values()...)
|
||||
|
||||
// Abort the loop when there's no nextLink in the response.
|
||||
if to.String(page.Response().NextLink) == "" {
|
||||
break
|
||||
}
|
||||
|
||||
if err = page.NextWithContext(ctx); err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "deployment.list.next", resourceID, err)
|
||||
return result, retry.GetError(page.Response().Response.Response, err)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *Client) listResponder(resp *http.Response) (result resources.DeploymentListResult, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
autorest.ByIgnoring(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// deploymentListResultPreparer prepares a request to retrieve the next set of results.
|
||||
// It returns nil if no more results exist.
|
||||
func (c *Client) deploymentListResultPreparer(ctx context.Context, dplr resources.DeploymentListResult) (*http.Request, error) {
|
||||
if dplr.NextLink == nil || len(to.String(dplr.NextLink)) < 1 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
decorators := []autorest.PrepareDecorator{
|
||||
autorest.WithBaseURL(to.String(dplr.NextLink)),
|
||||
}
|
||||
return c.armClient.PrepareGetRequest(ctx, decorators...)
|
||||
}
|
||||
|
||||
// listNextResults retrieves the next set of results, if any.
|
||||
func (c *Client) listNextResults(ctx context.Context, lastResults resources.DeploymentListResult) (result resources.DeploymentListResult, err error) {
|
||||
req, err := c.deploymentListResultPreparer(ctx, lastResults)
|
||||
if err != nil {
|
||||
return result, autorest.NewErrorWithError(err, "deploymentclient", "listNextResults", nil, "Failure preparing next results request")
|
||||
}
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
|
||||
resp, rerr := c.armClient.Send(ctx, req)
|
||||
defer c.armClient.CloseResponse(ctx, resp)
|
||||
if rerr != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, autorest.NewErrorWithError(rerr.Error(), "deploymentclient", "listNextResults", resp, "Failure sending next results request")
|
||||
}
|
||||
|
||||
result, err = c.listResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "deploymentclient", "listNextResults", resp, "Failure responding to next results request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// DeploymentResultPage contains a page of deployments values.
|
||||
type DeploymentResultPage struct {
|
||||
fn func(context.Context, resources.DeploymentListResult) (resources.DeploymentListResult, error)
|
||||
dplr resources.DeploymentListResult
|
||||
}
|
||||
|
||||
// NextWithContext advances to the next page of values. If there was an error making
|
||||
// the request the page does not advance and the error is returned.
|
||||
func (page *DeploymentResultPage) NextWithContext(ctx context.Context) (err error) {
|
||||
next, err := page.fn(ctx, page.dplr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
page.dplr = next
|
||||
return nil
|
||||
}
|
||||
|
||||
// Next advances to the next page of values. If there was an error making
|
||||
// the request the page does not advance and the error is returned.
|
||||
// Deprecated: Use NextWithContext() instead.
|
||||
func (page *DeploymentResultPage) Next() error {
|
||||
return page.NextWithContext(context.Background())
|
||||
}
|
||||
|
||||
// NotDone returns true if the page enumeration should be started or is not yet complete.
|
||||
func (page DeploymentResultPage) NotDone() bool {
|
||||
return !page.dplr.IsEmpty()
|
||||
}
|
||||
|
||||
// Response returns the raw server response from the last page request.
|
||||
func (page DeploymentResultPage) Response() resources.DeploymentListResult {
|
||||
return page.dplr
|
||||
}
|
||||
|
||||
// Values returns the slice of values for the current page or nil if there are no values.
|
||||
func (page DeploymentResultPage) Values() []resources.DeploymentExtended {
|
||||
if page.dplr.IsEmpty() {
|
||||
return nil
|
||||
}
|
||||
return *page.dplr.Value
|
||||
}
|
||||
|
||||
// CreateOrUpdate creates or updates a deployment.
|
||||
func (c *Client) CreateOrUpdate(ctx context.Context, resourceGroupName string, deploymentName string, parameters resources.Deployment, etag string) *retry.Error {
|
||||
mc := metrics.NewMetricContext("deployments", "create_or_update", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterWriter.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return retry.GetRateLimitError(true, "CreateOrUpdateDeployment")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterWriter.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("CreateOrUpdateDeployment", "client throttled", c.RetryAfterWriter)
|
||||
return rerr
|
||||
}
|
||||
|
||||
rerr := c.createOrUpdateDeployment(ctx, resourceGroupName, deploymentName, parameters, etag)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterWriter = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return rerr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) createOrUpdateDeployment(ctx context.Context, resourceGroupName string, deploymentName string, parameters resources.Deployment, etag string) *retry.Error {
|
||||
resourceID := armclient.GetResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Resources/deployments",
|
||||
deploymentName,
|
||||
)
|
||||
decorators := []autorest.PrepareDecorator{
|
||||
autorest.WithPathParameters("{resourceID}", map[string]interface{}{"resourceID": resourceID}),
|
||||
autorest.WithJSON(parameters),
|
||||
}
|
||||
if etag != "" {
|
||||
decorators = append(decorators, autorest.WithHeader("If-Match", autorest.String(etag)))
|
||||
}
|
||||
|
||||
response, rerr := c.armClient.PutResourceWithDecorators(ctx, resourceID, parameters, decorators)
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "deployment.put.request", resourceID, rerr.Error())
|
||||
return rerr
|
||||
}
|
||||
|
||||
if response != nil && response.StatusCode != http.StatusNoContent {
|
||||
_, rerr = c.createOrUpdateResponder(response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "deployment.put.respond", resourceID, rerr.Error())
|
||||
return rerr
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) createOrUpdateResponder(resp *http.Response) (*resources.DeploymentExtended, *retry.Error) {
|
||||
result := &resources.DeploymentExtended{}
|
||||
err := autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, retry.GetError(resp, err)
|
||||
}
|
||||
|
||||
// Delete deletes a deployment by name.
|
||||
func (c *Client) Delete(ctx context.Context, resourceGroupName string, deploymentName string) *retry.Error {
|
||||
mc := metrics.NewMetricContext("deployments", "delete", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterWriter.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return retry.GetRateLimitError(true, "DeleteDeployment")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterWriter.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("DeleteDeployment", "client throttled", c.RetryAfterWriter)
|
||||
return rerr
|
||||
}
|
||||
|
||||
rerr := c.deleteDeployment(ctx, resourceGroupName, deploymentName)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterWriter = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return rerr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteDeployment deletes a deployment by name.
|
||||
func (c *Client) deleteDeployment(ctx context.Context, resourceGroupName string, deploymentName string) *retry.Error {
|
||||
resourceID := armclient.GetResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Resources/deployments",
|
||||
deploymentName,
|
||||
)
|
||||
|
||||
return c.armClient.DeleteResource(ctx, resourceID, "")
|
||||
}
|
||||
|
||||
// ExportTemplate exports the template used for specified deployment
|
||||
func (c *Client) ExportTemplate(ctx context.Context, resourceGroupName string, deploymentName string) (result resources.DeploymentExportResult, rerr *retry.Error) {
|
||||
mc := metrics.NewMetricContext("deployments", "export_template", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterWriter.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return resources.DeploymentExportResult{}, retry.GetRateLimitError(true, "ExportTemplateDeployment")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterWriter.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("CreateOrUpdateDeployment", "client throttled", c.RetryAfterWriter)
|
||||
return resources.DeploymentExportResult{}, rerr
|
||||
}
|
||||
|
||||
resourceID := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Resources/deployments/%s/exportTemplate",
|
||||
autorest.Encode("path", c.subscriptionID),
|
||||
autorest.Encode("path", resourceGroupName),
|
||||
autorest.Encode("path", deploymentName))
|
||||
response, rerr := c.armClient.PostResource(ctx, resourceID, "exportTemplate", struct{}{}, map[string]interface{}{})
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "deployment.exportTemplate.request", resourceID, rerr.Error())
|
||||
return
|
||||
}
|
||||
|
||||
err := autorest.Respond(
|
||||
response,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "deployment.exportTemplate.respond", resourceID, err)
|
||||
return result, retry.GetError(response, err)
|
||||
}
|
||||
|
||||
result.Response = autorest.Response{Response: response}
|
||||
return result, rerr
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/deploymentclient/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/deploymentclient/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package deploymentclient implements the client for azure deployments.
|
||||
package deploymentclient // import "sigs.k8s.io/cloud-provider-azure/pkg/azureclients/deploymentclient"
|
||||
40
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/deploymentclient/interface.go
generated
vendored
Normal file
40
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/deploymentclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package deploymentclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2017-05-10/resources"
|
||||
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
const (
|
||||
// APIVersion is the API version for resources.
|
||||
APIVersion = "2017-05-10"
|
||||
)
|
||||
|
||||
// Interface is the client interface for Deployments.
|
||||
// Don't forget to run "hack/update-mock-clients.sh" command to generate the mock client.
|
||||
type Interface interface {
|
||||
Get(ctx context.Context, resourceGroupName string, deploymentName string) (resources.DeploymentExtended, *retry.Error)
|
||||
List(ctx context.Context, resourceGroupName string) ([]resources.DeploymentExtended, *retry.Error)
|
||||
ExportTemplate(ctx context.Context, resourceGroupName string, deploymentName string) (result resources.DeploymentExportResult, rerr *retry.Error)
|
||||
CreateOrUpdate(ctx context.Context, resourceGroupName string, managedClusterName string, parameters resources.Deployment, etag string) *retry.Error
|
||||
Delete(ctx context.Context, resourceGroupName string, deploymentName string) *retry.Error
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/diskclient/mockdiskclient/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/diskclient/mockdiskclient/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package mockdiskclient implements the mock client for Disks.
|
||||
package mockdiskclient // import "sigs.k8s.io/cloud-provider-azure/pkg/azureclients/diskclient/mockdiskclient"
|
||||
126
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/diskclient/mockdiskclient/interface.go
generated
vendored
Normal file
126
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/diskclient/mockdiskclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
// /*
|
||||
// Copyright The Kubernetes Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// */
|
||||
//
|
||||
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: /go/src/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/diskclient/interface.go
|
||||
|
||||
// Package mockdiskclient is a generated GoMock package.
|
||||
package mockdiskclient
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
compute "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-12-01/compute"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
retry "sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
// MockInterface is a mock of Interface interface.
|
||||
type MockInterface struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockInterfaceMockRecorder
|
||||
}
|
||||
|
||||
// MockInterfaceMockRecorder is the mock recorder for MockInterface.
|
||||
type MockInterfaceMockRecorder struct {
|
||||
mock *MockInterface
|
||||
}
|
||||
|
||||
// NewMockInterface creates a new mock instance.
|
||||
func NewMockInterface(ctrl *gomock.Controller) *MockInterface {
|
||||
mock := &MockInterface{ctrl: ctrl}
|
||||
mock.recorder = &MockInterfaceMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Get mocks base method.
|
||||
func (m *MockInterface) Get(ctx context.Context, resourceGroupName, diskName string) (compute.Disk, *retry.Error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Get", ctx, resourceGroupName, diskName)
|
||||
ret0, _ := ret[0].(compute.Disk)
|
||||
ret1, _ := ret[1].(*retry.Error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Get indicates an expected call of Get.
|
||||
func (mr *MockInterfaceMockRecorder) Get(ctx, resourceGroupName, diskName interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockInterface)(nil).Get), ctx, resourceGroupName, diskName)
|
||||
}
|
||||
|
||||
// CreateOrUpdate mocks base method.
|
||||
func (m *MockInterface) CreateOrUpdate(ctx context.Context, resourceGroupName, diskName string, diskParameter compute.Disk) *retry.Error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CreateOrUpdate", ctx, resourceGroupName, diskName, diskParameter)
|
||||
ret0, _ := ret[0].(*retry.Error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// CreateOrUpdate indicates an expected call of CreateOrUpdate.
|
||||
func (mr *MockInterfaceMockRecorder) CreateOrUpdate(ctx, resourceGroupName, diskName, diskParameter interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateOrUpdate", reflect.TypeOf((*MockInterface)(nil).CreateOrUpdate), ctx, resourceGroupName, diskName, diskParameter)
|
||||
}
|
||||
|
||||
// Update mocks base method.
|
||||
func (m *MockInterface) Update(ctx context.Context, resourceGroupName, diskName string, diskParameter compute.DiskUpdate) *retry.Error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Update", ctx, resourceGroupName, diskName, diskParameter)
|
||||
ret0, _ := ret[0].(*retry.Error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Update indicates an expected call of Update.
|
||||
func (mr *MockInterfaceMockRecorder) Update(ctx, resourceGroupName, diskName, diskParameter interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockInterface)(nil).Update), ctx, resourceGroupName, diskName, diskParameter)
|
||||
}
|
||||
|
||||
// Delete mocks base method.
|
||||
func (m *MockInterface) Delete(ctx context.Context, resourceGroupName, diskName string) *retry.Error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Delete", ctx, resourceGroupName, diskName)
|
||||
ret0, _ := ret[0].(*retry.Error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Delete indicates an expected call of Delete.
|
||||
func (mr *MockInterfaceMockRecorder) Delete(ctx, resourceGroupName, diskName interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockInterface)(nil).Delete), ctx, resourceGroupName, diskName)
|
||||
}
|
||||
|
||||
// ListByResourceGroup mocks base method.
|
||||
func (m *MockInterface) ListByResourceGroup(ctx context.Context, resourceGroupName string) ([]compute.Disk, *retry.Error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ListByResourceGroup", ctx, resourceGroupName)
|
||||
ret0, _ := ret[0].([]compute.Disk)
|
||||
ret1, _ := ret[1].(*retry.Error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ListByResourceGroup indicates an expected call of ListByResourceGroup.
|
||||
func (mr *MockInterfaceMockRecorder) ListByResourceGroup(ctx, resourceGroupName interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListByResourceGroup", reflect.TypeOf((*MockInterface)(nil).ListByResourceGroup), ctx, resourceGroupName)
|
||||
}
|
||||
173
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/fileclient/azure_fileclient.go
generated
vendored
Normal file
173
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/fileclient/azure_fileclient.go
generated
vendored
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package fileclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2021-02-01/storage"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
azclients "sigs.k8s.io/cloud-provider-azure/pkg/azureclients"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/metrics"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
// Client implements the azure file client interface
|
||||
type Client struct {
|
||||
fileSharesClient storage.FileSharesClient
|
||||
fileServicesClient storage.FileServicesClient
|
||||
|
||||
subscriptionID string
|
||||
}
|
||||
|
||||
// ShareOptions contains the fields which are used to create file share.
|
||||
type ShareOptions struct {
|
||||
Name string
|
||||
Protocol storage.EnabledProtocols
|
||||
RequestGiB int
|
||||
// supported values: ""(by default), "TransactionOptimized", "Cool", "Hot", "Premium"
|
||||
AccessTier string
|
||||
}
|
||||
|
||||
// New creates a azure file client
|
||||
func New(config *azclients.ClientConfig) *Client {
|
||||
fileSharesClient := storage.NewFileSharesClientWithBaseURI(config.ResourceManagerEndpoint, config.SubscriptionID)
|
||||
fileSharesClient.Authorizer = config.Authorizer
|
||||
|
||||
fileServicesClient := storage.NewFileServicesClientWithBaseURI(config.ResourceManagerEndpoint, config.SubscriptionID)
|
||||
fileServicesClient.Authorizer = config.Authorizer
|
||||
return &Client{
|
||||
fileSharesClient: fileSharesClient,
|
||||
fileServicesClient: fileServicesClient,
|
||||
subscriptionID: config.SubscriptionID,
|
||||
}
|
||||
}
|
||||
|
||||
// CreateFileShare creates a file share
|
||||
func (c *Client) CreateFileShare(resourceGroupName, accountName string, shareOptions *ShareOptions) error {
|
||||
mc := metrics.NewMetricContext("file_shares", "create", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
if shareOptions == nil {
|
||||
return fmt.Errorf("share options is nil")
|
||||
}
|
||||
quota := int32(shareOptions.RequestGiB)
|
||||
fileShareProperties := &storage.FileShareProperties{
|
||||
ShareQuota: "a,
|
||||
}
|
||||
if shareOptions.Protocol == storage.EnabledProtocolsNFS {
|
||||
fileShareProperties.EnabledProtocols = shareOptions.Protocol
|
||||
}
|
||||
if shareOptions.AccessTier != "" {
|
||||
fileShareProperties.AccessTier = storage.ShareAccessTier(shareOptions.AccessTier)
|
||||
}
|
||||
fileShare := storage.FileShare{
|
||||
Name: &shareOptions.Name,
|
||||
FileShareProperties: fileShareProperties,
|
||||
}
|
||||
_, err := c.fileSharesClient.Create(context.Background(), resourceGroupName, accountName, shareOptions.Name, fileShare, "")
|
||||
var rerr *retry.Error
|
||||
if err != nil {
|
||||
rerr = &retry.Error{
|
||||
RawError: err,
|
||||
}
|
||||
}
|
||||
mc.Observe(rerr)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteFileShare deletes a file share
|
||||
func (c *Client) DeleteFileShare(resourceGroupName, accountName, name string) error {
|
||||
mc := metrics.NewMetricContext("file_shares", "delete", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
_, err := c.fileSharesClient.Delete(context.Background(), resourceGroupName, accountName, name, "")
|
||||
var rerr *retry.Error
|
||||
if err != nil {
|
||||
rerr = &retry.Error{
|
||||
RawError: err,
|
||||
}
|
||||
}
|
||||
mc.Observe(rerr)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// ResizeFileShare resizes a file share
|
||||
func (c *Client) ResizeFileShare(resourceGroupName, accountName, name string, sizeGiB int) error {
|
||||
mc := metrics.NewMetricContext("file_shares", "resize", resourceGroupName, c.subscriptionID, "")
|
||||
var rerr *retry.Error
|
||||
|
||||
quota := int32(sizeGiB)
|
||||
|
||||
share, err := c.fileSharesClient.Get(context.Background(), resourceGroupName, accountName, name, storage.GetShareExpandStats, "")
|
||||
if err != nil {
|
||||
rerr = &retry.Error{
|
||||
RawError: err,
|
||||
}
|
||||
mc.Observe(rerr)
|
||||
return fmt.Errorf("failed to get file share (%s): %w", name, err)
|
||||
}
|
||||
if *share.FileShareProperties.ShareQuota >= quota {
|
||||
klog.Warningf("file share size(%dGi) is already greater or equal than requested size(%dGi), accountName: %s, shareName: %s",
|
||||
share.FileShareProperties.ShareQuota, sizeGiB, accountName, name)
|
||||
return nil
|
||||
}
|
||||
|
||||
share.FileShareProperties.ShareQuota = "a
|
||||
_, err = c.fileSharesClient.Update(context.Background(), resourceGroupName, accountName, name, share)
|
||||
if err != nil {
|
||||
rerr = &retry.Error{
|
||||
RawError: err,
|
||||
}
|
||||
mc.Observe(rerr)
|
||||
return fmt.Errorf("failed to update quota on file share(%s), err: %w", name, err)
|
||||
}
|
||||
|
||||
mc.Observe(rerr)
|
||||
klog.V(4).Infof("resize file share completed, resourceGroupName(%s), accountName: %s, shareName: %s, sizeGiB: %d", resourceGroupName, accountName, name, sizeGiB)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetFileShare gets a file share
|
||||
func (c *Client) GetFileShare(resourceGroupName, accountName, name string) (storage.FileShare, error) {
|
||||
mc := metrics.NewMetricContext("file_shares", "get", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
result, err := c.fileSharesClient.Get(context.Background(), resourceGroupName, accountName, name, storage.GetShareExpandStats, "")
|
||||
var rerr *retry.Error
|
||||
if err != nil {
|
||||
rerr = &retry.Error{
|
||||
RawError: err,
|
||||
}
|
||||
}
|
||||
mc.Observe(rerr)
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
// GetServiceProperties get service properties
|
||||
func (c *Client) GetServiceProperties(resourceGroupName, accountName string) (storage.FileServiceProperties, error) {
|
||||
return c.fileServicesClient.GetServiceProperties(context.Background(), resourceGroupName, accountName)
|
||||
}
|
||||
|
||||
// SetServiceProperties set service properties
|
||||
func (c *Client) SetServiceProperties(resourceGroupName, accountName string, parameters storage.FileServiceProperties) (storage.FileServiceProperties, error) {
|
||||
return c.fileServicesClient.SetServiceProperties(context.Background(), resourceGroupName, accountName, parameters)
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/fileclient/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/fileclient/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package fileclient implements the client for azure file.
|
||||
package fileclient // import "sigs.k8s.io/cloud-provider-azure/pkg/azureclients/fileclient"
|
||||
32
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/fileclient/interface.go
generated
vendored
Normal file
32
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/fileclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package fileclient
|
||||
|
||||
import (
|
||||
"github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2021-02-01/storage"
|
||||
)
|
||||
|
||||
// Interface is the client interface for creating file shares, interface for test injection.
|
||||
// Don't forget to run "hack/update-mock-clients.sh" command to generate the mock client.
|
||||
type Interface interface {
|
||||
CreateFileShare(resourceGroupName, accountName string, shareOptions *ShareOptions) error
|
||||
DeleteFileShare(resourceGroupName, accountName, name string) error
|
||||
ResizeFileShare(resourceGroupName, accountName, name string, sizeGiB int) error
|
||||
GetFileShare(resourceGroupName, accountName, name string) (storage.FileShare, error)
|
||||
GetServiceProperties(resourceGroupName, accountName string) (storage.FileServiceProperties, error)
|
||||
SetServiceProperties(resourceGroupName, accountName string, parameters storage.FileServiceProperties) (storage.FileServiceProperties, error)
|
||||
}
|
||||
503
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/loadbalancerclient/azure_loadbalancerclient.go
generated
vendored
Normal file
503
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/loadbalancerclient/azure_loadbalancerclient.go
generated
vendored
Normal file
|
|
@ -0,0 +1,503 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package loadbalancerclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
azclients "sigs.k8s.io/cloud-provider-azure/pkg/azureclients"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/armclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/metrics"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
var _ Interface = &Client{}
|
||||
|
||||
// Client implements LoadBalancer client Interface.
|
||||
type Client struct {
|
||||
armClient armclient.Interface
|
||||
subscriptionID string
|
||||
cloudName string
|
||||
|
||||
// Rate limiting configures.
|
||||
rateLimiterReader flowcontrol.RateLimiter
|
||||
rateLimiterWriter flowcontrol.RateLimiter
|
||||
|
||||
// ARM throttling configures.
|
||||
RetryAfterReader time.Time
|
||||
RetryAfterWriter time.Time
|
||||
}
|
||||
|
||||
// New creates a new LoadBalancer client with ratelimiting.
|
||||
func New(config *azclients.ClientConfig) *Client {
|
||||
baseURI := config.ResourceManagerEndpoint
|
||||
authorizer := config.Authorizer
|
||||
apiVersion := APIVersion
|
||||
if strings.EqualFold(config.CloudName, AzureStackCloudName) && !config.DisableAzureStackCloud {
|
||||
apiVersion = AzureStackCloudAPIVersion
|
||||
}
|
||||
armClient := armclient.New(authorizer, *config, baseURI, apiVersion)
|
||||
rateLimiterReader, rateLimiterWriter := azclients.NewRateLimiter(config.RateLimitConfig)
|
||||
|
||||
if azclients.RateLimitEnabled(config.RateLimitConfig) {
|
||||
klog.V(2).Infof("Azure LoadBalancersClient (read ops) using rate limit config: QPS=%g, bucket=%d",
|
||||
config.RateLimitConfig.CloudProviderRateLimitQPS,
|
||||
config.RateLimitConfig.CloudProviderRateLimitBucket)
|
||||
klog.V(2).Infof("Azure LoadBalancersClient (write ops) using rate limit config: QPS=%g, bucket=%d",
|
||||
config.RateLimitConfig.CloudProviderRateLimitQPSWrite,
|
||||
config.RateLimitConfig.CloudProviderRateLimitBucketWrite)
|
||||
}
|
||||
|
||||
client := &Client{
|
||||
armClient: armClient,
|
||||
rateLimiterReader: rateLimiterReader,
|
||||
rateLimiterWriter: rateLimiterWriter,
|
||||
subscriptionID: config.SubscriptionID,
|
||||
cloudName: config.CloudName,
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
// Get gets a LoadBalancer.
|
||||
func (c *Client) Get(ctx context.Context, resourceGroupName string, loadBalancerName string, expand string) (network.LoadBalancer, *retry.Error) {
|
||||
mc := metrics.NewMetricContext("load_balancers", "get", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterReader.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return network.LoadBalancer{}, retry.GetRateLimitError(false, "LBGet")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterReader.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("LBGet", "client throttled", c.RetryAfterReader)
|
||||
return network.LoadBalancer{}, rerr
|
||||
}
|
||||
|
||||
result, rerr := c.getLB(ctx, resourceGroupName, loadBalancerName, expand)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterReader = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// getLB gets a LoadBalancer.
|
||||
func (c *Client) getLB(ctx context.Context, resourceGroupName string, loadBalancerName string, expand string) (network.LoadBalancer, *retry.Error) {
|
||||
resourceID := armclient.GetResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Network/loadBalancers",
|
||||
loadBalancerName,
|
||||
)
|
||||
result := network.LoadBalancer{}
|
||||
|
||||
response, rerr := c.armClient.GetResource(ctx, resourceID, expand)
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "loadbalancer.get.request", resourceID, rerr.Error())
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
err := autorest.Respond(
|
||||
response,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "loadbalancer.get.respond", resourceID, err)
|
||||
return result, retry.GetError(response, err)
|
||||
}
|
||||
|
||||
result.Response = autorest.Response{Response: response}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// List gets a list of LoadBalancer in the resource group.
|
||||
func (c *Client) List(ctx context.Context, resourceGroupName string) ([]network.LoadBalancer, *retry.Error) {
|
||||
mc := metrics.NewMetricContext("load_balancers", "list", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterReader.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return nil, retry.GetRateLimitError(false, "LBList")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterReader.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("LBList", "client throttled", c.RetryAfterReader)
|
||||
return nil, rerr
|
||||
}
|
||||
|
||||
result, rerr := c.listLB(ctx, resourceGroupName)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterReader = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// listLB gets a list of LoadBalancers in the resource group.
|
||||
func (c *Client) listLB(ctx context.Context, resourceGroupName string) ([]network.LoadBalancer, *retry.Error) {
|
||||
resourceID := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/loadBalancers",
|
||||
autorest.Encode("path", c.subscriptionID),
|
||||
autorest.Encode("path", resourceGroupName))
|
||||
result := make([]network.LoadBalancer, 0)
|
||||
page := &LoadBalancerListResultPage{}
|
||||
page.fn = c.listNextResults
|
||||
|
||||
resp, rerr := c.armClient.GetResource(ctx, resourceID, "")
|
||||
defer c.armClient.CloseResponse(ctx, resp)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "loadbalancer.list.request", resourceID, rerr.Error())
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
var err error
|
||||
page.lblr, err = c.listResponder(resp)
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "loadbalancer.list.respond", resourceID, err)
|
||||
return result, retry.GetError(resp, err)
|
||||
}
|
||||
|
||||
for {
|
||||
result = append(result, page.Values()...)
|
||||
|
||||
// Abort the loop when there's no nextLink in the response.
|
||||
if to.String(page.Response().NextLink) == "" {
|
||||
break
|
||||
}
|
||||
|
||||
if err = page.NextWithContext(ctx); err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "loadbalancer.list.next", resourceID, err)
|
||||
return result, retry.GetError(page.Response().Response.Response, err)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// CreateOrUpdate creates or updates a LoadBalancer.
|
||||
func (c *Client) CreateOrUpdate(ctx context.Context, resourceGroupName string, loadBalancerName string, parameters network.LoadBalancer, etag string) *retry.Error {
|
||||
mc := metrics.NewMetricContext("load_balancers", "create_or_update", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterWriter.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return retry.GetRateLimitError(true, "LBCreateOrUpdate")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterWriter.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("LBCreateOrUpdate", "client throttled", c.RetryAfterWriter)
|
||||
return rerr
|
||||
}
|
||||
|
||||
rerr := c.createOrUpdateLB(ctx, resourceGroupName, loadBalancerName, parameters, etag)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterWriter = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return rerr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// createOrUpdateLB creates or updates a LoadBalancer.
|
||||
func (c *Client) createOrUpdateLB(ctx context.Context, resourceGroupName string, loadBalancerName string, parameters network.LoadBalancer, etag string) *retry.Error {
|
||||
resourceID := armclient.GetResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Network/loadBalancers",
|
||||
loadBalancerName,
|
||||
)
|
||||
decorators := []autorest.PrepareDecorator{
|
||||
autorest.WithPathParameters("{resourceID}", map[string]interface{}{"resourceID": resourceID}),
|
||||
autorest.WithJSON(parameters),
|
||||
}
|
||||
if etag != "" {
|
||||
decorators = append(decorators, autorest.WithHeader("If-Match", autorest.String(etag)))
|
||||
}
|
||||
|
||||
response, rerr := c.armClient.PutResourceWithDecorators(ctx, resourceID, parameters, decorators)
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "loadbalancer.put.request", resourceID, rerr.Error())
|
||||
return rerr
|
||||
}
|
||||
|
||||
if response != nil && response.StatusCode != http.StatusNoContent {
|
||||
_, rerr = c.createOrUpdateResponder(response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "loadbalancer.put.respond", resourceID, rerr.Error())
|
||||
return rerr
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) createOrUpdateResponder(resp *http.Response) (*network.LoadBalancer, *retry.Error) {
|
||||
result := &network.LoadBalancer{}
|
||||
err := autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, retry.GetError(resp, err)
|
||||
}
|
||||
|
||||
// Delete deletes a LoadBalancer by name.
|
||||
func (c *Client) Delete(ctx context.Context, resourceGroupName string, loadBalancerName string) *retry.Error {
|
||||
mc := metrics.NewMetricContext("load_balancers", "delete", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterWriter.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return retry.GetRateLimitError(true, "LBDelete")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterWriter.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("LBDelete", "client throttled", c.RetryAfterWriter)
|
||||
return rerr
|
||||
}
|
||||
|
||||
rerr := c.deleteLB(ctx, resourceGroupName, loadBalancerName)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterWriter = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return rerr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteLB deletes a LoadBalancer by name.
|
||||
func (c *Client) deleteLB(ctx context.Context, resourceGroupName string, loadBalancerName string) *retry.Error {
|
||||
resourceID := armclient.GetResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Network/loadBalancers",
|
||||
loadBalancerName,
|
||||
)
|
||||
|
||||
return c.armClient.DeleteResource(ctx, resourceID, "")
|
||||
}
|
||||
|
||||
func (c *Client) listResponder(resp *http.Response) (result network.LoadBalancerListResult, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
autorest.ByIgnoring(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// loadBalancerListResultPreparer prepares a request to retrieve the next set of results.
|
||||
// It returns nil if no more results exist.
|
||||
func (c *Client) loadBalancerListResultPreparer(ctx context.Context, lblr network.LoadBalancerListResult) (*http.Request, error) {
|
||||
if lblr.NextLink == nil || len(to.String(lblr.NextLink)) < 1 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
decorators := []autorest.PrepareDecorator{
|
||||
autorest.WithBaseURL(to.String(lblr.NextLink)),
|
||||
}
|
||||
return c.armClient.PrepareGetRequest(ctx, decorators...)
|
||||
}
|
||||
|
||||
// listNextResults retrieves the next set of results, if any.
|
||||
func (c *Client) listNextResults(ctx context.Context, lastResults network.LoadBalancerListResult) (result network.LoadBalancerListResult, err error) {
|
||||
req, err := c.loadBalancerListResultPreparer(ctx, lastResults)
|
||||
if err != nil {
|
||||
return result, autorest.NewErrorWithError(err, "loadbalancerclient", "listNextResults", nil, "Failure preparing next results request")
|
||||
}
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
|
||||
resp, rerr := c.armClient.Send(ctx, req)
|
||||
defer c.armClient.CloseResponse(ctx, resp)
|
||||
if rerr != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, autorest.NewErrorWithError(rerr.Error(), "loadbalancerclient", "listNextResults", resp, "Failure sending next results request")
|
||||
}
|
||||
|
||||
result, err = c.listResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "loadbalancerclient", "listNextResults", resp, "Failure responding to next results request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// LoadBalancerListResultPage contains a page of LoadBalancer values.
|
||||
type LoadBalancerListResultPage struct {
|
||||
fn func(context.Context, network.LoadBalancerListResult) (network.LoadBalancerListResult, error)
|
||||
lblr network.LoadBalancerListResult
|
||||
}
|
||||
|
||||
// NextWithContext advances to the next page of values. If there was an error making
|
||||
// the request the page does not advance and the error is returned.
|
||||
func (page *LoadBalancerListResultPage) NextWithContext(ctx context.Context) (err error) {
|
||||
next, err := page.fn(ctx, page.lblr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
page.lblr = next
|
||||
return nil
|
||||
}
|
||||
|
||||
// Next advances to the next page of values. If there was an error making
|
||||
// the request the page does not advance and the error is returned.
|
||||
// Deprecated: Use NextWithContext() instead.
|
||||
func (page *LoadBalancerListResultPage) Next() error {
|
||||
return page.NextWithContext(context.Background())
|
||||
}
|
||||
|
||||
// NotDone returns true if the page enumeration should be started or is not yet complete.
|
||||
func (page LoadBalancerListResultPage) NotDone() bool {
|
||||
return !page.lblr.IsEmpty()
|
||||
}
|
||||
|
||||
// Response returns the raw server response from the last page request.
|
||||
func (page LoadBalancerListResultPage) Response() network.LoadBalancerListResult {
|
||||
return page.lblr
|
||||
}
|
||||
|
||||
// Values returns the slice of values for the current page or nil if there are no values.
|
||||
func (page LoadBalancerListResultPage) Values() []network.LoadBalancer {
|
||||
if page.lblr.IsEmpty() {
|
||||
return nil
|
||||
}
|
||||
return *page.lblr.Value
|
||||
}
|
||||
|
||||
// CreateOrUpdateBackendPools creates or updates a LoadBalancer backend pool.
|
||||
func (c *Client) CreateOrUpdateBackendPools(ctx context.Context, resourceGroupName string, loadBalancerName string, backendPoolName string, parameters network.BackendAddressPool, etag string) *retry.Error {
|
||||
mc := metrics.NewMetricContext("load_balancers", "create_or_update_backend_pools", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterWriter.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return retry.GetRateLimitError(true, "LBCreateOrUpdateBackendPools")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterWriter.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("LBCreateOrUpdateBackendPools", "client throttled", c.RetryAfterWriter)
|
||||
return rerr
|
||||
}
|
||||
|
||||
rerr := c.createOrUpdateLBBackendPool(ctx, resourceGroupName, loadBalancerName, backendPoolName, parameters, etag)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterWriter = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return rerr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// createOrUpdateLBBackendPool creates or updates a LoadBalancer.
|
||||
func (c *Client) createOrUpdateLBBackendPool(ctx context.Context, resourceGroupName string, loadBalancerName string, backendPoolName string, parameters network.BackendAddressPool, etag string) *retry.Error {
|
||||
resourceID := armclient.GetChildResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Network/loadBalancers",
|
||||
loadBalancerName,
|
||||
"backendAddressPools",
|
||||
backendPoolName,
|
||||
)
|
||||
decorators := []autorest.PrepareDecorator{
|
||||
autorest.WithPathParameters("{resourceID}", map[string]interface{}{"resourceID": resourceID}),
|
||||
autorest.WithJSON(parameters),
|
||||
}
|
||||
if etag != "" {
|
||||
decorators = append(decorators, autorest.WithHeader("If-Match", autorest.String(etag)))
|
||||
}
|
||||
|
||||
response, rerr := c.armClient.PutResourceWithDecorators(ctx, resourceID, parameters, decorators)
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "loadbalancerbackendpool.put.request", resourceID, rerr.Error())
|
||||
return rerr
|
||||
}
|
||||
|
||||
if response != nil && response.StatusCode != http.StatusNoContent {
|
||||
_, rerr = c.createOrUpdateBackendPoolResponder(response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "loadbalancerbackendpool.put.respond", resourceID, rerr.Error())
|
||||
return rerr
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) createOrUpdateBackendPoolResponder(resp *http.Response) (*network.BackendAddressPool, *retry.Error) {
|
||||
result := &network.BackendAddressPool{}
|
||||
err := autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, retry.GetError(resp, err)
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/loadbalancerclient/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/loadbalancerclient/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package loadbalancerclient implements the client for LoadBalancer.
|
||||
package loadbalancerclient // import "sigs.k8s.io/cloud-provider-azure/pkg/azureclients/loadbalancerclient"
|
||||
53
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/loadbalancerclient/interface.go
generated
vendored
Normal file
53
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/loadbalancerclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package loadbalancerclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
const (
|
||||
// APIVersion is the API version for network.
|
||||
APIVersion = "2020-08-01"
|
||||
// AzureStackCloudAPIVersion is the API version for Azure Stack
|
||||
AzureStackCloudAPIVersion = "2018-11-01"
|
||||
// AzureStackCloudName is the cloud name of Azure Stack
|
||||
AzureStackCloudName = "AZURESTACKCLOUD"
|
||||
)
|
||||
|
||||
// Interface is the client interface for LoadBalancer.
|
||||
// Don't forget to run "hack/update-mock-clients.sh" command to generate the mock client.
|
||||
type Interface interface {
|
||||
// Get gets a LoadBalancer.
|
||||
Get(ctx context.Context, resourceGroupName string, loadBalancerName string, expand string) (result network.LoadBalancer, rerr *retry.Error)
|
||||
|
||||
// List gets a list of LoadBalancer in the resource group.
|
||||
List(ctx context.Context, resourceGroupName string) (result []network.LoadBalancer, rerr *retry.Error)
|
||||
|
||||
// CreateOrUpdate creates or updates a LoadBalancer.
|
||||
CreateOrUpdate(ctx context.Context, resourceGroupName string, loadBalancerName string, parameters network.LoadBalancer, etag string) *retry.Error
|
||||
|
||||
// CreateOrUpdateBackendPools creates or updates loadbalancer's backend address pool.
|
||||
CreateOrUpdateBackendPools(ctx context.Context, resourceGroupName string, loadBalancerName string, backendPoolName string, parameters network.BackendAddressPool, etag string) *retry.Error
|
||||
|
||||
// Delete deletes a LoadBalancer by name.
|
||||
Delete(ctx context.Context, resourceGroupName string, loadBalancerName string) *retry.Error
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/loadbalancerclient/mockloadbalancerclient/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/loadbalancerclient/mockloadbalancerclient/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package mockloadbalancerclient implements the mock client for LoadBalancer.
|
||||
package mockloadbalancerclient // import "sigs.k8s.io/cloud-provider-azure/pkg/azureclients/loadbalancerclient/mockloadbalancerclient"
|
||||
126
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/loadbalancerclient/mockloadbalancerclient/interface.go
generated
vendored
Normal file
126
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/loadbalancerclient/mockloadbalancerclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
// /*
|
||||
// Copyright The Kubernetes Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// */
|
||||
//
|
||||
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: /go/src/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/loadbalancerclient/interface.go
|
||||
|
||||
// Package mockloadbalancerclient is a generated GoMock package.
|
||||
package mockloadbalancerclient
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
network "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
retry "sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
// MockInterface is a mock of Interface interface.
|
||||
type MockInterface struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockInterfaceMockRecorder
|
||||
}
|
||||
|
||||
// MockInterfaceMockRecorder is the mock recorder for MockInterface.
|
||||
type MockInterfaceMockRecorder struct {
|
||||
mock *MockInterface
|
||||
}
|
||||
|
||||
// NewMockInterface creates a new mock instance.
|
||||
func NewMockInterface(ctrl *gomock.Controller) *MockInterface {
|
||||
mock := &MockInterface{ctrl: ctrl}
|
||||
mock.recorder = &MockInterfaceMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Get mocks base method.
|
||||
func (m *MockInterface) Get(ctx context.Context, resourceGroupName, loadBalancerName, expand string) (network.LoadBalancer, *retry.Error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Get", ctx, resourceGroupName, loadBalancerName, expand)
|
||||
ret0, _ := ret[0].(network.LoadBalancer)
|
||||
ret1, _ := ret[1].(*retry.Error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Get indicates an expected call of Get.
|
||||
func (mr *MockInterfaceMockRecorder) Get(ctx, resourceGroupName, loadBalancerName, expand interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockInterface)(nil).Get), ctx, resourceGroupName, loadBalancerName, expand)
|
||||
}
|
||||
|
||||
// List mocks base method.
|
||||
func (m *MockInterface) List(ctx context.Context, resourceGroupName string) ([]network.LoadBalancer, *retry.Error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "List", ctx, resourceGroupName)
|
||||
ret0, _ := ret[0].([]network.LoadBalancer)
|
||||
ret1, _ := ret[1].(*retry.Error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// List indicates an expected call of List.
|
||||
func (mr *MockInterfaceMockRecorder) List(ctx, resourceGroupName interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockInterface)(nil).List), ctx, resourceGroupName)
|
||||
}
|
||||
|
||||
// CreateOrUpdate mocks base method.
|
||||
func (m *MockInterface) CreateOrUpdate(ctx context.Context, resourceGroupName, loadBalancerName string, parameters network.LoadBalancer, etag string) *retry.Error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CreateOrUpdate", ctx, resourceGroupName, loadBalancerName, parameters, etag)
|
||||
ret0, _ := ret[0].(*retry.Error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// CreateOrUpdate indicates an expected call of CreateOrUpdate.
|
||||
func (mr *MockInterfaceMockRecorder) CreateOrUpdate(ctx, resourceGroupName, loadBalancerName, parameters, etag interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateOrUpdate", reflect.TypeOf((*MockInterface)(nil).CreateOrUpdate), ctx, resourceGroupName, loadBalancerName, parameters, etag)
|
||||
}
|
||||
|
||||
// CreateOrUpdateBackendPools mocks base method.
|
||||
func (m *MockInterface) CreateOrUpdateBackendPools(ctx context.Context, resourceGroupName, loadBalancerName, backendPoolName string, parameters network.BackendAddressPool, etag string) *retry.Error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CreateOrUpdateBackendPools", ctx, resourceGroupName, loadBalancerName, backendPoolName, parameters, etag)
|
||||
ret0, _ := ret[0].(*retry.Error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// CreateOrUpdateBackendPools indicates an expected call of CreateOrUpdateBackendPools.
|
||||
func (mr *MockInterfaceMockRecorder) CreateOrUpdateBackendPools(ctx, resourceGroupName, loadBalancerName, backendPoolName, parameters, etag interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateOrUpdateBackendPools", reflect.TypeOf((*MockInterface)(nil).CreateOrUpdateBackendPools), ctx, resourceGroupName, loadBalancerName, backendPoolName, parameters, etag)
|
||||
}
|
||||
|
||||
// Delete mocks base method.
|
||||
func (m *MockInterface) Delete(ctx context.Context, resourceGroupName, loadBalancerName string) *retry.Error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Delete", ctx, resourceGroupName, loadBalancerName)
|
||||
ret0, _ := ret[0].(*retry.Error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Delete indicates an expected call of Delete.
|
||||
func (mr *MockInterfaceMockRecorder) Delete(ctx, resourceGroupName, loadBalancerName interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockInterface)(nil).Delete), ctx, resourceGroupName, loadBalancerName)
|
||||
}
|
||||
65
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/privatednsclient/azure_privatednsclient.go
generated
vendored
Normal file
65
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/privatednsclient/azure_privatednsclient.go
generated
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package privatednsclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns"
|
||||
"k8s.io/klog/v2"
|
||||
azclients "sigs.k8s.io/cloud-provider-azure/pkg/azureclients"
|
||||
)
|
||||
|
||||
var _ Interface = &Client{}
|
||||
|
||||
// Client implements privatednsclient Interface.
|
||||
type Client struct {
|
||||
privateDNSClient privatedns.PrivateZonesClient
|
||||
}
|
||||
|
||||
// New creates a new privatedns client.
|
||||
func New(config *azclients.ClientConfig) *Client {
|
||||
privateDNSClient := privatedns.NewPrivateZonesClientWithBaseURI(config.ResourceManagerEndpoint, config.SubscriptionID)
|
||||
privateDNSClient.Authorizer = config.Authorizer
|
||||
client := &Client{
|
||||
privateDNSClient: privateDNSClient,
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// CreateOrUpdate creates or updates a private dns zone
|
||||
func (c *Client) CreateOrUpdate(ctx context.Context, resourceGroupName string, privateZoneName string, parameters privatedns.PrivateZone, waitForCompletion bool) error {
|
||||
createOrUpdateFuture, err := c.privateDNSClient.CreateOrUpdate(ctx, resourceGroupName, privateZoneName, parameters, "", "*")
|
||||
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error for %s, resourceGroup: %s, error: %s", "privatedns.put.request", resourceGroupName, err)
|
||||
return err
|
||||
}
|
||||
|
||||
if waitForCompletion {
|
||||
err := createOrUpdateFuture.WaitForCompletionRef(ctx, c.privateDNSClient.Client)
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error while waiting for completion for %s, resourceGroup: %s, error: %s", "privatedns.put.request", resourceGroupName, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) Get(ctx context.Context, resourceGroupName string, privateZoneName string) (result privatedns.PrivateZone, err error) {
|
||||
return c.privateDNSClient.Get(ctx, resourceGroupName, privateZoneName)
|
||||
}
|
||||
34
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/privatednsclient/interface.go
generated
vendored
Normal file
34
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/privatednsclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package privatednsclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns"
|
||||
)
|
||||
|
||||
// Interface is the client interface for Private DNS Zones
|
||||
// Don't forget to run "hack/update-mock-clients.sh" command to generate the mock client.
|
||||
type Interface interface {
|
||||
|
||||
//Get gets the PrivateDNSZone
|
||||
Get(ctx context.Context, resourceGroupName string, privateZoneName string) (result privatedns.PrivateZone, err error)
|
||||
|
||||
// CreateOrUpdate creates or updates a private dns zone.
|
||||
CreateOrUpdate(ctx context.Context, resourceGroupName string, privateZoneName string, parameters privatedns.PrivateZone, waitForCompletion bool) error
|
||||
}
|
||||
64
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/privatednszonegroupclient/azure_privatednszonegroupclient.go
generated
vendored
Normal file
64
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/privatednszonegroupclient/azure_privatednszonegroupclient.go
generated
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package privatednszonegroupclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
"k8s.io/klog/v2"
|
||||
azclients "sigs.k8s.io/cloud-provider-azure/pkg/azureclients"
|
||||
)
|
||||
|
||||
var _ Interface = &Client{}
|
||||
|
||||
// Client implements privatednszonegroupclient client Interface.
|
||||
type Client struct {
|
||||
privateDNSZoneGroupClient network.PrivateDNSZoneGroupsClient
|
||||
}
|
||||
|
||||
// New creates a new private dns zone group client.
|
||||
func New(config *azclients.ClientConfig) *Client {
|
||||
privateDNSZoneGroupClient := network.NewPrivateDNSZoneGroupsClientWithBaseURI(config.ResourceManagerEndpoint, config.SubscriptionID)
|
||||
privateDNSZoneGroupClient.Authorizer = config.Authorizer
|
||||
client := &Client{
|
||||
privateDNSZoneGroupClient: privateDNSZoneGroupClient,
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// CreateOrUpdate creates or updates a private dns zone group
|
||||
func (c *Client) CreateOrUpdate(ctx context.Context, resourceGroupName string, privateEndpointName string, privateDNSZoneGroupName string, parameters network.PrivateDNSZoneGroup, waitForCompletion bool) error {
|
||||
createOrUpdateFuture, err := c.privateDNSZoneGroupClient.CreateOrUpdate(ctx, resourceGroupName, privateEndpointName, privateDNSZoneGroupName, parameters)
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error for %s, resourceGroup: %s, privateEndpointName: %s, error: %s", "privatednszonegroup.put.request", resourceGroupName, privateEndpointName, err)
|
||||
return err
|
||||
}
|
||||
if waitForCompletion {
|
||||
err = createOrUpdateFuture.WaitForCompletionRef(ctx, c.privateDNSZoneGroupClient.Client)
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error while waiting for completion for %s, resourceGroup: %s, privateEndpointName: %s, error: %s", "privatednszonegroup.put.request", resourceGroupName, privateEndpointName, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get gets the private dns zone group
|
||||
func (c *Client) Get(ctx context.Context, resourceGroupName string, privateEndpointName string, privateDNSZoneGroupName string) (result network.PrivateDNSZoneGroup, err error) {
|
||||
return c.privateDNSZoneGroupClient.Get(ctx, resourceGroupName, privateEndpointName, privateDNSZoneGroupName)
|
||||
}
|
||||
34
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/privatednszonegroupclient/interface.go
generated
vendored
Normal file
34
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/privatednszonegroupclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package privatednszonegroupclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
)
|
||||
|
||||
// Interface is the client interface for Private DNS Zone Group.
|
||||
// Don't forget to run "hack/update-mock-clients.sh" command to generate the mock client.
|
||||
type Interface interface {
|
||||
|
||||
// Get gets the private dns zone group
|
||||
Get(ctx context.Context, resourceGroupName string, privateEndpointName string, privateDNSZoneGroupName string) (result network.PrivateDNSZoneGroup, err error)
|
||||
|
||||
// CreateOrUpdate creates or updates a private dns zone group endpoint.
|
||||
CreateOrUpdate(ctx context.Context, resourceGroupName string, privateEndpointName string, privateDNSZoneGroupName string, parameters network.PrivateDNSZoneGroup, waitForCompletion bool) error
|
||||
}
|
||||
66
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/privateendpointclient/azure_privateendpointclient.go
generated
vendored
Normal file
66
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/privateendpointclient/azure_privateendpointclient.go
generated
vendored
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package privateendpointclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
"k8s.io/klog/v2"
|
||||
azclients "sigs.k8s.io/cloud-provider-azure/pkg/azureclients"
|
||||
)
|
||||
|
||||
var _ Interface = &Client{}
|
||||
|
||||
// Client implements privateendpointclient Interface.
|
||||
type Client struct {
|
||||
privateEndpointClient network.PrivateEndpointsClient
|
||||
}
|
||||
|
||||
// New creates a new private endpoint client.
|
||||
func New(config *azclients.ClientConfig) *Client {
|
||||
privateEndpointClient := network.NewPrivateEndpointsClientWithBaseURI(config.ResourceManagerEndpoint, config.SubscriptionID)
|
||||
privateEndpointClient.Authorizer = config.Authorizer
|
||||
|
||||
client := &Client{
|
||||
privateEndpointClient: privateEndpointClient,
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// CreateOrUpdate creates or updates a private endpoint.
|
||||
func (c *Client) CreateOrUpdate(ctx context.Context, resourceGroupName string, endpointName string, privateEndpoint network.PrivateEndpoint, waitForCompletion bool) error {
|
||||
createOrUpdateFuture, err := c.privateEndpointClient.CreateOrUpdate(ctx, resourceGroupName, endpointName, privateEndpoint)
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error for %s, resourceGroup: %s, error: %s", "privateendpoint.put.request", resourceGroupName, err)
|
||||
return err
|
||||
}
|
||||
if waitForCompletion {
|
||||
err = createOrUpdateFuture.WaitForCompletionRef(ctx, c.privateEndpointClient.Client)
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error while waiting for completion for %s, resourceGroup: %s, error: %s", "privateendpoint.put.request", resourceGroupName, err)
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get gets the private endpoint
|
||||
func (c *Client) Get(ctx context.Context, resourceGroupName string, privateEndpointName string, expand string) (result network.PrivateEndpoint, err error) {
|
||||
return c.privateEndpointClient.Get(ctx, resourceGroupName, privateEndpointName, expand)
|
||||
}
|
||||
34
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/privateendpointclient/interface.go
generated
vendored
Normal file
34
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/privateendpointclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package privateendpointclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
)
|
||||
|
||||
// Interface is the client interface for Private Endpoints.
|
||||
// Don't forget to run "hack/update-mock-clients.sh" command to generate the mock client.
|
||||
type Interface interface {
|
||||
|
||||
// Get gets the private endpoint
|
||||
Get(ctx context.Context, resourceGroupName string, privateEndpointName string, expand string) (result network.PrivateEndpoint, err error)
|
||||
|
||||
// CreateOrUpdate creates or updates a private endpoint.
|
||||
CreateOrUpdate(ctx context.Context, resourceGroupName string, endpointName string, privateEndpoint network.PrivateEndpoint, waitForCompletion bool) error
|
||||
}
|
||||
563
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/publicipclient/azure_publicipclient.go
generated
vendored
Normal file
563
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/publicipclient/azure_publicipclient.go
generated
vendored
Normal file
|
|
@ -0,0 +1,563 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package publicipclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
azclients "sigs.k8s.io/cloud-provider-azure/pkg/azureclients"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/armclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/metrics"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
var _ Interface = &Client{}
|
||||
|
||||
// Client implements PublicIPAddress client Interface.
|
||||
type Client struct {
|
||||
armClient armclient.Interface
|
||||
subscriptionID string
|
||||
cloudName string
|
||||
disableAzureStackCloud bool
|
||||
|
||||
// Rate limiting configures.
|
||||
rateLimiterReader flowcontrol.RateLimiter
|
||||
rateLimiterWriter flowcontrol.RateLimiter
|
||||
|
||||
// ARM throttling configures.
|
||||
RetryAfterReader time.Time
|
||||
RetryAfterWriter time.Time
|
||||
}
|
||||
|
||||
// New creates a new PublicIPAddress client with ratelimiting.
|
||||
func New(config *azclients.ClientConfig) *Client {
|
||||
baseURI := config.ResourceManagerEndpoint
|
||||
authorizer := config.Authorizer
|
||||
apiVersion := APIVersion
|
||||
if strings.EqualFold(config.CloudName, AzureStackCloudName) && !config.DisableAzureStackCloud {
|
||||
apiVersion = AzureStackCloudAPIVersion
|
||||
}
|
||||
armClient := armclient.New(authorizer, *config, baseURI, apiVersion)
|
||||
rateLimiterReader, rateLimiterWriter := azclients.NewRateLimiter(config.RateLimitConfig)
|
||||
|
||||
if azclients.RateLimitEnabled(config.RateLimitConfig) {
|
||||
klog.V(2).Infof("Azure PublicIPAddressesClient (read ops) using rate limit config: QPS=%g, bucket=%d",
|
||||
config.RateLimitConfig.CloudProviderRateLimitQPS,
|
||||
config.RateLimitConfig.CloudProviderRateLimitBucket)
|
||||
klog.V(2).Infof("Azure PublicIPAddressesClient (write ops) using rate limit config: QPS=%g, bucket=%d",
|
||||
config.RateLimitConfig.CloudProviderRateLimitQPSWrite,
|
||||
config.RateLimitConfig.CloudProviderRateLimitBucketWrite)
|
||||
}
|
||||
|
||||
client := &Client{
|
||||
armClient: armClient,
|
||||
rateLimiterReader: rateLimiterReader,
|
||||
rateLimiterWriter: rateLimiterWriter,
|
||||
subscriptionID: config.SubscriptionID,
|
||||
cloudName: config.CloudName,
|
||||
disableAzureStackCloud: config.DisableAzureStackCloud,
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
// Get gets a PublicIPAddress.
|
||||
func (c *Client) Get(ctx context.Context, resourceGroupName string, publicIPAddressName string, expand string) (network.PublicIPAddress, *retry.Error) {
|
||||
mc := metrics.NewMetricContext("public_ip_addresses", "get", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterReader.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return network.PublicIPAddress{}, retry.GetRateLimitError(false, "PublicIPGet")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterReader.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("PublicIPGet", "client throttled", c.RetryAfterReader)
|
||||
return network.PublicIPAddress{}, rerr
|
||||
}
|
||||
|
||||
result, rerr := c.getPublicIPAddress(ctx, resourceGroupName, publicIPAddressName, expand)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterReader = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// getPublicIPAddress gets a PublicIPAddress.
|
||||
func (c *Client) getPublicIPAddress(ctx context.Context, resourceGroupName string, publicIPAddressName string, expand string) (network.PublicIPAddress, *retry.Error) {
|
||||
resourceID := armclient.GetResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Network/publicIPAddresses",
|
||||
publicIPAddressName,
|
||||
)
|
||||
result := network.PublicIPAddress{}
|
||||
|
||||
response, rerr := c.armClient.GetResource(ctx, resourceID, expand)
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "publicip.get.request", resourceID, rerr.Error())
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
err := autorest.Respond(
|
||||
response,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "publicip.get.respond", resourceID, err)
|
||||
return result, retry.GetError(response, err)
|
||||
}
|
||||
|
||||
result.Response = autorest.Response{Response: response}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetVirtualMachineScaleSetPublicIPAddress gets a PublicIPAddress for VMSS VM.
|
||||
func (c *Client) GetVirtualMachineScaleSetPublicIPAddress(ctx context.Context, resourceGroupName string, virtualMachineScaleSetName string, virtualmachineIndex string, networkInterfaceName string, IPConfigurationName string, publicIPAddressName string, expand string) (network.PublicIPAddress, *retry.Error) {
|
||||
mc := metrics.NewMetricContext("vmss_public_ip_addresses", "get", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterReader.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return network.PublicIPAddress{}, retry.GetRateLimitError(false, "VMSSPublicIPGet")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterReader.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("VMSSPublicIPGet", "client throttled", c.RetryAfterReader)
|
||||
return network.PublicIPAddress{}, rerr
|
||||
}
|
||||
|
||||
result, rerr := c.getVMSSPublicIPAddress(ctx, resourceGroupName, virtualMachineScaleSetName, virtualmachineIndex, networkInterfaceName, IPConfigurationName, publicIPAddressName, expand)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterReader = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// getVMSSPublicIPAddress gets a PublicIPAddress for VMSS VM.
|
||||
func (c *Client) getVMSSPublicIPAddress(ctx context.Context, resourceGroupName string, virtualMachineScaleSetName string, virtualmachineIndex string, networkInterfaceName string, IPConfigurationName string, publicIPAddressName string, expand string) (network.PublicIPAddress, *retry.Error) {
|
||||
resourceID := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/virtualMachineScaleSets/%s/virtualMachines/%s/networkInterfaces/%s/ipconfigurations/%s/publicipaddresses/%s",
|
||||
autorest.Encode("path", c.subscriptionID),
|
||||
autorest.Encode("path", resourceGroupName),
|
||||
autorest.Encode("path", virtualMachineScaleSetName),
|
||||
autorest.Encode("path", virtualmachineIndex),
|
||||
autorest.Encode("path", networkInterfaceName),
|
||||
autorest.Encode("path", IPConfigurationName),
|
||||
autorest.Encode("path", publicIPAddressName),
|
||||
)
|
||||
|
||||
result := network.PublicIPAddress{}
|
||||
computeAPIVersion := ComputeAPIVersion
|
||||
if strings.EqualFold(c.cloudName, AzureStackCloudName) && !c.disableAzureStackCloud {
|
||||
computeAPIVersion = AzureStackComputeAPIVersion
|
||||
}
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": computeAPIVersion,
|
||||
}
|
||||
if len(expand) > 0 {
|
||||
queryParameters["$expand"] = autorest.Encode("query", expand)
|
||||
}
|
||||
decorators := []autorest.PrepareDecorator{
|
||||
autorest.WithQueryParameters(queryParameters),
|
||||
}
|
||||
response, rerr := c.armClient.GetResourceWithDecorators(ctx, resourceID, decorators)
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmsspublicip.get.request", resourceID, rerr.Error())
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
err := autorest.Respond(
|
||||
response,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmsspublicip.get.respond", resourceID, err)
|
||||
return result, retry.GetError(response, err)
|
||||
}
|
||||
|
||||
result.Response = autorest.Response{Response: response}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// List gets a list of PublicIPAddress in the resource group.
|
||||
func (c *Client) List(ctx context.Context, resourceGroupName string) ([]network.PublicIPAddress, *retry.Error) {
|
||||
mc := metrics.NewMetricContext("public_ip_addresses", "list", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterReader.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return nil, retry.GetRateLimitError(false, "PublicIPList")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterReader.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("PublicIPList", "client throttled", c.RetryAfterReader)
|
||||
return nil, rerr
|
||||
}
|
||||
|
||||
result, rerr := c.listPublicIPAddress(ctx, resourceGroupName)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterReader = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// listPublicIPAddress gets a list of PublicIPAddress in the resource group.
|
||||
func (c *Client) listPublicIPAddress(ctx context.Context, resourceGroupName string) ([]network.PublicIPAddress, *retry.Error) {
|
||||
resourceID := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/publicIPAddresses",
|
||||
autorest.Encode("path", c.subscriptionID),
|
||||
autorest.Encode("path", resourceGroupName))
|
||||
result := make([]network.PublicIPAddress, 0)
|
||||
page := &PublicIPAddressListResultPage{}
|
||||
page.fn = c.listNextResults
|
||||
|
||||
resp, rerr := c.armClient.GetResource(ctx, resourceID, "")
|
||||
defer c.armClient.CloseResponse(ctx, resp)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "publicip.list.request", resourceID, rerr.Error())
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
var err error
|
||||
page.pialr, err = c.listResponder(resp)
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "publicip.list.respond", resourceID, err)
|
||||
return result, retry.GetError(resp, err)
|
||||
}
|
||||
|
||||
for {
|
||||
result = append(result, page.Values()...)
|
||||
|
||||
// Abort the loop when there's no nextLink in the response.
|
||||
if to.String(page.Response().NextLink) == "" {
|
||||
break
|
||||
}
|
||||
|
||||
if err = page.NextWithContext(ctx); err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "publicip.list.next", resourceID, err)
|
||||
return result, retry.GetError(page.Response().Response.Response, err)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// CreateOrUpdate creates or updates a PublicIPAddress.
|
||||
func (c *Client) CreateOrUpdate(ctx context.Context, resourceGroupName string, publicIPAddressName string, parameters network.PublicIPAddress) *retry.Error {
|
||||
mc := metrics.NewMetricContext("public_ip_addresses", "create_or_update", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterWriter.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return retry.GetRateLimitError(true, "PublicIPCreateOrUpdate")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterWriter.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("PublicIPCreateOrUpdate", "client throttled", c.RetryAfterWriter)
|
||||
return rerr
|
||||
}
|
||||
|
||||
rerr := c.createOrUpdatePublicIP(ctx, resourceGroupName, publicIPAddressName, parameters)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterWriter = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return rerr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// createOrUpdatePublicIP creates or updates a PublicIPAddress.
|
||||
func (c *Client) createOrUpdatePublicIP(ctx context.Context, resourceGroupName string, publicIPAddressName string, parameters network.PublicIPAddress) *retry.Error {
|
||||
resourceID := armclient.GetResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Network/publicIPAddresses",
|
||||
publicIPAddressName,
|
||||
)
|
||||
|
||||
response, rerr := c.armClient.PutResource(ctx, resourceID, parameters)
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "publicip.put.request", resourceID, rerr.Error())
|
||||
return rerr
|
||||
}
|
||||
|
||||
if response != nil && response.StatusCode != http.StatusNoContent {
|
||||
_, rerr = c.createOrUpdateResponder(response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "publicip.put.respond", resourceID, rerr.Error())
|
||||
return rerr
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) createOrUpdateResponder(resp *http.Response) (*network.PublicIPAddress, *retry.Error) {
|
||||
result := &network.PublicIPAddress{}
|
||||
err := autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, retry.GetError(resp, err)
|
||||
}
|
||||
|
||||
// Delete deletes a PublicIPAddress by name.
|
||||
func (c *Client) Delete(ctx context.Context, resourceGroupName string, publicIPAddressName string) *retry.Error {
|
||||
mc := metrics.NewMetricContext("public_ip_addresses", "delete", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterWriter.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return retry.GetRateLimitError(true, "PublicIPDelete")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterWriter.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("PublicIPDelete", "client throttled", c.RetryAfterWriter)
|
||||
return rerr
|
||||
}
|
||||
|
||||
rerr := c.deletePublicIP(ctx, resourceGroupName, publicIPAddressName)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterWriter = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return rerr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// deletePublicIP deletes a PublicIPAddress by name.
|
||||
func (c *Client) deletePublicIP(ctx context.Context, resourceGroupName string, publicIPAddressName string) *retry.Error {
|
||||
resourceID := armclient.GetResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Network/publicIPAddresses",
|
||||
publicIPAddressName,
|
||||
)
|
||||
|
||||
return c.armClient.DeleteResource(ctx, resourceID, "")
|
||||
}
|
||||
|
||||
func (c *Client) listResponder(resp *http.Response) (result network.PublicIPAddressListResult, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
autorest.ByIgnoring(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// publicIPAddressListResultPreparer prepares a request to retrieve the next set of results.
|
||||
// It returns nil if no more results exist.
|
||||
func (c *Client) publicIPAddressListResultPreparer(ctx context.Context, lr network.PublicIPAddressListResult) (*http.Request, error) {
|
||||
if lr.NextLink == nil || len(to.String(lr.NextLink)) < 1 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
decorators := []autorest.PrepareDecorator{
|
||||
autorest.WithBaseURL(to.String(lr.NextLink)),
|
||||
}
|
||||
return c.armClient.PrepareGetRequest(ctx, decorators...)
|
||||
}
|
||||
|
||||
// listNextResults retrieves the next set of results, if any.
|
||||
func (c *Client) listNextResults(ctx context.Context, lastResults network.PublicIPAddressListResult) (result network.PublicIPAddressListResult, err error) {
|
||||
req, err := c.publicIPAddressListResultPreparer(ctx, lastResults)
|
||||
if err != nil {
|
||||
return result, autorest.NewErrorWithError(err, "publicipclient", "listNextResults", nil, "Failure preparing next results request")
|
||||
}
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
|
||||
resp, rerr := c.armClient.Send(ctx, req)
|
||||
defer c.armClient.CloseResponse(ctx, resp)
|
||||
if rerr != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, autorest.NewErrorWithError(rerr.Error(), "publicipclient", "listNextResults", resp, "Failure sending next results request")
|
||||
}
|
||||
|
||||
result, err = c.listResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "publicipclient", "listNextResults", resp, "Failure responding to next results request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// PublicIPAddressListResultPage contains a page of PublicIPAddress values.
|
||||
type PublicIPAddressListResultPage struct {
|
||||
fn func(context.Context, network.PublicIPAddressListResult) (network.PublicIPAddressListResult, error)
|
||||
pialr network.PublicIPAddressListResult
|
||||
}
|
||||
|
||||
// NextWithContext advances to the next page of values. If there was an error making
|
||||
// the request the page does not advance and the error is returned.
|
||||
func (page *PublicIPAddressListResultPage) NextWithContext(ctx context.Context) (err error) {
|
||||
next, err := page.fn(ctx, page.pialr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
page.pialr = next
|
||||
return nil
|
||||
}
|
||||
|
||||
// Next advances to the next page of values. If there was an error making
|
||||
// the request the page does not advance and the error is returned.
|
||||
// Deprecated: Use NextWithContext() instead.
|
||||
func (page *PublicIPAddressListResultPage) Next() error {
|
||||
return page.NextWithContext(context.Background())
|
||||
}
|
||||
|
||||
// NotDone returns true if the page enumeration should be started or is not yet complete.
|
||||
func (page PublicIPAddressListResultPage) NotDone() bool {
|
||||
return !page.pialr.IsEmpty()
|
||||
}
|
||||
|
||||
// Response returns the raw server response from the last page request.
|
||||
func (page PublicIPAddressListResultPage) Response() network.PublicIPAddressListResult {
|
||||
return page.pialr
|
||||
}
|
||||
|
||||
// Values returns the slice of values for the current page or nil if there are no values.
|
||||
func (page PublicIPAddressListResultPage) Values() []network.PublicIPAddress {
|
||||
if page.pialr.IsEmpty() {
|
||||
return nil
|
||||
}
|
||||
return *page.pialr.Value
|
||||
}
|
||||
|
||||
// ListAll gets all of PublicIPAddress in the subscription.
|
||||
func (c *Client) ListAll(ctx context.Context) ([]network.PublicIPAddress, *retry.Error) {
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterReader.TryAccept() {
|
||||
return nil, retry.GetRateLimitError(false, "PublicIPListAll")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterReader.After(time.Now()) {
|
||||
rerr := retry.GetThrottlingError("PublicIPListAll", "client throttled", c.RetryAfterReader)
|
||||
return nil, rerr
|
||||
}
|
||||
|
||||
result, rerr := c.listAllPublicIPAddress(ctx)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterReader = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// listAllPublicIPAddress gets all of PublicIPAddress in the subscription.
|
||||
func (c *Client) listAllPublicIPAddress(ctx context.Context) ([]network.PublicIPAddress, *retry.Error) {
|
||||
resourceID := fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Network/publicIPAddresses",
|
||||
autorest.Encode("path", c.subscriptionID))
|
||||
result := make([]network.PublicIPAddress, 0)
|
||||
page := &PublicIPAddressListResultPage{}
|
||||
page.fn = c.listNextResults
|
||||
|
||||
resp, rerr := c.armClient.GetResource(ctx, resourceID, "")
|
||||
defer c.armClient.CloseResponse(ctx, resp)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "publicip.listall.request", resourceID, rerr.Error())
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
var err error
|
||||
page.pialr, err = c.listResponder(resp)
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "publicip.listall.respond", resourceID, err)
|
||||
return result, retry.GetError(resp, err)
|
||||
}
|
||||
|
||||
for {
|
||||
result = append(result, page.Values()...)
|
||||
|
||||
// Abort the loop when there's no nextLink in the response.
|
||||
if to.String(page.Response().NextLink) == "" {
|
||||
break
|
||||
}
|
||||
|
||||
if err = page.NextWithContext(ctx); err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "publicip.listall.next", resourceID, err)
|
||||
return result, retry.GetError(page.Response().Response.Response, err)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/publicipclient/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/publicipclient/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package publicipclient implements the client for PublicIPAddress.
|
||||
package publicipclient // import "sigs.k8s.io/cloud-provider-azure/pkg/azureclients/publicipclient"
|
||||
62
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/publicipclient/interface.go
generated
vendored
Normal file
62
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/publicipclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package publicipclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
const (
|
||||
// APIVersion is the API version for network.
|
||||
APIVersion = "2020-08-01"
|
||||
// AzureStackCloudAPIVersion is the API version for Azure Stack
|
||||
AzureStackCloudAPIVersion = "2018-11-01"
|
||||
|
||||
// ComputeAPIVersion is the API version for compute. It is required to get VMSS public IP.
|
||||
ComputeAPIVersion = "2017-03-30"
|
||||
// AzureStackComputeAPIVersion is the API version for compute for Azure Stack. It is required to get VMSS network interface.
|
||||
AzureStackComputeAPIVersion = "2018-11-01"
|
||||
|
||||
// AzureStackCloudName is the cloud name of Azure Stack
|
||||
AzureStackCloudName = "AZURESTACKCLOUD"
|
||||
)
|
||||
|
||||
// Interface is the client interface for PublicIPAddress.
|
||||
// Don't forget to run "hack/update-mock-clients.sh" command to generate the mock client.
|
||||
type Interface interface {
|
||||
// Get gets a PublicIPAddress.
|
||||
Get(ctx context.Context, resourceGroupName string, publicIPAddressName string, expand string) (result network.PublicIPAddress, rerr *retry.Error)
|
||||
|
||||
// GetVirtualMachineScaleSetPublicIPAddress gets a PublicIPAddress for VMSS VM.
|
||||
GetVirtualMachineScaleSetPublicIPAddress(ctx context.Context, resourceGroupName string, virtualMachineScaleSetName string, virtualmachineIndex string, networkInterfaceName string, IPConfigurationName string, publicIPAddressName string, expand string) (result network.PublicIPAddress, rerr *retry.Error)
|
||||
|
||||
// List gets a list of PublicIPAddress in the resource group.
|
||||
List(ctx context.Context, resourceGroupName string) (result []network.PublicIPAddress, rerr *retry.Error)
|
||||
|
||||
// ListAll gets all of PublicIPAddress in the subscription.
|
||||
ListAll(ctx context.Context) (result []network.PublicIPAddress, rerr *retry.Error)
|
||||
|
||||
// CreateOrUpdate creates or updates a PublicIPAddress.
|
||||
CreateOrUpdate(ctx context.Context, resourceGroupName string, publicIPAddressName string, parameters network.PublicIPAddress) *retry.Error
|
||||
|
||||
// Delete deletes a PublicIPAddress by name.
|
||||
Delete(ctx context.Context, resourceGroupName string, publicIPAddressName string) *retry.Error
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/publicipclient/mockpublicipclient/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/publicipclient/mockpublicipclient/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package mockpublicipclient implements the mock client for PublicIPAddress.
|
||||
package mockpublicipclient // import "sigs.k8s.io/cloud-provider-azure/pkg/azureclients/publicipclient/mockpublicipclient"
|
||||
142
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/publicipclient/mockpublicipclient/interface.go
generated
vendored
Normal file
142
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/publicipclient/mockpublicipclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
// /*
|
||||
// Copyright The Kubernetes Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// */
|
||||
//
|
||||
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: /go/src/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/publicipclient/interface.go
|
||||
|
||||
// Package mockpublicipclient is a generated GoMock package.
|
||||
package mockpublicipclient
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
network "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
retry "sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
// MockInterface is a mock of Interface interface.
|
||||
type MockInterface struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockInterfaceMockRecorder
|
||||
}
|
||||
|
||||
// MockInterfaceMockRecorder is the mock recorder for MockInterface.
|
||||
type MockInterfaceMockRecorder struct {
|
||||
mock *MockInterface
|
||||
}
|
||||
|
||||
// NewMockInterface creates a new mock instance.
|
||||
func NewMockInterface(ctrl *gomock.Controller) *MockInterface {
|
||||
mock := &MockInterface{ctrl: ctrl}
|
||||
mock.recorder = &MockInterfaceMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Get mocks base method.
|
||||
func (m *MockInterface) Get(ctx context.Context, resourceGroupName, publicIPAddressName, expand string) (network.PublicIPAddress, *retry.Error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Get", ctx, resourceGroupName, publicIPAddressName, expand)
|
||||
ret0, _ := ret[0].(network.PublicIPAddress)
|
||||
ret1, _ := ret[1].(*retry.Error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Get indicates an expected call of Get.
|
||||
func (mr *MockInterfaceMockRecorder) Get(ctx, resourceGroupName, publicIPAddressName, expand interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockInterface)(nil).Get), ctx, resourceGroupName, publicIPAddressName, expand)
|
||||
}
|
||||
|
||||
// GetVirtualMachineScaleSetPublicIPAddress mocks base method.
|
||||
func (m *MockInterface) GetVirtualMachineScaleSetPublicIPAddress(ctx context.Context, resourceGroupName, virtualMachineScaleSetName, virtualmachineIndex, networkInterfaceName, IPConfigurationName, publicIPAddressName, expand string) (network.PublicIPAddress, *retry.Error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetVirtualMachineScaleSetPublicIPAddress", ctx, resourceGroupName, virtualMachineScaleSetName, virtualmachineIndex, networkInterfaceName, IPConfigurationName, publicIPAddressName, expand)
|
||||
ret0, _ := ret[0].(network.PublicIPAddress)
|
||||
ret1, _ := ret[1].(*retry.Error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetVirtualMachineScaleSetPublicIPAddress indicates an expected call of GetVirtualMachineScaleSetPublicIPAddress.
|
||||
func (mr *MockInterfaceMockRecorder) GetVirtualMachineScaleSetPublicIPAddress(ctx, resourceGroupName, virtualMachineScaleSetName, virtualmachineIndex, networkInterfaceName, IPConfigurationName, publicIPAddressName, expand interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVirtualMachineScaleSetPublicIPAddress", reflect.TypeOf((*MockInterface)(nil).GetVirtualMachineScaleSetPublicIPAddress), ctx, resourceGroupName, virtualMachineScaleSetName, virtualmachineIndex, networkInterfaceName, IPConfigurationName, publicIPAddressName, expand)
|
||||
}
|
||||
|
||||
// List mocks base method.
|
||||
func (m *MockInterface) List(ctx context.Context, resourceGroupName string) ([]network.PublicIPAddress, *retry.Error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "List", ctx, resourceGroupName)
|
||||
ret0, _ := ret[0].([]network.PublicIPAddress)
|
||||
ret1, _ := ret[1].(*retry.Error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// List indicates an expected call of List.
|
||||
func (mr *MockInterfaceMockRecorder) List(ctx, resourceGroupName interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockInterface)(nil).List), ctx, resourceGroupName)
|
||||
}
|
||||
|
||||
// ListAll mocks base method.
|
||||
func (m *MockInterface) ListAll(ctx context.Context) ([]network.PublicIPAddress, *retry.Error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ListAll", ctx)
|
||||
ret0, _ := ret[0].([]network.PublicIPAddress)
|
||||
ret1, _ := ret[1].(*retry.Error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ListAll indicates an expected call of ListAll.
|
||||
func (mr *MockInterfaceMockRecorder) ListAll(ctx interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAll", reflect.TypeOf((*MockInterface)(nil).ListAll), ctx)
|
||||
}
|
||||
|
||||
// CreateOrUpdate mocks base method.
|
||||
func (m *MockInterface) CreateOrUpdate(ctx context.Context, resourceGroupName, publicIPAddressName string, parameters network.PublicIPAddress) *retry.Error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CreateOrUpdate", ctx, resourceGroupName, publicIPAddressName, parameters)
|
||||
ret0, _ := ret[0].(*retry.Error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// CreateOrUpdate indicates an expected call of CreateOrUpdate.
|
||||
func (mr *MockInterfaceMockRecorder) CreateOrUpdate(ctx, resourceGroupName, publicIPAddressName, parameters interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateOrUpdate", reflect.TypeOf((*MockInterface)(nil).CreateOrUpdate), ctx, resourceGroupName, publicIPAddressName, parameters)
|
||||
}
|
||||
|
||||
// Delete mocks base method.
|
||||
func (m *MockInterface) Delete(ctx context.Context, resourceGroupName, publicIPAddressName string) *retry.Error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Delete", ctx, resourceGroupName, publicIPAddressName)
|
||||
ret0, _ := ret[0].(*retry.Error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Delete indicates an expected call of Delete.
|
||||
func (mr *MockInterfaceMockRecorder) Delete(ctx, resourceGroupName, publicIPAddressName interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockInterface)(nil).Delete), ctx, resourceGroupName, publicIPAddressName)
|
||||
}
|
||||
206
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routeclient/azure_routeclient.go
generated
vendored
Normal file
206
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routeclient/azure_routeclient.go
generated
vendored
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package routeclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
azclients "sigs.k8s.io/cloud-provider-azure/pkg/azureclients"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/armclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/metrics"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
var _ Interface = &Client{}
|
||||
|
||||
// Client implements Route client Interface.
|
||||
type Client struct {
|
||||
armClient armclient.Interface
|
||||
subscriptionID string
|
||||
cloudName string
|
||||
|
||||
// Rate limiting configures.
|
||||
rateLimiterReader flowcontrol.RateLimiter
|
||||
rateLimiterWriter flowcontrol.RateLimiter
|
||||
|
||||
// ARM throttling configures.
|
||||
RetryAfterReader time.Time
|
||||
RetryAfterWriter time.Time
|
||||
}
|
||||
|
||||
// New creates a new Route client with ratelimiting.
|
||||
func New(config *azclients.ClientConfig) *Client {
|
||||
baseURI := config.ResourceManagerEndpoint
|
||||
authorizer := config.Authorizer
|
||||
apiVersion := APIVersion
|
||||
if strings.EqualFold(config.CloudName, AzureStackCloudName) && !config.DisableAzureStackCloud {
|
||||
apiVersion = AzureStackCloudAPIVersion
|
||||
}
|
||||
armClient := armclient.New(authorizer, *config, baseURI, apiVersion)
|
||||
rateLimiterReader, rateLimiterWriter := azclients.NewRateLimiter(config.RateLimitConfig)
|
||||
|
||||
if azclients.RateLimitEnabled(config.RateLimitConfig) {
|
||||
klog.V(2).Infof("Azure RoutesClient (read ops) using rate limit config: QPS=%g, bucket=%d",
|
||||
config.RateLimitConfig.CloudProviderRateLimitQPS,
|
||||
config.RateLimitConfig.CloudProviderRateLimitBucket)
|
||||
klog.V(2).Infof("Azure RoutesClient (write ops) using rate limit config: QPS=%g, bucket=%d",
|
||||
config.RateLimitConfig.CloudProviderRateLimitQPSWrite,
|
||||
config.RateLimitConfig.CloudProviderRateLimitBucketWrite)
|
||||
}
|
||||
|
||||
client := &Client{
|
||||
armClient: armClient,
|
||||
rateLimiterReader: rateLimiterReader,
|
||||
rateLimiterWriter: rateLimiterWriter,
|
||||
subscriptionID: config.SubscriptionID,
|
||||
cloudName: config.CloudName,
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
// CreateOrUpdate creates or updates a Route.
|
||||
func (c *Client) CreateOrUpdate(ctx context.Context, resourceGroupName string, routeTableName string, routeName string, routeParameters network.Route, etag string) *retry.Error {
|
||||
mc := metrics.NewMetricContext("routes", "create_or_update", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterWriter.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return retry.GetRateLimitError(true, "RouteCreateOrUpdate")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterWriter.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("RouteCreateOrUpdate", "client throttled", c.RetryAfterWriter)
|
||||
return rerr
|
||||
}
|
||||
|
||||
rerr := c.createOrUpdateRoute(ctx, resourceGroupName, routeTableName, routeName, routeParameters, etag)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterWriter = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return rerr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// createOrUpdateRoute creates or updates a Route.
|
||||
func (c *Client) createOrUpdateRoute(ctx context.Context, resourceGroupName string, routeTableName string, routeName string, routeParameters network.Route, etag string) *retry.Error {
|
||||
resourceID := armclient.GetChildResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Network/routeTables",
|
||||
routeTableName,
|
||||
"routes",
|
||||
routeName,
|
||||
)
|
||||
decorators := []autorest.PrepareDecorator{
|
||||
autorest.WithPathParameters("{resourceID}", map[string]interface{}{"resourceID": resourceID}),
|
||||
autorest.WithJSON(routeParameters),
|
||||
}
|
||||
if etag != "" {
|
||||
decorators = append(decorators, autorest.WithHeader("If-Match", autorest.String(etag)))
|
||||
}
|
||||
|
||||
response, rerr := c.armClient.PutResourceWithDecorators(ctx, resourceID, routeParameters, decorators)
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "route.put.request", resourceID, rerr.Error())
|
||||
return rerr
|
||||
}
|
||||
|
||||
if response != nil && response.StatusCode != http.StatusNoContent {
|
||||
_, rerr = c.createOrUpdateResponder(response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "route.put.respond", resourceID, rerr.Error())
|
||||
return rerr
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) createOrUpdateResponder(resp *http.Response) (*network.Route, *retry.Error) {
|
||||
result := &network.Route{}
|
||||
err := autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, retry.GetError(resp, err)
|
||||
}
|
||||
|
||||
// Delete deletes a Route by name.
|
||||
func (c *Client) Delete(ctx context.Context, resourceGroupName string, routeTableName string, routeName string) *retry.Error {
|
||||
mc := metrics.NewMetricContext("routes", "delete", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterWriter.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return retry.GetRateLimitError(true, "RouteDelete")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterWriter.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("RouteDelete", "client throttled", c.RetryAfterWriter)
|
||||
return rerr
|
||||
}
|
||||
|
||||
rerr := c.deleteRoute(ctx, resourceGroupName, routeTableName, routeName)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterWriter = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return rerr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteRoute deletes a Route by name.
|
||||
func (c *Client) deleteRoute(ctx context.Context, resourceGroupName string, routeTableName string, routeName string) *retry.Error {
|
||||
resourceID := armclient.GetChildResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Network/routeTables",
|
||||
routeTableName,
|
||||
"routes",
|
||||
routeName,
|
||||
)
|
||||
|
||||
return c.armClient.DeleteResource(ctx, resourceID, "")
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routeclient/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routeclient/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package routeclient implements the client for Route.
|
||||
package routeclient // import "sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routeclient"
|
||||
45
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routeclient/interface.go
generated
vendored
Normal file
45
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routeclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package routeclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
const (
|
||||
// APIVersion is the API version for network.
|
||||
APIVersion = "2020-08-01"
|
||||
// AzureStackCloudAPIVersion is the API version for Azure Stack
|
||||
AzureStackCloudAPIVersion = "2018-11-01"
|
||||
// AzureStackCloudName is the cloud name of Azure Stack
|
||||
AzureStackCloudName = "AZURESTACKCLOUD"
|
||||
)
|
||||
|
||||
// Interface is the client interface for Route.
|
||||
// Don't forget to run the following command to generate the mock client:
|
||||
// Don't forget to run "hack/update-mock-clients.sh" command to generate the mock client.
|
||||
type Interface interface {
|
||||
// CreateOrUpdate creates or updates a Route.
|
||||
CreateOrUpdate(ctx context.Context, resourceGroupName string, routeTableName string, routeName string, routeParameters network.Route, etag string) *retry.Error
|
||||
|
||||
// Delete deletes a Route by name.
|
||||
Delete(ctx context.Context, resourceGroupName string, routeTableName string, routeName string) *retry.Error
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routeclient/mockrouteclient/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routeclient/mockrouteclient/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package mockrouteclient implements the mock client for Route.
|
||||
package mockrouteclient // import "sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routeclient/mockrouteclient"
|
||||
82
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routeclient/mockrouteclient/interface.go
generated
vendored
Normal file
82
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routeclient/mockrouteclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
// /*
|
||||
// Copyright The Kubernetes Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// */
|
||||
//
|
||||
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: /go/src/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routeclient/interface.go
|
||||
|
||||
// Package mockrouteclient is a generated GoMock package.
|
||||
package mockrouteclient
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
network "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
retry "sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
// MockInterface is a mock of Interface interface.
|
||||
type MockInterface struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockInterfaceMockRecorder
|
||||
}
|
||||
|
||||
// MockInterfaceMockRecorder is the mock recorder for MockInterface.
|
||||
type MockInterfaceMockRecorder struct {
|
||||
mock *MockInterface
|
||||
}
|
||||
|
||||
// NewMockInterface creates a new mock instance.
|
||||
func NewMockInterface(ctrl *gomock.Controller) *MockInterface {
|
||||
mock := &MockInterface{ctrl: ctrl}
|
||||
mock.recorder = &MockInterfaceMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// CreateOrUpdate mocks base method.
|
||||
func (m *MockInterface) CreateOrUpdate(ctx context.Context, resourceGroupName, routeTableName, routeName string, routeParameters network.Route, etag string) *retry.Error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CreateOrUpdate", ctx, resourceGroupName, routeTableName, routeName, routeParameters, etag)
|
||||
ret0, _ := ret[0].(*retry.Error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// CreateOrUpdate indicates an expected call of CreateOrUpdate.
|
||||
func (mr *MockInterfaceMockRecorder) CreateOrUpdate(ctx, resourceGroupName, routeTableName, routeName, routeParameters, etag interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateOrUpdate", reflect.TypeOf((*MockInterface)(nil).CreateOrUpdate), ctx, resourceGroupName, routeTableName, routeName, routeParameters, etag)
|
||||
}
|
||||
|
||||
// Delete mocks base method.
|
||||
func (m *MockInterface) Delete(ctx context.Context, resourceGroupName, routeTableName, routeName string) *retry.Error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Delete", ctx, resourceGroupName, routeTableName, routeName)
|
||||
ret0, _ := ret[0].(*retry.Error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Delete indicates an expected call of Delete.
|
||||
func (mr *MockInterfaceMockRecorder) Delete(ctx, resourceGroupName, routeTableName, routeName interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockInterface)(nil).Delete), ctx, resourceGroupName, routeTableName, routeName)
|
||||
}
|
||||
220
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routetableclient/azure_routetableclient.go
generated
vendored
Normal file
220
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routetableclient/azure_routetableclient.go
generated
vendored
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package routetableclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
azclients "sigs.k8s.io/cloud-provider-azure/pkg/azureclients"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/armclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/metrics"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
var _ Interface = &Client{}
|
||||
|
||||
// Client implements RouteTable client Interface.
|
||||
type Client struct {
|
||||
armClient armclient.Interface
|
||||
subscriptionID string
|
||||
cloudName string
|
||||
|
||||
// Rate limiting configures.
|
||||
rateLimiterReader flowcontrol.RateLimiter
|
||||
rateLimiterWriter flowcontrol.RateLimiter
|
||||
|
||||
// ARM throttling configures.
|
||||
RetryAfterReader time.Time
|
||||
RetryAfterWriter time.Time
|
||||
}
|
||||
|
||||
// New creates a new RouteTable client with ratelimiting.
|
||||
func New(config *azclients.ClientConfig) *Client {
|
||||
baseURI := config.ResourceManagerEndpoint
|
||||
authorizer := config.Authorizer
|
||||
apiVersion := APIVersion
|
||||
if strings.EqualFold(config.CloudName, AzureStackCloudName) && !config.DisableAzureStackCloud {
|
||||
apiVersion = AzureStackCloudAPIVersion
|
||||
}
|
||||
armClient := armclient.New(authorizer, *config, baseURI, apiVersion)
|
||||
rateLimiterReader, rateLimiterWriter := azclients.NewRateLimiter(config.RateLimitConfig)
|
||||
|
||||
if azclients.RateLimitEnabled(config.RateLimitConfig) {
|
||||
klog.V(2).Infof("Azure RouteTablesClient (read ops) using rate limit config: QPS=%g, bucket=%d",
|
||||
config.RateLimitConfig.CloudProviderRateLimitQPS,
|
||||
config.RateLimitConfig.CloudProviderRateLimitBucket)
|
||||
klog.V(2).Infof("Azure RouteTablesClient (write ops) using rate limit config: QPS=%g, bucket=%d",
|
||||
config.RateLimitConfig.CloudProviderRateLimitQPSWrite,
|
||||
config.RateLimitConfig.CloudProviderRateLimitBucketWrite)
|
||||
}
|
||||
|
||||
client := &Client{
|
||||
armClient: armClient,
|
||||
rateLimiterReader: rateLimiterReader,
|
||||
rateLimiterWriter: rateLimiterWriter,
|
||||
subscriptionID: config.SubscriptionID,
|
||||
cloudName: config.CloudName,
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
// Get gets a RouteTable.
|
||||
func (c *Client) Get(ctx context.Context, resourceGroupName string, routeTableName string, expand string) (network.RouteTable, *retry.Error) {
|
||||
mc := metrics.NewMetricContext("route_tables", "get", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterReader.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return network.RouteTable{}, retry.GetRateLimitError(false, "RouteTableGet")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterReader.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("RouteTableGet", "client throttled", c.RetryAfterReader)
|
||||
return network.RouteTable{}, rerr
|
||||
}
|
||||
|
||||
result, rerr := c.getRouteTable(ctx, resourceGroupName, routeTableName, expand)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterReader = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// getRouteTable gets a RouteTable.
|
||||
func (c *Client) getRouteTable(ctx context.Context, resourceGroupName string, routeTableName string, expand string) (network.RouteTable, *retry.Error) {
|
||||
resourceID := armclient.GetResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Network/routeTables",
|
||||
routeTableName,
|
||||
)
|
||||
result := network.RouteTable{}
|
||||
|
||||
response, rerr := c.armClient.GetResource(ctx, resourceID, expand)
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "routetable.get.request", resourceID, rerr.Error())
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
err := autorest.Respond(
|
||||
response,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "routetable.get.respond", resourceID, err)
|
||||
return result, retry.GetError(response, err)
|
||||
}
|
||||
|
||||
result.Response = autorest.Response{Response: response}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// CreateOrUpdate creates or updates a RouteTable.
|
||||
func (c *Client) CreateOrUpdate(ctx context.Context, resourceGroupName string, routeTableName string, parameters network.RouteTable, etag string) *retry.Error {
|
||||
mc := metrics.NewMetricContext("route_tables", "create_or_update", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterWriter.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return retry.GetRateLimitError(true, "RouteTableCreateOrUpdate")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterWriter.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("RouteTableCreateOrUpdate", "client throttled", c.RetryAfterWriter)
|
||||
return rerr
|
||||
}
|
||||
|
||||
rerr := c.createOrUpdateRouteTable(ctx, resourceGroupName, routeTableName, parameters, etag)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterWriter = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return rerr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// createOrUpdateRouteTable creates or updates a RouteTable.
|
||||
func (c *Client) createOrUpdateRouteTable(ctx context.Context, resourceGroupName string, routeTableName string, parameters network.RouteTable, etag string) *retry.Error {
|
||||
resourceID := armclient.GetResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Network/routeTables",
|
||||
routeTableName,
|
||||
)
|
||||
decorators := []autorest.PrepareDecorator{
|
||||
autorest.WithPathParameters("{resourceID}", map[string]interface{}{"resourceID": resourceID}),
|
||||
autorest.WithJSON(parameters),
|
||||
}
|
||||
if etag != "" {
|
||||
decorators = append(decorators, autorest.WithHeader("If-Match", autorest.String(etag)))
|
||||
}
|
||||
|
||||
response, rerr := c.armClient.PutResourceWithDecorators(ctx, resourceID, parameters, decorators)
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "routetable.put.request", resourceID, rerr.Error())
|
||||
return rerr
|
||||
}
|
||||
|
||||
if response != nil && response.StatusCode != http.StatusNoContent {
|
||||
_, rerr = c.createOrUpdateResponder(response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "routetable.put.respond", resourceID, rerr.Error())
|
||||
return rerr
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) createOrUpdateResponder(resp *http.Response) (*network.RouteTable, *retry.Error) {
|
||||
result := &network.RouteTable{}
|
||||
err := autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, retry.GetError(resp, err)
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routetableclient/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routetableclient/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package routetableclient implements the client for RouteTable.
|
||||
package routetableclient // import "sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routetableclient"
|
||||
44
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routetableclient/interface.go
generated
vendored
Normal file
44
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routetableclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package routetableclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
const (
|
||||
// APIVersion is the API version for network.
|
||||
APIVersion = "2020-08-01"
|
||||
// AzureStackCloudAPIVersion is the API version for Azure Stack
|
||||
AzureStackCloudAPIVersion = "2018-11-01"
|
||||
// AzureStackCloudName is the cloud name of Azure Stack
|
||||
AzureStackCloudName = "AZURESTACKCLOUD"
|
||||
)
|
||||
|
||||
// Interface is the client interface for RouteTable.
|
||||
// Don't forget to run "hack/update-mock-clients.sh" command to generate the mock client.
|
||||
type Interface interface {
|
||||
// Get gets a RouteTable.
|
||||
Get(ctx context.Context, resourceGroupName string, routeTableName string, expand string) (result network.RouteTable, rerr *retry.Error)
|
||||
|
||||
// CreateOrUpdate creates or updates a RouteTable.
|
||||
CreateOrUpdate(ctx context.Context, resourceGroupName string, routeTableName string, parameters network.RouteTable, etag string) *retry.Error
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routetableclient/mockroutetableclient/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routetableclient/mockroutetableclient/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package mockroutetableclient implements the mock client for RouteTable.
|
||||
package mockroutetableclient // import "sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routetableclient/mockroutetableclient"
|
||||
83
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routetableclient/mockroutetableclient/interface.go
generated
vendored
Normal file
83
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routetableclient/mockroutetableclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
// /*
|
||||
// Copyright The Kubernetes Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// */
|
||||
//
|
||||
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: /go/src/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routetableclient/interface.go
|
||||
|
||||
// Package mockroutetableclient is a generated GoMock package.
|
||||
package mockroutetableclient
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
network "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
retry "sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
// MockInterface is a mock of Interface interface.
|
||||
type MockInterface struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockInterfaceMockRecorder
|
||||
}
|
||||
|
||||
// MockInterfaceMockRecorder is the mock recorder for MockInterface.
|
||||
type MockInterfaceMockRecorder struct {
|
||||
mock *MockInterface
|
||||
}
|
||||
|
||||
// NewMockInterface creates a new mock instance.
|
||||
func NewMockInterface(ctrl *gomock.Controller) *MockInterface {
|
||||
mock := &MockInterface{ctrl: ctrl}
|
||||
mock.recorder = &MockInterfaceMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Get mocks base method.
|
||||
func (m *MockInterface) Get(ctx context.Context, resourceGroupName, routeTableName, expand string) (network.RouteTable, *retry.Error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Get", ctx, resourceGroupName, routeTableName, expand)
|
||||
ret0, _ := ret[0].(network.RouteTable)
|
||||
ret1, _ := ret[1].(*retry.Error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Get indicates an expected call of Get.
|
||||
func (mr *MockInterfaceMockRecorder) Get(ctx, resourceGroupName, routeTableName, expand interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockInterface)(nil).Get), ctx, resourceGroupName, routeTableName, expand)
|
||||
}
|
||||
|
||||
// CreateOrUpdate mocks base method.
|
||||
func (m *MockInterface) CreateOrUpdate(ctx context.Context, resourceGroupName, routeTableName string, parameters network.RouteTable, etag string) *retry.Error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CreateOrUpdate", ctx, resourceGroupName, routeTableName, parameters, etag)
|
||||
ret0, _ := ret[0].(*retry.Error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// CreateOrUpdate indicates an expected call of CreateOrUpdate.
|
||||
func (mr *MockInterfaceMockRecorder) CreateOrUpdate(ctx, resourceGroupName, routeTableName, parameters, etag interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateOrUpdate", reflect.TypeOf((*MockInterface)(nil).CreateOrUpdate), ctx, resourceGroupName, routeTableName, parameters, etag)
|
||||
}
|
||||
426
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/securitygroupclient/azure_securitygroupclient.go
generated
vendored
Normal file
426
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/securitygroupclient/azure_securitygroupclient.go
generated
vendored
Normal file
|
|
@ -0,0 +1,426 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package securitygroupclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
azclients "sigs.k8s.io/cloud-provider-azure/pkg/azureclients"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/armclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/metrics"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
var _ Interface = &Client{}
|
||||
|
||||
// Client implements SecurityGroup client Interface.
|
||||
type Client struct {
|
||||
armClient armclient.Interface
|
||||
subscriptionID string
|
||||
cloudName string
|
||||
|
||||
// Rate limiting configures.
|
||||
rateLimiterReader flowcontrol.RateLimiter
|
||||
rateLimiterWriter flowcontrol.RateLimiter
|
||||
|
||||
// ARM throttling configures.
|
||||
RetryAfterReader time.Time
|
||||
RetryAfterWriter time.Time
|
||||
}
|
||||
|
||||
// New creates a new SecurityGroup client with ratelimiting.
|
||||
func New(config *azclients.ClientConfig) *Client {
|
||||
baseURI := config.ResourceManagerEndpoint
|
||||
authorizer := config.Authorizer
|
||||
apiVersion := APIVersion
|
||||
if strings.EqualFold(config.CloudName, AzureStackCloudName) && !config.DisableAzureStackCloud {
|
||||
apiVersion = AzureStackCloudAPIVersion
|
||||
}
|
||||
armClient := armclient.New(authorizer, *config, baseURI, apiVersion)
|
||||
rateLimiterReader, rateLimiterWriter := azclients.NewRateLimiter(config.RateLimitConfig)
|
||||
|
||||
if azclients.RateLimitEnabled(config.RateLimitConfig) {
|
||||
klog.V(2).Infof("Azure SecurityGroupsClient (read ops) using rate limit config: QPS=%g, bucket=%d",
|
||||
config.RateLimitConfig.CloudProviderRateLimitQPS,
|
||||
config.RateLimitConfig.CloudProviderRateLimitBucket)
|
||||
klog.V(2).Infof("Azure SecurityGroupsClient (write ops) using rate limit config: QPS=%g, bucket=%d",
|
||||
config.RateLimitConfig.CloudProviderRateLimitQPSWrite,
|
||||
config.RateLimitConfig.CloudProviderRateLimitBucketWrite)
|
||||
}
|
||||
|
||||
client := &Client{
|
||||
armClient: armClient,
|
||||
rateLimiterReader: rateLimiterReader,
|
||||
rateLimiterWriter: rateLimiterWriter,
|
||||
subscriptionID: config.SubscriptionID,
|
||||
cloudName: config.CloudName,
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
// Get gets a SecurityGroup.
|
||||
func (c *Client) Get(ctx context.Context, resourceGroupName string, networkSecurityGroupName string, expand string) (network.SecurityGroup, *retry.Error) {
|
||||
mc := metrics.NewMetricContext("security_groups", "get", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterReader.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return network.SecurityGroup{}, retry.GetRateLimitError(false, "NSGGet")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterReader.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("NSGGet", "client throttled", c.RetryAfterReader)
|
||||
return network.SecurityGroup{}, rerr
|
||||
}
|
||||
|
||||
result, rerr := c.getSecurityGroup(ctx, resourceGroupName, networkSecurityGroupName, expand)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterReader = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// getSecurityGroup gets a SecurityGroup.
|
||||
func (c *Client) getSecurityGroup(ctx context.Context, resourceGroupName string, networkSecurityGroupName string, expand string) (network.SecurityGroup, *retry.Error) {
|
||||
resourceID := armclient.GetResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Network/networkSecurityGroups",
|
||||
networkSecurityGroupName,
|
||||
)
|
||||
result := network.SecurityGroup{}
|
||||
|
||||
response, rerr := c.armClient.GetResource(ctx, resourceID, expand)
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "securitygroup.get.request", resourceID, rerr.Error())
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
err := autorest.Respond(
|
||||
response,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "securitygroup.get.respond", resourceID, err)
|
||||
return result, retry.GetError(response, err)
|
||||
}
|
||||
|
||||
result.Response = autorest.Response{Response: response}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// List gets a list of SecurityGroups in the resource group.
|
||||
func (c *Client) List(ctx context.Context, resourceGroupName string) ([]network.SecurityGroup, *retry.Error) {
|
||||
mc := metrics.NewMetricContext("security_groups", "list", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterReader.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return nil, retry.GetRateLimitError(false, "NSGList")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterReader.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("NSGList", "client throttled", c.RetryAfterReader)
|
||||
return nil, rerr
|
||||
}
|
||||
|
||||
result, rerr := c.listSecurityGroup(ctx, resourceGroupName)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterReader = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// listSecurityGroup gets a list of SecurityGroups in the resource group.
|
||||
func (c *Client) listSecurityGroup(ctx context.Context, resourceGroupName string) ([]network.SecurityGroup, *retry.Error) {
|
||||
resourceID := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/networkSecurityGroups",
|
||||
autorest.Encode("path", c.subscriptionID),
|
||||
autorest.Encode("path", resourceGroupName))
|
||||
result := make([]network.SecurityGroup, 0)
|
||||
page := &SecurityGroupListResultPage{}
|
||||
page.fn = c.listNextResults
|
||||
|
||||
resp, rerr := c.armClient.GetResource(ctx, resourceID, "")
|
||||
defer c.armClient.CloseResponse(ctx, resp)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "securitygroup.list.request", resourceID, rerr.Error())
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
var err error
|
||||
page.sglr, err = c.listResponder(resp)
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "securitygroup.list.respond", resourceID, err)
|
||||
return result, retry.GetError(resp, err)
|
||||
}
|
||||
|
||||
for {
|
||||
result = append(result, page.Values()...)
|
||||
|
||||
// Abort the loop when there's no nextLink in the response.
|
||||
if to.String(page.Response().NextLink) == "" {
|
||||
break
|
||||
}
|
||||
|
||||
if err = page.NextWithContext(ctx); err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "securitygroup.list.next", resourceID, err)
|
||||
return result, retry.GetError(page.Response().Response.Response, err)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// CreateOrUpdate creates or updates a SecurityGroup.
|
||||
func (c *Client) CreateOrUpdate(ctx context.Context, resourceGroupName string, networkSecurityGroupName string, parameters network.SecurityGroup, etag string) *retry.Error {
|
||||
mc := metrics.NewMetricContext("security_groups", "create_or_update", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterWriter.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return retry.GetRateLimitError(true, "NSGCreateOrUpdate")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterWriter.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("NSGCreateOrUpdate", "client throttled", c.RetryAfterWriter)
|
||||
return rerr
|
||||
}
|
||||
|
||||
rerr := c.createOrUpdateNSG(ctx, resourceGroupName, networkSecurityGroupName, parameters, etag)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterWriter = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return rerr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// createOrUpdateNSG creates or updates a SecurityGroup.
|
||||
func (c *Client) createOrUpdateNSG(ctx context.Context, resourceGroupName string, networkSecurityGroupName string, parameters network.SecurityGroup, etag string) *retry.Error {
|
||||
resourceID := armclient.GetResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Network/networkSecurityGroups",
|
||||
networkSecurityGroupName,
|
||||
)
|
||||
decorators := []autorest.PrepareDecorator{
|
||||
autorest.WithPathParameters("{resourceID}", map[string]interface{}{"resourceID": resourceID}),
|
||||
autorest.WithJSON(parameters),
|
||||
}
|
||||
if etag != "" {
|
||||
decorators = append(decorators, autorest.WithHeader("If-Match", autorest.String(etag)))
|
||||
}
|
||||
|
||||
response, rerr := c.armClient.PutResourceWithDecorators(ctx, resourceID, parameters, decorators)
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "securityGroup.put.request", resourceID, rerr.Error())
|
||||
return rerr
|
||||
}
|
||||
|
||||
if response != nil && response.StatusCode != http.StatusNoContent {
|
||||
_, rerr = c.createOrUpdateResponder(response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "securityGroup.put.respond", resourceID, rerr.Error())
|
||||
return rerr
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) createOrUpdateResponder(resp *http.Response) (*network.SecurityGroup, *retry.Error) {
|
||||
result := &network.SecurityGroup{}
|
||||
err := autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, retry.GetError(resp, err)
|
||||
}
|
||||
|
||||
// Delete deletes a SecurityGroup by name.
|
||||
func (c *Client) Delete(ctx context.Context, resourceGroupName string, networkSecurityGroupName string) *retry.Error {
|
||||
mc := metrics.NewMetricContext("security_groups", "delete", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterWriter.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return retry.GetRateLimitError(true, "NSGDelete")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterWriter.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("NSGDelete", "client throttled", c.RetryAfterWriter)
|
||||
return rerr
|
||||
}
|
||||
|
||||
rerr := c.deleteNSG(ctx, resourceGroupName, networkSecurityGroupName)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterWriter = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return rerr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteNSG deletes a SecurityGroup by name.
|
||||
func (c *Client) deleteNSG(ctx context.Context, resourceGroupName string, networkSecurityGroupName string) *retry.Error {
|
||||
resourceID := armclient.GetResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Network/networkSecurityGroups",
|
||||
networkSecurityGroupName,
|
||||
)
|
||||
|
||||
return c.armClient.DeleteResource(ctx, resourceID, "")
|
||||
}
|
||||
|
||||
func (c *Client) listResponder(resp *http.Response) (result network.SecurityGroupListResult, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
autorest.ByIgnoring(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// securityGroupListResultPreparer prepares a request to retrieve the next set of results.
|
||||
// It returns nil if no more results exist.
|
||||
func (c *Client) securityGroupListResultPreparer(ctx context.Context, sglr network.SecurityGroupListResult) (*http.Request, error) {
|
||||
if sglr.NextLink == nil || len(to.String(sglr.NextLink)) < 1 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
decorators := []autorest.PrepareDecorator{
|
||||
autorest.WithBaseURL(to.String(sglr.NextLink)),
|
||||
}
|
||||
return c.armClient.PrepareGetRequest(ctx, decorators...)
|
||||
}
|
||||
|
||||
// listNextResults retrieves the next set of results, if any.
|
||||
func (c *Client) listNextResults(ctx context.Context, lastResults network.SecurityGroupListResult) (result network.SecurityGroupListResult, err error) {
|
||||
req, err := c.securityGroupListResultPreparer(ctx, lastResults)
|
||||
if err != nil {
|
||||
return result, autorest.NewErrorWithError(err, "securitygroupclient", "listNextResults", nil, "Failure preparing next results request")
|
||||
}
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
|
||||
resp, rerr := c.armClient.Send(ctx, req)
|
||||
defer c.armClient.CloseResponse(ctx, resp)
|
||||
if rerr != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, autorest.NewErrorWithError(rerr.Error(), "securitygroupclient", "listNextResults", resp, "Failure sending next results request")
|
||||
}
|
||||
|
||||
result, err = c.listResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "securitygroupclient", "listNextResults", resp, "Failure responding to next results request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SecurityGroupListResultPage contains a page of SecurityGroup values.
|
||||
type SecurityGroupListResultPage struct {
|
||||
fn func(context.Context, network.SecurityGroupListResult) (network.SecurityGroupListResult, error)
|
||||
sglr network.SecurityGroupListResult
|
||||
}
|
||||
|
||||
// NextWithContext advances to the next page of values. If there was an error making
|
||||
// the request the page does not advance and the error is returned.
|
||||
func (page *SecurityGroupListResultPage) NextWithContext(ctx context.Context) (err error) {
|
||||
next, err := page.fn(ctx, page.sglr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
page.sglr = next
|
||||
return nil
|
||||
}
|
||||
|
||||
// Next advances to the next page of values. If there was an error making
|
||||
// the request the page does not advance and the error is returned.
|
||||
// Deprecated: Use NextWithContext() instead.
|
||||
func (page *SecurityGroupListResultPage) Next() error {
|
||||
return page.NextWithContext(context.Background())
|
||||
}
|
||||
|
||||
// NotDone returns true if the page enumeration should be started or is not yet complete.
|
||||
func (page SecurityGroupListResultPage) NotDone() bool {
|
||||
return !page.sglr.IsEmpty()
|
||||
}
|
||||
|
||||
// Response returns the raw server response from the last page request.
|
||||
func (page SecurityGroupListResultPage) Response() network.SecurityGroupListResult {
|
||||
return page.sglr
|
||||
}
|
||||
|
||||
// Values returns the slice of values for the current page or nil if there are no values.
|
||||
func (page SecurityGroupListResultPage) Values() []network.SecurityGroup {
|
||||
if page.sglr.IsEmpty() {
|
||||
return nil
|
||||
}
|
||||
return *page.sglr.Value
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/securitygroupclient/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/securitygroupclient/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package securitygroupclient implements the client for SecurityGroups.
|
||||
package securitygroupclient // import "sigs.k8s.io/cloud-provider-azure/pkg/azureclients/securitygroupclient"
|
||||
50
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/securitygroupclient/interface.go
generated
vendored
Normal file
50
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/securitygroupclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package securitygroupclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
const (
|
||||
// APIVersion is the API version for network.
|
||||
APIVersion = "2020-08-01"
|
||||
// AzureStackCloudAPIVersion is the API version for Azure Stack
|
||||
AzureStackCloudAPIVersion = "2018-11-01"
|
||||
// AzureStackCloudName is the cloud name of Azure Stack
|
||||
AzureStackCloudName = "AZURESTACKCLOUD"
|
||||
)
|
||||
|
||||
// Interface is the client interface for SecurityGroups.
|
||||
// Don't forget to run "hack/update-mock-clients.sh" command to generate the mock client.
|
||||
type Interface interface {
|
||||
// Get gets a SecurityGroup.
|
||||
Get(ctx context.Context, resourceGroupName string, networkSecurityGroupName string, expand string) (result network.SecurityGroup, rerr *retry.Error)
|
||||
|
||||
// List gets a list of SecurityGroup in the resource group.
|
||||
List(ctx context.Context, resourceGroupName string) (result []network.SecurityGroup, rerr *retry.Error)
|
||||
|
||||
// CreateOrUpdate creates or updates a SecurityGroup.
|
||||
CreateOrUpdate(ctx context.Context, resourceGroupName string, networkSecurityGroupName string, parameters network.SecurityGroup, etag string) *retry.Error
|
||||
|
||||
// Delete deletes a SecurityGroup by name.
|
||||
Delete(ctx context.Context, resourceGroupName string, networkSecurityGroupName string) *retry.Error
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/securitygroupclient/mocksecuritygroupclient/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/securitygroupclient/mocksecuritygroupclient/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package mocksecuritygroupclient implements the mock client for SecurityGroups.
|
||||
package mocksecuritygroupclient // import "sigs.k8s.io/cloud-provider-azure/pkg/azureclients/securitygroupclient/mocksecuritygroupclient"
|
||||
112
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/securitygroupclient/mocksecuritygroupclient/interface.go
generated
vendored
Normal file
112
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/securitygroupclient/mocksecuritygroupclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
// /*
|
||||
// Copyright The Kubernetes Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// */
|
||||
//
|
||||
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: /go/src/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/securitygroupclient/interface.go
|
||||
|
||||
// Package mocksecuritygroupclient is a generated GoMock package.
|
||||
package mocksecuritygroupclient
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
network "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
retry "sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
// MockInterface is a mock of Interface interface.
|
||||
type MockInterface struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockInterfaceMockRecorder
|
||||
}
|
||||
|
||||
// MockInterfaceMockRecorder is the mock recorder for MockInterface.
|
||||
type MockInterfaceMockRecorder struct {
|
||||
mock *MockInterface
|
||||
}
|
||||
|
||||
// NewMockInterface creates a new mock instance.
|
||||
func NewMockInterface(ctrl *gomock.Controller) *MockInterface {
|
||||
mock := &MockInterface{ctrl: ctrl}
|
||||
mock.recorder = &MockInterfaceMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Get mocks base method.
|
||||
func (m *MockInterface) Get(ctx context.Context, resourceGroupName, networkSecurityGroupName, expand string) (network.SecurityGroup, *retry.Error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Get", ctx, resourceGroupName, networkSecurityGroupName, expand)
|
||||
ret0, _ := ret[0].(network.SecurityGroup)
|
||||
ret1, _ := ret[1].(*retry.Error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Get indicates an expected call of Get.
|
||||
func (mr *MockInterfaceMockRecorder) Get(ctx, resourceGroupName, networkSecurityGroupName, expand interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockInterface)(nil).Get), ctx, resourceGroupName, networkSecurityGroupName, expand)
|
||||
}
|
||||
|
||||
// List mocks base method.
|
||||
func (m *MockInterface) List(ctx context.Context, resourceGroupName string) ([]network.SecurityGroup, *retry.Error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "List", ctx, resourceGroupName)
|
||||
ret0, _ := ret[0].([]network.SecurityGroup)
|
||||
ret1, _ := ret[1].(*retry.Error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// List indicates an expected call of List.
|
||||
func (mr *MockInterfaceMockRecorder) List(ctx, resourceGroupName interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockInterface)(nil).List), ctx, resourceGroupName)
|
||||
}
|
||||
|
||||
// CreateOrUpdate mocks base method.
|
||||
func (m *MockInterface) CreateOrUpdate(ctx context.Context, resourceGroupName, networkSecurityGroupName string, parameters network.SecurityGroup, etag string) *retry.Error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CreateOrUpdate", ctx, resourceGroupName, networkSecurityGroupName, parameters, etag)
|
||||
ret0, _ := ret[0].(*retry.Error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// CreateOrUpdate indicates an expected call of CreateOrUpdate.
|
||||
func (mr *MockInterfaceMockRecorder) CreateOrUpdate(ctx, resourceGroupName, networkSecurityGroupName, parameters, etag interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateOrUpdate", reflect.TypeOf((*MockInterface)(nil).CreateOrUpdate), ctx, resourceGroupName, networkSecurityGroupName, parameters, etag)
|
||||
}
|
||||
|
||||
// Delete mocks base method.
|
||||
func (m *MockInterface) Delete(ctx context.Context, resourceGroupName, networkSecurityGroupName string) *retry.Error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Delete", ctx, resourceGroupName, networkSecurityGroupName)
|
||||
ret0, _ := ret[0].(*retry.Error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Delete indicates an expected call of Delete.
|
||||
func (mr *MockInterfaceMockRecorder) Delete(ctx, resourceGroupName, networkSecurityGroupName interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockInterface)(nil).Delete), ctx, resourceGroupName, networkSecurityGroupName)
|
||||
}
|
||||
419
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/snapshotclient/azure_snapshotclient.go
generated
vendored
Normal file
419
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/snapshotclient/azure_snapshotclient.go
generated
vendored
Normal file
|
|
@ -0,0 +1,419 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package snapshotclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-12-01/compute"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
azclients "sigs.k8s.io/cloud-provider-azure/pkg/azureclients"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/armclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/metrics"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
var _ Interface = &Client{}
|
||||
|
||||
// Client implements Snapshot client Interface.
|
||||
type Client struct {
|
||||
armClient armclient.Interface
|
||||
subscriptionID string
|
||||
cloudName string
|
||||
|
||||
// Rate limiting configures.
|
||||
rateLimiterReader flowcontrol.RateLimiter
|
||||
rateLimiterWriter flowcontrol.RateLimiter
|
||||
|
||||
// ARM throttling configures.
|
||||
RetryAfterReader time.Time
|
||||
RetryAfterWriter time.Time
|
||||
}
|
||||
|
||||
// New creates a new Snapshot client with ratelimiting.
|
||||
func New(config *azclients.ClientConfig) *Client {
|
||||
baseURI := config.ResourceManagerEndpoint
|
||||
authorizer := config.Authorizer
|
||||
apiVersion := APIVersion
|
||||
if strings.EqualFold(config.CloudName, AzureStackCloudName) && !config.DisableAzureStackCloud {
|
||||
apiVersion = AzureStackCloudAPIVersion
|
||||
}
|
||||
armClient := armclient.New(authorizer, *config, baseURI, apiVersion)
|
||||
rateLimiterReader, rateLimiterWriter := azclients.NewRateLimiter(config.RateLimitConfig)
|
||||
|
||||
if azclients.RateLimitEnabled(config.RateLimitConfig) {
|
||||
klog.V(2).Infof("Azure SnapshotClient (read ops) using rate limit config: QPS=%g, bucket=%d",
|
||||
config.RateLimitConfig.CloudProviderRateLimitQPS,
|
||||
config.RateLimitConfig.CloudProviderRateLimitBucket)
|
||||
klog.V(2).Infof("Azure SnapshotClient (write ops) using rate limit config: QPS=%g, bucket=%d",
|
||||
config.RateLimitConfig.CloudProviderRateLimitQPSWrite,
|
||||
config.RateLimitConfig.CloudProviderRateLimitBucketWrite)
|
||||
}
|
||||
|
||||
client := &Client{
|
||||
armClient: armClient,
|
||||
rateLimiterReader: rateLimiterReader,
|
||||
rateLimiterWriter: rateLimiterWriter,
|
||||
subscriptionID: config.SubscriptionID,
|
||||
cloudName: config.CloudName,
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
// Get gets a Snapshot.
|
||||
func (c *Client) Get(ctx context.Context, resourceGroupName string, snapshotName string) (compute.Snapshot, *retry.Error) {
|
||||
mc := metrics.NewMetricContext("snapshot", "get", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterReader.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return compute.Snapshot{}, retry.GetRateLimitError(false, "SnapshotGet")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterReader.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("SnapshotGet", "client throttled", c.RetryAfterReader)
|
||||
return compute.Snapshot{}, rerr
|
||||
}
|
||||
|
||||
result, rerr := c.getSnapshot(ctx, resourceGroupName, snapshotName)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterReader = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// getSnapshot gets a Snapshot.
|
||||
func (c *Client) getSnapshot(ctx context.Context, resourceGroupName string, snapshotName string) (compute.Snapshot, *retry.Error) {
|
||||
resourceID := armclient.GetResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Compute/snapshots",
|
||||
snapshotName,
|
||||
)
|
||||
result := compute.Snapshot{}
|
||||
|
||||
response, rerr := c.armClient.GetResource(ctx, resourceID, "")
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "snapshot.get.request", resourceID, rerr.Error())
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
err := autorest.Respond(
|
||||
response,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "snapshot.get.respond", resourceID, err)
|
||||
return result, retry.GetError(response, err)
|
||||
}
|
||||
|
||||
result.Response = autorest.Response{Response: response}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Delete deletes a Snapshot by name.
|
||||
func (c *Client) Delete(ctx context.Context, resourceGroupName string, snapshotName string) *retry.Error {
|
||||
mc := metrics.NewMetricContext("snapshot", "delete", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterWriter.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return retry.GetRateLimitError(true, "SnapshotDelete")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterWriter.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("SnapshotDelete", "client throttled", c.RetryAfterWriter)
|
||||
return rerr
|
||||
}
|
||||
|
||||
rerr := c.deleteSnapshot(ctx, resourceGroupName, snapshotName)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterWriter = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return rerr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteSnapshot deletes a PublicIPAddress by name.
|
||||
func (c *Client) deleteSnapshot(ctx context.Context, resourceGroupName string, snapshotName string) *retry.Error {
|
||||
resourceID := armclient.GetResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Compute/snapshots",
|
||||
snapshotName,
|
||||
)
|
||||
|
||||
return c.armClient.DeleteResource(ctx, resourceID, "")
|
||||
}
|
||||
|
||||
// CreateOrUpdate creates or updates a Snapshot.
|
||||
func (c *Client) CreateOrUpdate(ctx context.Context, resourceGroupName string, snapshotName string, snapshot compute.Snapshot) *retry.Error {
|
||||
mc := metrics.NewMetricContext("snapshot", "create_or_update", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterWriter.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return retry.GetRateLimitError(true, "SnapshotCreateOrUpdate")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterWriter.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("SnapshotCreateOrUpdate", "client throttled", c.RetryAfterWriter)
|
||||
return rerr
|
||||
}
|
||||
|
||||
rerr := c.createOrUpdateSnapshot(ctx, resourceGroupName, snapshotName, snapshot)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterWriter = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return rerr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// createOrUpdateSnapshot creates or updates a Snapshot.
|
||||
func (c *Client) createOrUpdateSnapshot(ctx context.Context, resourceGroupName string, snapshotName string, snapshot compute.Snapshot) *retry.Error {
|
||||
resourceID := armclient.GetResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Compute/snapshots",
|
||||
snapshotName,
|
||||
)
|
||||
|
||||
response, rerr := c.armClient.PutResource(ctx, resourceID, snapshot)
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "snapshot.put.request", resourceID, rerr.Error())
|
||||
return rerr
|
||||
}
|
||||
|
||||
if response != nil && response.StatusCode != http.StatusNoContent {
|
||||
_, rerr = c.createOrUpdateResponder(response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "snapshot.put.respond", resourceID, rerr.Error())
|
||||
return rerr
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) createOrUpdateResponder(resp *http.Response) (*compute.Snapshot, *retry.Error) {
|
||||
result := &compute.Snapshot{}
|
||||
err := autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, retry.GetError(resp, err)
|
||||
}
|
||||
|
||||
// ListByResourceGroup get a list snapshots by resourceGroup.
|
||||
func (c *Client) ListByResourceGroup(ctx context.Context, resourceGroupName string) ([]compute.Snapshot, *retry.Error) {
|
||||
mc := metrics.NewMetricContext("snapshot", "list_by_resource_group", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterReader.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return nil, retry.GetRateLimitError(false, "SnapshotListByResourceGroup")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterReader.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("SnapshotListByResourceGroup", "client throttled", c.RetryAfterReader)
|
||||
return nil, rerr
|
||||
}
|
||||
|
||||
result, rerr := c.listSnapshotsByResourceGroup(ctx, resourceGroupName)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterReader = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// listSnapshotsByResourceGroup gets a list of snapshots in the resource group.
|
||||
func (c *Client) listSnapshotsByResourceGroup(ctx context.Context, resourceGroupName string) ([]compute.Snapshot, *retry.Error) {
|
||||
resourceID := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/snapshots",
|
||||
autorest.Encode("path", c.subscriptionID),
|
||||
autorest.Encode("path", resourceGroupName))
|
||||
result := make([]compute.Snapshot, 0)
|
||||
page := &SnapshotListPage{}
|
||||
page.fn = c.listNextResults
|
||||
|
||||
resp, rerr := c.armClient.GetResource(ctx, resourceID, "")
|
||||
defer c.armClient.CloseResponse(ctx, resp)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "snapshot.list.request", resourceID, rerr.Error())
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
var err error
|
||||
page.sl, err = c.listResponder(resp)
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "snapshot.list.respond", resourceID, err)
|
||||
return result, retry.GetError(resp, err)
|
||||
}
|
||||
|
||||
for {
|
||||
result = append(result, page.Values()...)
|
||||
|
||||
// Abort the loop when there's no nextLink in the response.
|
||||
if to.String(page.Response().NextLink) == "" {
|
||||
break
|
||||
}
|
||||
|
||||
if err = page.NextWithContext(ctx); err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "snapshot.list.next", resourceID, err)
|
||||
return result, retry.GetError(page.Response().Response.Response, err)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *Client) listResponder(resp *http.Response) (result compute.SnapshotList, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
autorest.ByIgnoring(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// SnapshotListResultPreparer prepares a request to retrieve the next set of results.
|
||||
// It returns nil if no more results exist.
|
||||
func (c *Client) SnapshotListResultPreparer(ctx context.Context, lr compute.SnapshotList) (*http.Request, error) {
|
||||
if lr.NextLink == nil || len(to.String(lr.NextLink)) < 1 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
decorators := []autorest.PrepareDecorator{
|
||||
autorest.WithBaseURL(to.String(lr.NextLink)),
|
||||
}
|
||||
return c.armClient.PrepareGetRequest(ctx, decorators...)
|
||||
}
|
||||
|
||||
// listNextResults retrieves the next set of results, if any.
|
||||
func (c *Client) listNextResults(ctx context.Context, lastResults compute.SnapshotList) (result compute.SnapshotList, err error) {
|
||||
req, err := c.SnapshotListResultPreparer(ctx, lastResults)
|
||||
if err != nil {
|
||||
return result, autorest.NewErrorWithError(err, "snapshotclient", "listNextResults", nil, "Failure preparing next results request")
|
||||
}
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
|
||||
resp, rerr := c.armClient.Send(ctx, req)
|
||||
defer c.armClient.CloseResponse(ctx, resp)
|
||||
if rerr != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, autorest.NewErrorWithError(rerr.Error(), "snapshotclient", "listNextResults", resp, "Failure sending next results request")
|
||||
}
|
||||
|
||||
result, err = c.listResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "snapshotclient", "listNextResults", resp, "Failure responding to next results request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SnapshotListPage contains a page of Snapshot values.
|
||||
type SnapshotListPage struct {
|
||||
fn func(context.Context, compute.SnapshotList) (compute.SnapshotList, error)
|
||||
sl compute.SnapshotList
|
||||
}
|
||||
|
||||
// NextWithContext advances to the next page of values. If there was an error making
|
||||
// the request the page does not advance and the error is returned.
|
||||
func (page *SnapshotListPage) NextWithContext(ctx context.Context) (err error) {
|
||||
next, err := page.fn(ctx, page.sl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
page.sl = next
|
||||
return nil
|
||||
}
|
||||
|
||||
// Next advances to the next page of values. If there was an error making
|
||||
// the request the page does not advance and the error is returned.
|
||||
// Deprecated: Use NextWithContext() instead.
|
||||
func (page *SnapshotListPage) Next() error {
|
||||
return page.NextWithContext(context.Background())
|
||||
}
|
||||
|
||||
// NotDone returns true if the page enumeration should be started or is not yet complete.
|
||||
func (page SnapshotListPage) NotDone() bool {
|
||||
return !page.sl.IsEmpty()
|
||||
}
|
||||
|
||||
// Response returns the raw server response from the last page request.
|
||||
func (page SnapshotListPage) Response() compute.SnapshotList {
|
||||
return page.sl
|
||||
}
|
||||
|
||||
// Values returns the slice of values for the current page or nil if there are no values.
|
||||
func (page SnapshotListPage) Values() []compute.Snapshot {
|
||||
if page.sl.IsEmpty() {
|
||||
return nil
|
||||
}
|
||||
return *page.sl.Value
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/snapshotclient/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/snapshotclient/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package snapshotclient implements the client for Snapshots.
|
||||
package snapshotclient // import "sigs.k8s.io/cloud-provider-azure/pkg/azureclients/snapshotclient"
|
||||
50
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/snapshotclient/interface.go
generated
vendored
Normal file
50
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/snapshotclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package snapshotclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-12-01/compute"
|
||||
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
const (
|
||||
// APIVersion is the API version for compute.
|
||||
APIVersion = "2020-12-01"
|
||||
// AzureStackCloudAPIVersion is the API version for Azure Stack
|
||||
AzureStackCloudAPIVersion = "2019-03-01"
|
||||
// AzureStackCloudName is the cloud name of Azure Stack
|
||||
AzureStackCloudName = "AZURESTACKCLOUD"
|
||||
)
|
||||
|
||||
// Interface is the client interface for Snapshots.
|
||||
// Don't forget to run "hack/update-mock-clients.sh" command to generate the mock client.
|
||||
type Interface interface {
|
||||
// Get gets a Snapshot.
|
||||
Get(ctx context.Context, resourceGroupName string, snapshotName string) (compute.Snapshot, *retry.Error)
|
||||
|
||||
// Delete deletes a Snapshot by name.
|
||||
Delete(ctx context.Context, resourceGroupName string, snapshotName string) *retry.Error
|
||||
|
||||
// ListByResourceGroup get a list snapshots by resourceGroup.
|
||||
ListByResourceGroup(ctx context.Context, resourceGroupName string) ([]compute.Snapshot, *retry.Error)
|
||||
|
||||
// CreateOrUpdate creates or updates a Snapshot.
|
||||
CreateOrUpdate(ctx context.Context, resourceGroupName string, snapshotName string, snapshot compute.Snapshot) *retry.Error
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/snapshotclient/mocksnapshotclient/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/snapshotclient/mocksnapshotclient/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package mocksnapshotclient implements the mock client for Snapshots.
|
||||
package mocksnapshotclient // import "sigs.k8s.io/cloud-provider-azure/pkg/azureclients/snapshotclient/mocksnapshotclient"
|
||||
112
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/snapshotclient/mocksnapshotclient/interface.go
generated
vendored
Normal file
112
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/snapshotclient/mocksnapshotclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
// /*
|
||||
// Copyright The Kubernetes Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// */
|
||||
//
|
||||
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: /go/src/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/snapshotclient/interface.go
|
||||
|
||||
// Package mocksnapshotclient is a generated GoMock package.
|
||||
package mocksnapshotclient
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
compute "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-12-01/compute"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
retry "sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
// MockInterface is a mock of Interface interface.
|
||||
type MockInterface struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockInterfaceMockRecorder
|
||||
}
|
||||
|
||||
// MockInterfaceMockRecorder is the mock recorder for MockInterface.
|
||||
type MockInterfaceMockRecorder struct {
|
||||
mock *MockInterface
|
||||
}
|
||||
|
||||
// NewMockInterface creates a new mock instance.
|
||||
func NewMockInterface(ctrl *gomock.Controller) *MockInterface {
|
||||
mock := &MockInterface{ctrl: ctrl}
|
||||
mock.recorder = &MockInterfaceMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Get mocks base method.
|
||||
func (m *MockInterface) Get(ctx context.Context, resourceGroupName, snapshotName string) (compute.Snapshot, *retry.Error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Get", ctx, resourceGroupName, snapshotName)
|
||||
ret0, _ := ret[0].(compute.Snapshot)
|
||||
ret1, _ := ret[1].(*retry.Error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Get indicates an expected call of Get.
|
||||
func (mr *MockInterfaceMockRecorder) Get(ctx, resourceGroupName, snapshotName interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockInterface)(nil).Get), ctx, resourceGroupName, snapshotName)
|
||||
}
|
||||
|
||||
// Delete mocks base method.
|
||||
func (m *MockInterface) Delete(ctx context.Context, resourceGroupName, snapshotName string) *retry.Error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Delete", ctx, resourceGroupName, snapshotName)
|
||||
ret0, _ := ret[0].(*retry.Error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Delete indicates an expected call of Delete.
|
||||
func (mr *MockInterfaceMockRecorder) Delete(ctx, resourceGroupName, snapshotName interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockInterface)(nil).Delete), ctx, resourceGroupName, snapshotName)
|
||||
}
|
||||
|
||||
// ListByResourceGroup mocks base method.
|
||||
func (m *MockInterface) ListByResourceGroup(ctx context.Context, resourceGroupName string) ([]compute.Snapshot, *retry.Error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ListByResourceGroup", ctx, resourceGroupName)
|
||||
ret0, _ := ret[0].([]compute.Snapshot)
|
||||
ret1, _ := ret[1].(*retry.Error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ListByResourceGroup indicates an expected call of ListByResourceGroup.
|
||||
func (mr *MockInterfaceMockRecorder) ListByResourceGroup(ctx, resourceGroupName interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListByResourceGroup", reflect.TypeOf((*MockInterface)(nil).ListByResourceGroup), ctx, resourceGroupName)
|
||||
}
|
||||
|
||||
// CreateOrUpdate mocks base method.
|
||||
func (m *MockInterface) CreateOrUpdate(ctx context.Context, resourceGroupName, snapshotName string, snapshot compute.Snapshot) *retry.Error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CreateOrUpdate", ctx, resourceGroupName, snapshotName, snapshot)
|
||||
ret0, _ := ret[0].(*retry.Error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// CreateOrUpdate indicates an expected call of CreateOrUpdate.
|
||||
func (mr *MockInterfaceMockRecorder) CreateOrUpdate(ctx, resourceGroupName, snapshotName, snapshot interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateOrUpdate", reflect.TypeOf((*MockInterface)(nil).CreateOrUpdate), ctx, resourceGroupName, snapshotName, snapshot)
|
||||
}
|
||||
426
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/subnetclient/azure_subnetclient.go
generated
vendored
Normal file
426
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/subnetclient/azure_subnetclient.go
generated
vendored
Normal file
|
|
@ -0,0 +1,426 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package subnetclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
azclients "sigs.k8s.io/cloud-provider-azure/pkg/azureclients"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/armclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/metrics"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
var _ Interface = &Client{}
|
||||
|
||||
// Client implements Subnet client Interface.
|
||||
type Client struct {
|
||||
armClient armclient.Interface
|
||||
subscriptionID string
|
||||
cloudName string
|
||||
|
||||
// Rate limiting configures.
|
||||
rateLimiterReader flowcontrol.RateLimiter
|
||||
rateLimiterWriter flowcontrol.RateLimiter
|
||||
|
||||
// ARM throttling configures.
|
||||
RetryAfterReader time.Time
|
||||
RetryAfterWriter time.Time
|
||||
}
|
||||
|
||||
// New creates a new Subnet client with ratelimiting.
|
||||
func New(config *azclients.ClientConfig) *Client {
|
||||
baseURI := config.ResourceManagerEndpoint
|
||||
authorizer := config.Authorizer
|
||||
apiVersion := APIVersion
|
||||
if strings.EqualFold(config.CloudName, AzureStackCloudName) && !config.DisableAzureStackCloud {
|
||||
apiVersion = AzureStackCloudAPIVersion
|
||||
}
|
||||
armClient := armclient.New(authorizer, *config, baseURI, apiVersion)
|
||||
rateLimiterReader, rateLimiterWriter := azclients.NewRateLimiter(config.RateLimitConfig)
|
||||
|
||||
if azclients.RateLimitEnabled(config.RateLimitConfig) {
|
||||
klog.V(2).Infof("Azure SubnetsClient (read ops) using rate limit config: QPS=%g, bucket=%d",
|
||||
config.RateLimitConfig.CloudProviderRateLimitQPS,
|
||||
config.RateLimitConfig.CloudProviderRateLimitBucket)
|
||||
klog.V(2).Infof("Azure SubnetsClient (write ops) using rate limit config: QPS=%g, bucket=%d",
|
||||
config.RateLimitConfig.CloudProviderRateLimitQPSWrite,
|
||||
config.RateLimitConfig.CloudProviderRateLimitBucketWrite)
|
||||
}
|
||||
|
||||
client := &Client{
|
||||
armClient: armClient,
|
||||
rateLimiterReader: rateLimiterReader,
|
||||
rateLimiterWriter: rateLimiterWriter,
|
||||
subscriptionID: config.SubscriptionID,
|
||||
cloudName: config.CloudName,
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
// Get gets a Subnet.
|
||||
func (c *Client) Get(ctx context.Context, resourceGroupName string, virtualNetworkName string, subnetName string, expand string) (network.Subnet, *retry.Error) {
|
||||
mc := metrics.NewMetricContext("subnets", "get", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterReader.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return network.Subnet{}, retry.GetRateLimitError(false, "SubnetGet")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterReader.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("SubnetGet", "client throttled", c.RetryAfterReader)
|
||||
return network.Subnet{}, rerr
|
||||
}
|
||||
|
||||
result, rerr := c.getSubnet(ctx, resourceGroupName, virtualNetworkName, subnetName, expand)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterReader = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// getSubnet gets a Subnet.
|
||||
func (c *Client) getSubnet(ctx context.Context, resourceGroupName string, virtualNetworkName string, subnetName string, expand string) (network.Subnet, *retry.Error) {
|
||||
resourceID := armclient.GetChildResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Network/virtualNetworks",
|
||||
virtualNetworkName,
|
||||
"subnets",
|
||||
subnetName,
|
||||
)
|
||||
result := network.Subnet{}
|
||||
|
||||
response, rerr := c.armClient.GetResource(ctx, resourceID, expand)
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "subnet.get.request", resourceID, rerr.Error())
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
err := autorest.Respond(
|
||||
response,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "subnet.get.respond", resourceID, err)
|
||||
return result, retry.GetError(response, err)
|
||||
}
|
||||
|
||||
result.Response = autorest.Response{Response: response}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// List gets a list of Subnets in the VNet.
|
||||
func (c *Client) List(ctx context.Context, resourceGroupName string, virtualNetworkName string) ([]network.Subnet, *retry.Error) {
|
||||
mc := metrics.NewMetricContext("subnets", "list", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterReader.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return nil, retry.GetRateLimitError(false, "SubnetList")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterReader.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("SubnetList", "client throttled", c.RetryAfterReader)
|
||||
return nil, rerr
|
||||
}
|
||||
|
||||
result, rerr := c.listSubnet(ctx, resourceGroupName, virtualNetworkName)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterReader = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// listSubnet gets a list of Subnets in the VNet.
|
||||
func (c *Client) listSubnet(ctx context.Context, resourceGroupName string, virtualNetworkName string) ([]network.Subnet, *retry.Error) {
|
||||
resourceID := armclient.GetChildResourcesListID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Network/virtualNetworks",
|
||||
virtualNetworkName,
|
||||
"subnets")
|
||||
|
||||
result := make([]network.Subnet, 0)
|
||||
page := &SubnetListResultPage{}
|
||||
page.fn = c.listNextResults
|
||||
|
||||
resp, rerr := c.armClient.GetResource(ctx, resourceID, "")
|
||||
defer c.armClient.CloseResponse(ctx, resp)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "subnet.list.request", resourceID, rerr.Error())
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
var err error
|
||||
page.slr, err = c.listResponder(resp)
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "subnet.list.respond", resourceID, err)
|
||||
return result, retry.GetError(resp, err)
|
||||
}
|
||||
|
||||
for {
|
||||
result = append(result, page.Values()...)
|
||||
|
||||
// Abort the loop when there's no nextLink in the response.
|
||||
if to.String(page.Response().NextLink) == "" {
|
||||
break
|
||||
}
|
||||
|
||||
if err = page.NextWithContext(ctx); err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "subnet.list.next", resourceID, err)
|
||||
return result, retry.GetError(page.Response().Response.Response, err)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// CreateOrUpdate creates or updates a Subnet.
|
||||
func (c *Client) CreateOrUpdate(ctx context.Context, resourceGroupName string, virtualNetworkName string, subnetName string, subnetParameters network.Subnet) *retry.Error {
|
||||
mc := metrics.NewMetricContext("subnets", "create_or_update", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterWriter.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return retry.GetRateLimitError(true, "SubnetCreateOrUpdate")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterWriter.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("SubnetCreateOrUpdate", "client throttled", c.RetryAfterWriter)
|
||||
return rerr
|
||||
}
|
||||
|
||||
rerr := c.createOrUpdateSubnet(ctx, resourceGroupName, virtualNetworkName, subnetName, subnetParameters)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterWriter = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return rerr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// createOrUpdateSubnet creates or updates a Subnet.
|
||||
func (c *Client) createOrUpdateSubnet(ctx context.Context, resourceGroupName string, virtualNetworkName string, subnetName string, subnetParameters network.Subnet) *retry.Error {
|
||||
resourceID := armclient.GetChildResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Network/virtualNetworks",
|
||||
virtualNetworkName,
|
||||
"subnets",
|
||||
subnetName)
|
||||
|
||||
response, rerr := c.armClient.PutResource(ctx, resourceID, subnetParameters)
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "subnet.put.request", resourceID, rerr.Error())
|
||||
return rerr
|
||||
}
|
||||
|
||||
if response != nil && response.StatusCode != http.StatusNoContent {
|
||||
_, rerr = c.createOrUpdateResponder(response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "subnet.put.respond", resourceID, rerr.Error())
|
||||
return rerr
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) createOrUpdateResponder(resp *http.Response) (*network.Subnet, *retry.Error) {
|
||||
result := &network.Subnet{}
|
||||
err := autorest.Respond(
|
||||
resp,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, retry.GetError(resp, err)
|
||||
}
|
||||
|
||||
// Delete deletes a Subnet by name.
|
||||
func (c *Client) Delete(ctx context.Context, resourceGroupName string, virtualNetworkName string, subnetName string) *retry.Error {
|
||||
mc := metrics.NewMetricContext("subnets", "delete", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterWriter.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return retry.GetRateLimitError(true, "SubnetDelete")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterWriter.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("SubnetDelete", "client throttled", c.RetryAfterWriter)
|
||||
return rerr
|
||||
}
|
||||
|
||||
rerr := c.deleteSubnet(ctx, resourceGroupName, virtualNetworkName, subnetName)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterWriter = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return rerr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// deleteSubnet deletes a PublicIPAddress by name.
|
||||
func (c *Client) deleteSubnet(ctx context.Context, resourceGroupName string, virtualNetworkName string, subnetName string) *retry.Error {
|
||||
resourceID := armclient.GetChildResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Network/virtualNetworks",
|
||||
virtualNetworkName,
|
||||
"subnets",
|
||||
subnetName)
|
||||
|
||||
return c.armClient.DeleteResource(ctx, resourceID, "")
|
||||
}
|
||||
|
||||
func (c *Client) listResponder(resp *http.Response) (result network.SubnetListResult, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
autorest.ByIgnoring(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// subnetListResultPreparer prepares a request to retrieve the next set of results.
|
||||
// It returns nil if no more results exist.
|
||||
func (c *Client) subnetListResultPreparer(ctx context.Context, lblr network.SubnetListResult) (*http.Request, error) {
|
||||
if lblr.NextLink == nil || len(to.String(lblr.NextLink)) < 1 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
decorators := []autorest.PrepareDecorator{
|
||||
autorest.WithBaseURL(to.String(lblr.NextLink)),
|
||||
}
|
||||
return c.armClient.PrepareGetRequest(ctx, decorators...)
|
||||
}
|
||||
|
||||
// listNextResults retrieves the next set of results, if any.
|
||||
func (c *Client) listNextResults(ctx context.Context, lastResults network.SubnetListResult) (result network.SubnetListResult, err error) {
|
||||
req, err := c.subnetListResultPreparer(ctx, lastResults)
|
||||
if err != nil {
|
||||
return result, autorest.NewErrorWithError(err, "subnetclient", "listNextResults", nil, "Failure preparing next results request")
|
||||
}
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
|
||||
resp, rerr := c.armClient.Send(ctx, req)
|
||||
defer c.armClient.CloseResponse(ctx, resp)
|
||||
if rerr != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, autorest.NewErrorWithError(rerr.Error(), "subnetclient", "listNextResults", resp, "Failure sending next results request")
|
||||
}
|
||||
|
||||
result, err = c.listResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "subnetclient", "listNextResults", resp, "Failure responding to next results request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SubnetListResultPage contains a page of Subnet values.
|
||||
type SubnetListResultPage struct {
|
||||
fn func(context.Context, network.SubnetListResult) (network.SubnetListResult, error)
|
||||
slr network.SubnetListResult
|
||||
}
|
||||
|
||||
// NextWithContext advances to the next page of values. If there was an error making
|
||||
// the request the page does not advance and the error is returned.
|
||||
func (page *SubnetListResultPage) NextWithContext(ctx context.Context) (err error) {
|
||||
next, err := page.fn(ctx, page.slr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
page.slr = next
|
||||
return nil
|
||||
}
|
||||
|
||||
// Next advances to the next page of values. If there was an error making
|
||||
// the request the page does not advance and the error is returned.
|
||||
// Deprecated: Use NextWithContext() instead.
|
||||
func (page *SubnetListResultPage) Next() error {
|
||||
return page.NextWithContext(context.Background())
|
||||
}
|
||||
|
||||
// NotDone returns true if the page enumeration should be started or is not yet complete.
|
||||
func (page SubnetListResultPage) NotDone() bool {
|
||||
return !page.slr.IsEmpty()
|
||||
}
|
||||
|
||||
// Response returns the raw server response from the last page request.
|
||||
func (page SubnetListResultPage) Response() network.SubnetListResult {
|
||||
return page.slr
|
||||
}
|
||||
|
||||
// Values returns the slice of values for the current page or nil if there are no values.
|
||||
func (page SubnetListResultPage) Values() []network.Subnet {
|
||||
if page.slr.IsEmpty() {
|
||||
return nil
|
||||
}
|
||||
return *page.slr.Value
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/subnetclient/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/subnetclient/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package subnetclient implements the client for Subnet.
|
||||
package subnetclient // import "sigs.k8s.io/cloud-provider-azure/pkg/azureclients/subnetclient"
|
||||
50
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/subnetclient/interface.go
generated
vendored
Normal file
50
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/subnetclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package subnetclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
const (
|
||||
// APIVersion is the API version for network.
|
||||
APIVersion = "2021-02-01"
|
||||
// AzureStackCloudAPIVersion is the API version for Azure Stack
|
||||
AzureStackCloudAPIVersion = "2018-11-01"
|
||||
// AzureStackCloudName is the cloud name of Azure Stack
|
||||
AzureStackCloudName = "AZURESTACKCLOUD"
|
||||
)
|
||||
|
||||
// Interface is the client interface for Subnet.
|
||||
// Don't forget to run "hack/update-mock-clients.sh" command to generate the mock client.
|
||||
type Interface interface {
|
||||
// Get gets a Subnet.
|
||||
Get(ctx context.Context, resourceGroupName string, virtualNetworkName string, subnetName string, expand string) (result network.Subnet, rerr *retry.Error)
|
||||
|
||||
// List gets a list of Subnet in the VNet.
|
||||
List(ctx context.Context, resourceGroupName string, virtualNetworkName string) (result []network.Subnet, rerr *retry.Error)
|
||||
|
||||
// CreateOrUpdate creates or updates a Subnet.
|
||||
CreateOrUpdate(ctx context.Context, resourceGroupName string, virtualNetworkName string, subnetName string, subnetParameters network.Subnet) *retry.Error
|
||||
|
||||
// Delete deletes a Subnet by name.
|
||||
Delete(ctx context.Context, resourceGroupName string, virtualNetworkName string, subnetName string) *retry.Error
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/subnetclient/mocksubnetclient/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/subnetclient/mocksubnetclient/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package mocksubnetclient implements the mock client for Subnet.
|
||||
package mocksubnetclient // import "sigs.k8s.io/cloud-provider-azure/pkg/azureclients/subnetclient/mocksubnetclient"
|
||||
112
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/subnetclient/mocksubnetclient/interface.go
generated
vendored
Normal file
112
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/subnetclient/mocksubnetclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
// /*
|
||||
// Copyright The Kubernetes Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// */
|
||||
//
|
||||
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: /go/src/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/subnetclient/interface.go
|
||||
|
||||
// Package mocksubnetclient is a generated GoMock package.
|
||||
package mocksubnetclient
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
network "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
retry "sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
// MockInterface is a mock of Interface interface.
|
||||
type MockInterface struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockInterfaceMockRecorder
|
||||
}
|
||||
|
||||
// MockInterfaceMockRecorder is the mock recorder for MockInterface.
|
||||
type MockInterfaceMockRecorder struct {
|
||||
mock *MockInterface
|
||||
}
|
||||
|
||||
// NewMockInterface creates a new mock instance.
|
||||
func NewMockInterface(ctrl *gomock.Controller) *MockInterface {
|
||||
mock := &MockInterface{ctrl: ctrl}
|
||||
mock.recorder = &MockInterfaceMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Get mocks base method.
|
||||
func (m *MockInterface) Get(ctx context.Context, resourceGroupName, virtualNetworkName, subnetName, expand string) (network.Subnet, *retry.Error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Get", ctx, resourceGroupName, virtualNetworkName, subnetName, expand)
|
||||
ret0, _ := ret[0].(network.Subnet)
|
||||
ret1, _ := ret[1].(*retry.Error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Get indicates an expected call of Get.
|
||||
func (mr *MockInterfaceMockRecorder) Get(ctx, resourceGroupName, virtualNetworkName, subnetName, expand interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockInterface)(nil).Get), ctx, resourceGroupName, virtualNetworkName, subnetName, expand)
|
||||
}
|
||||
|
||||
// List mocks base method.
|
||||
func (m *MockInterface) List(ctx context.Context, resourceGroupName, virtualNetworkName string) ([]network.Subnet, *retry.Error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "List", ctx, resourceGroupName, virtualNetworkName)
|
||||
ret0, _ := ret[0].([]network.Subnet)
|
||||
ret1, _ := ret[1].(*retry.Error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// List indicates an expected call of List.
|
||||
func (mr *MockInterfaceMockRecorder) List(ctx, resourceGroupName, virtualNetworkName interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockInterface)(nil).List), ctx, resourceGroupName, virtualNetworkName)
|
||||
}
|
||||
|
||||
// CreateOrUpdate mocks base method.
|
||||
func (m *MockInterface) CreateOrUpdate(ctx context.Context, resourceGroupName, virtualNetworkName, subnetName string, subnetParameters network.Subnet) *retry.Error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CreateOrUpdate", ctx, resourceGroupName, virtualNetworkName, subnetName, subnetParameters)
|
||||
ret0, _ := ret[0].(*retry.Error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// CreateOrUpdate indicates an expected call of CreateOrUpdate.
|
||||
func (mr *MockInterfaceMockRecorder) CreateOrUpdate(ctx, resourceGroupName, virtualNetworkName, subnetName, subnetParameters interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateOrUpdate", reflect.TypeOf((*MockInterface)(nil).CreateOrUpdate), ctx, resourceGroupName, virtualNetworkName, subnetName, subnetParameters)
|
||||
}
|
||||
|
||||
// Delete mocks base method.
|
||||
func (m *MockInterface) Delete(ctx context.Context, resourceGroupName, virtualNetworkName, subnetName string) *retry.Error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Delete", ctx, resourceGroupName, virtualNetworkName, subnetName)
|
||||
ret0, _ := ret[0].(*retry.Error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Delete indicates an expected call of Delete.
|
||||
func (mr *MockInterfaceMockRecorder) Delete(ctx, resourceGroupName, virtualNetworkName, subnetName interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockInterface)(nil).Delete), ctx, resourceGroupName, virtualNetworkName, subnetName)
|
||||
}
|
||||
65
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/virtualnetworklinksclient/azure_virtualnetworklinksclient.go
generated
vendored
Normal file
65
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/virtualnetworklinksclient/azure_virtualnetworklinksclient.go
generated
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package virtualnetworklinksclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns"
|
||||
"k8s.io/klog/v2"
|
||||
azclients "sigs.k8s.io/cloud-provider-azure/pkg/azureclients"
|
||||
)
|
||||
|
||||
var _ Interface = &Client{}
|
||||
|
||||
// Client implements virtualnetworklinksclient Interface.
|
||||
type Client struct {
|
||||
virtualNetworkLinksClient privatedns.VirtualNetworkLinksClient
|
||||
}
|
||||
|
||||
// New creates a new virtualnetworklinks client.
|
||||
func New(config *azclients.ClientConfig) *Client {
|
||||
virtualNetworkLinksClient := privatedns.NewVirtualNetworkLinksClient(config.SubscriptionID)
|
||||
virtualNetworkLinksClient.Authorizer = config.Authorizer
|
||||
|
||||
client := &Client{
|
||||
virtualNetworkLinksClient: virtualNetworkLinksClient,
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// CreateOrUpdate creates or updates a virtual network link
|
||||
func (c *Client) CreateOrUpdate(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string, parameters privatedns.VirtualNetworkLink, waitForCompletion bool) error {
|
||||
createOrUpdateFuture, err := c.virtualNetworkLinksClient.CreateOrUpdate(ctx, resourceGroupName, privateZoneName, virtualNetworkLinkName, parameters, "", "*")
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error for %s, resourceGroup: %s, privateZoneName: %s, error: %s", "virtualnetworklinks.put.request", resourceGroupName, privateZoneName, err)
|
||||
return err
|
||||
}
|
||||
if waitForCompletion {
|
||||
err := createOrUpdateFuture.WaitForCompletionRef(ctx, c.virtualNetworkLinksClient.Client)
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error while waiting for completion for %s, resourceGroup: %s, privateZoneName: %s, error: %s", "virtualnetworklinks.put.request", resourceGroupName, privateZoneName, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get gets a virtual network link
|
||||
func (c *Client) Get(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string) (result privatedns.VirtualNetworkLink, err error) {
|
||||
return c.virtualNetworkLinksClient.Get(ctx, resourceGroupName, privateZoneName, virtualNetworkLinkName)
|
||||
}
|
||||
34
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/virtualnetworklinksclient/interface.go
generated
vendored
Normal file
34
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/virtualnetworklinksclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package virtualnetworklinksclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns"
|
||||
)
|
||||
|
||||
// Interface is the client interface for Virtual Network Link.
|
||||
// Don't forget to run "hack/update-mock-clients.sh" command to generate the mock client.
|
||||
type Interface interface {
|
||||
|
||||
// Get gets a virtual network link
|
||||
Get(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string) (result privatedns.VirtualNetworkLink, err error)
|
||||
|
||||
// CreateOrUpdate creates or updates a private dns zone.
|
||||
CreateOrUpdate(ctx context.Context, resourceGroupName string, privateZoneName string, virtualNetworkLinkName string, parameters privatedns.VirtualNetworkLink, waitForCompletion bool) error
|
||||
}
|
||||
308
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmasclient/azure_vmasclient.go
generated
vendored
Normal file
308
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmasclient/azure_vmasclient.go
generated
vendored
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package vmasclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-12-01/compute"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
azclients "sigs.k8s.io/cloud-provider-azure/pkg/azureclients"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/armclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/metrics"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
//var _ Interface = &Client{}
|
||||
|
||||
// Client implements VMAS client Interface.
|
||||
type Client struct {
|
||||
armClient armclient.Interface
|
||||
subscriptionID string
|
||||
cloudName string
|
||||
|
||||
// Rate limiting configures.
|
||||
rateLimiterReader flowcontrol.RateLimiter
|
||||
rateLimiterWriter flowcontrol.RateLimiter
|
||||
|
||||
// ARM throttling configures.
|
||||
RetryAfterReader time.Time
|
||||
RetryAfterWriter time.Time
|
||||
}
|
||||
|
||||
// New creates a new VMAS client with ratelimiting.
|
||||
func New(config *azclients.ClientConfig) *Client {
|
||||
baseURI := config.ResourceManagerEndpoint
|
||||
authorizer := config.Authorizer
|
||||
apiVersion := APIVersion
|
||||
if strings.EqualFold(config.CloudName, AzureStackCloudName) && !config.DisableAzureStackCloud {
|
||||
apiVersion = AzureStackCloudAPIVersion
|
||||
}
|
||||
armClient := armclient.New(authorizer, *config, baseURI, apiVersion)
|
||||
rateLimiterReader, rateLimiterWriter := azclients.NewRateLimiter(config.RateLimitConfig)
|
||||
|
||||
if azclients.RateLimitEnabled(config.RateLimitConfig) {
|
||||
klog.V(2).Infof("Azure AvailabilitySetsClient (read ops) using rate limit config: QPS=%g, bucket=%d",
|
||||
config.RateLimitConfig.CloudProviderRateLimitQPS,
|
||||
config.RateLimitConfig.CloudProviderRateLimitBucket)
|
||||
klog.V(2).Infof("Azure AvailabilitySetsClient (write ops) using rate limit config: QPS=%g, bucket=%d",
|
||||
config.RateLimitConfig.CloudProviderRateLimitQPSWrite,
|
||||
config.RateLimitConfig.CloudProviderRateLimitBucketWrite)
|
||||
}
|
||||
|
||||
client := &Client{
|
||||
armClient: armClient,
|
||||
rateLimiterReader: rateLimiterReader,
|
||||
rateLimiterWriter: rateLimiterWriter,
|
||||
subscriptionID: config.SubscriptionID,
|
||||
cloudName: config.CloudName,
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
// Get gets a AvailabilitySet.
|
||||
func (c *Client) Get(ctx context.Context, resourceGroupName string, vmasName string) (compute.AvailabilitySet, *retry.Error) {
|
||||
mc := metrics.NewMetricContext("vmas", "get", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterReader.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return compute.AvailabilitySet{}, retry.GetRateLimitError(false, "VMASGet")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterReader.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("VMASGet", "client throttled", c.RetryAfterReader)
|
||||
return compute.AvailabilitySet{}, rerr
|
||||
}
|
||||
|
||||
result, rerr := c.getVMAS(ctx, resourceGroupName, vmasName)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterReader = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// getVMAS gets a AvailabilitySet.
|
||||
func (c *Client) getVMAS(ctx context.Context, resourceGroupName string, vmasName string) (compute.AvailabilitySet, *retry.Error) {
|
||||
resourceID := armclient.GetResourceID(
|
||||
c.subscriptionID,
|
||||
resourceGroupName,
|
||||
"Microsoft.Compute/availabilitySets",
|
||||
vmasName,
|
||||
)
|
||||
result := compute.AvailabilitySet{}
|
||||
|
||||
response, rerr := c.armClient.GetResource(ctx, resourceID, "")
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmas.get.request", resourceID, rerr.Error())
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
err := autorest.Respond(
|
||||
response,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmas.get.respond", resourceID, err)
|
||||
return result, retry.GetError(response, err)
|
||||
}
|
||||
|
||||
result.Response = autorest.Response{Response: response}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// List gets a list of AvailabilitySets in the resource group.
|
||||
func (c *Client) List(ctx context.Context, resourceGroupName string) ([]compute.AvailabilitySet, *retry.Error) {
|
||||
mc := metrics.NewMetricContext("vmas", "list", resourceGroupName, c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterReader.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return nil, retry.GetRateLimitError(false, "VMASList")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterReader.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("VMASList", "client throttled", c.RetryAfterReader)
|
||||
return nil, rerr
|
||||
}
|
||||
|
||||
result, rerr := c.listVMAS(ctx, resourceGroupName)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterReader = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// listVMAS gets a list of AvailabilitySets in the resource group.
|
||||
func (c *Client) listVMAS(ctx context.Context, resourceGroupName string) ([]compute.AvailabilitySet, *retry.Error) {
|
||||
resourceID := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/availabilitySets",
|
||||
autorest.Encode("path", c.subscriptionID),
|
||||
autorest.Encode("path", resourceGroupName))
|
||||
result := make([]compute.AvailabilitySet, 0)
|
||||
page := &AvailabilitySetListResultPage{}
|
||||
page.fn = c.listNextResults
|
||||
|
||||
resp, rerr := c.armClient.GetResource(ctx, resourceID, "")
|
||||
defer c.armClient.CloseResponse(ctx, resp)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmas.list.request", resourceID, rerr.Error())
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
var err error
|
||||
page.vmaslr, err = c.listResponder(resp)
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmas.list.respond", resourceID, err)
|
||||
return result, retry.GetError(resp, err)
|
||||
}
|
||||
|
||||
for {
|
||||
result = append(result, page.Values()...)
|
||||
|
||||
// Abort the loop when there's no nextLink in the response.
|
||||
if to.String(page.Response().NextLink) == "" {
|
||||
break
|
||||
}
|
||||
|
||||
if err = page.NextWithContext(ctx); err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmas.list.next", resourceID, err)
|
||||
return result, retry.GetError(page.Response().Response.Response, err)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *Client) listResponder(resp *http.Response) (result compute.AvailabilitySetListResult, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
autorest.ByIgnoring(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// availabilitySetListResultPreparer prepares a request to retrieve the next set of results.
|
||||
// It returns nil if no more results exist.
|
||||
func (c *Client) availabilitySetListResultPreparer(ctx context.Context, vmaslr compute.AvailabilitySetListResult) (*http.Request, error) {
|
||||
if vmaslr.NextLink == nil || len(to.String(vmaslr.NextLink)) < 1 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
decorators := []autorest.PrepareDecorator{
|
||||
autorest.WithBaseURL(to.String(vmaslr.NextLink)),
|
||||
}
|
||||
return c.armClient.PrepareGetRequest(ctx, decorators...)
|
||||
}
|
||||
|
||||
// listNextResults retrieves the next set of results, if any.
|
||||
func (c *Client) listNextResults(ctx context.Context, lastResults compute.AvailabilitySetListResult) (result compute.AvailabilitySetListResult, err error) {
|
||||
req, err := c.availabilitySetListResultPreparer(ctx, lastResults)
|
||||
if err != nil {
|
||||
return result, autorest.NewErrorWithError(err, "vmasclient", "listNextResults", nil, "Failure preparing next results request")
|
||||
}
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
|
||||
resp, rerr := c.armClient.Send(ctx, req)
|
||||
defer c.armClient.CloseResponse(ctx, resp)
|
||||
if rerr != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, autorest.NewErrorWithError(rerr.Error(), "vmasclient", "listNextResults", resp, "Failure sending next results request")
|
||||
}
|
||||
|
||||
result, err = c.listResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "vmasclient", "listNextResults", resp, "Failure responding to next results request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// AvailabilitySetListResultPage contains a page of AvailabilitySet values.
|
||||
type AvailabilitySetListResultPage struct {
|
||||
fn func(context.Context, compute.AvailabilitySetListResult) (compute.AvailabilitySetListResult, error)
|
||||
vmaslr compute.AvailabilitySetListResult
|
||||
}
|
||||
|
||||
// NextWithContext advances to the next page of values. If there was an error making
|
||||
// the request the page does not advance and the error is returned.
|
||||
func (page *AvailabilitySetListResultPage) NextWithContext(ctx context.Context) (err error) {
|
||||
next, err := page.fn(ctx, page.vmaslr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
page.vmaslr = next
|
||||
return nil
|
||||
}
|
||||
|
||||
// Next advances to the next page of values. If there was an error making
|
||||
// the request the page does not advance and the error is returned.
|
||||
// Deprecated: Use NextWithContext() instead.
|
||||
func (page *AvailabilitySetListResultPage) Next() error {
|
||||
return page.NextWithContext(context.Background())
|
||||
}
|
||||
|
||||
// NotDone returns true if the page enumeration should be started or is not yet complete.
|
||||
func (page AvailabilitySetListResultPage) NotDone() bool {
|
||||
return !page.vmaslr.IsEmpty()
|
||||
}
|
||||
|
||||
// Response returns the raw server response from the last page request.
|
||||
func (page AvailabilitySetListResultPage) Response() compute.AvailabilitySetListResult {
|
||||
return page.vmaslr
|
||||
}
|
||||
|
||||
// Values returns the slice of values for the current page or nil if there are no values.
|
||||
func (page AvailabilitySetListResultPage) Values() []compute.AvailabilitySet {
|
||||
if page.vmaslr.IsEmpty() {
|
||||
return nil
|
||||
}
|
||||
return *page.vmaslr.Value
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmasclient/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmasclient/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package vmasclient implements the client for VMAS.
|
||||
package vmasclient // import "sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmasclient"
|
||||
43
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmasclient/interface.go
generated
vendored
Normal file
43
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmasclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package vmasclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-12-01/compute"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
const (
|
||||
// APIVersion is the API version for VMAS.
|
||||
APIVersion = "2020-12-01"
|
||||
// AzureStackCloudAPIVersion is the API version for Azure Stack
|
||||
AzureStackCloudAPIVersion = "2019-07-01"
|
||||
// AzureStackCloudName is the cloud name of Azure Stack
|
||||
AzureStackCloudName = "AZURESTACKCLOUD"
|
||||
)
|
||||
|
||||
// Interface is the client interface for AvailabilitySet.
|
||||
// Don't forget to run "hack/update-mock-clients.sh" command to generate the mock client.
|
||||
type Interface interface {
|
||||
// Get gets a VirtualMachineScaleSet.
|
||||
Get(ctx context.Context, resourceGroupName string, VMScaleSetName string) (result compute.AvailabilitySet, rerr *retry.Error)
|
||||
|
||||
// List gets a list of VirtualMachineScaleSets in the resource group.
|
||||
List(ctx context.Context, resourceGroupName string) (result []compute.AvailabilitySet, rerr *retry.Error)
|
||||
}
|
||||
144
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmsizeclient/azure_vmsizeclient.go
generated
vendored
Normal file
144
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmsizeclient/azure_vmsizeclient.go
generated
vendored
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package vmsizeclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-12-01/compute"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
azclients "sigs.k8s.io/cloud-provider-azure/pkg/azureclients"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/armclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/metrics"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
var _ Interface = &Client{}
|
||||
|
||||
// Client implements VirtualMachineSize client Interface.
|
||||
type Client struct {
|
||||
armClient armclient.Interface
|
||||
subscriptionID string
|
||||
cloudName string
|
||||
|
||||
// Rate limiting configures.
|
||||
rateLimiterReader flowcontrol.RateLimiter
|
||||
rateLimiterWriter flowcontrol.RateLimiter
|
||||
|
||||
// ARM throttling configures.
|
||||
RetryAfterReader time.Time
|
||||
RetryAfterWriter time.Time
|
||||
}
|
||||
|
||||
// New creates a new VirtualMachineSize client with ratelimiting.
|
||||
func New(config *azclients.ClientConfig) *Client {
|
||||
baseURI := config.ResourceManagerEndpoint
|
||||
authorizer := config.Authorizer
|
||||
apiVersion := APIVersion
|
||||
if strings.EqualFold(config.CloudName, AzureStackCloudName) && !config.DisableAzureStackCloud {
|
||||
apiVersion = AzureStackCloudAPIVersion
|
||||
}
|
||||
armClient := armclient.New(authorizer, *config, baseURI, apiVersion)
|
||||
rateLimiterReader, rateLimiterWriter := azclients.NewRateLimiter(config.RateLimitConfig)
|
||||
|
||||
if azclients.RateLimitEnabled(config.RateLimitConfig) {
|
||||
klog.V(2).Infof("Azure VirtualMachineSizesClient (read ops) using rate limit config: QPS=%g, bucket=%d",
|
||||
config.RateLimitConfig.CloudProviderRateLimitQPS,
|
||||
config.RateLimitConfig.CloudProviderRateLimitBucket)
|
||||
klog.V(2).Infof("Azure VirtualMachineSizesClient (write ops) using rate limit config: QPS=%g, bucket=%d",
|
||||
config.RateLimitConfig.CloudProviderRateLimitQPSWrite,
|
||||
config.RateLimitConfig.CloudProviderRateLimitBucketWrite)
|
||||
}
|
||||
|
||||
client := &Client{
|
||||
armClient: armClient,
|
||||
rateLimiterReader: rateLimiterReader,
|
||||
rateLimiterWriter: rateLimiterWriter,
|
||||
subscriptionID: config.SubscriptionID,
|
||||
cloudName: config.CloudName,
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
// List gets compute.VirtualMachineSizeListResult.
|
||||
func (c *Client) List(ctx context.Context, location string) (compute.VirtualMachineSizeListResult, *retry.Error) {
|
||||
mc := metrics.NewMetricContext("vmsizes", "list", "", c.subscriptionID, "")
|
||||
|
||||
// Report errors if the client is rate limited.
|
||||
if !c.rateLimiterReader.TryAccept() {
|
||||
mc.RateLimitedCount()
|
||||
return compute.VirtualMachineSizeListResult{}, retry.GetRateLimitError(false, "VMSizesList")
|
||||
}
|
||||
|
||||
// Report errors if the client is throttled.
|
||||
if c.RetryAfterReader.After(time.Now()) {
|
||||
mc.ThrottledCount()
|
||||
rerr := retry.GetThrottlingError("VMSizesList", "client throttled", c.RetryAfterReader)
|
||||
return compute.VirtualMachineSizeListResult{}, rerr
|
||||
}
|
||||
|
||||
result, rerr := c.listVirtualMachineSizes(ctx, location)
|
||||
mc.Observe(rerr)
|
||||
if rerr != nil {
|
||||
if rerr.IsThrottled() {
|
||||
// Update RetryAfterReader so that no more requests would be sent until RetryAfter expires.
|
||||
c.RetryAfterReader = rerr.RetryAfter
|
||||
}
|
||||
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// listVirtualMachineSizes gets compute.VirtualMachineSizeListResult.
|
||||
func (c *Client) listVirtualMachineSizes(ctx context.Context, location string) (compute.VirtualMachineSizeListResult, *retry.Error) {
|
||||
resourceID := fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Compute/locations/%s/vmSizes",
|
||||
autorest.Encode("path", c.subscriptionID),
|
||||
autorest.Encode("path", location),
|
||||
)
|
||||
|
||||
result := compute.VirtualMachineSizeListResult{}
|
||||
response, rerr := c.armClient.GetResource(ctx, resourceID, "")
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmsize.list.request", resourceID, rerr.Error())
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
err := autorest.Respond(
|
||||
response,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "vmsize.list.respond", resourceID, err)
|
||||
return result, retry.GetError(response, err)
|
||||
}
|
||||
|
||||
result.Response = autorest.Response{Response: response}
|
||||
return result, nil
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmsizeclient/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmsizeclient/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package vmsizeclient implements the client for VirtualMachineSizes.
|
||||
package vmsizeclient // import "sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmsizeclient"
|
||||
40
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmsizeclient/interface.go
generated
vendored
Normal file
40
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmsizeclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package vmsizeclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-12-01/compute"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
const (
|
||||
// APIVersion is the API version for compute.
|
||||
APIVersion = "2020-12-01"
|
||||
// AzureStackCloudAPIVersion is the API version for Azure Stack
|
||||
AzureStackCloudAPIVersion = "2017-12-01"
|
||||
// AzureStackCloudName is the cloud name of Azure Stack
|
||||
AzureStackCloudName = "AZURESTACKCLOUD"
|
||||
)
|
||||
|
||||
// Interface is the client interface for VirtualMachineSizes.
|
||||
// Don't forget to run "hack/update-mock-clients.sh" command to generate the mock client.
|
||||
type Interface interface {
|
||||
// List gets compute.VirtualMachineSizeListResult.
|
||||
List(ctx context.Context, location string) (result compute.VirtualMachineSizeListResult, rerr *retry.Error)
|
||||
}
|
||||
134
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/zoneclient/azure_zoneclient.go
generated
vendored
Normal file
134
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/zoneclient/azure_zoneclient.go
generated
vendored
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package zoneclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
azclients "sigs.k8s.io/cloud-provider-azure/pkg/azureclients"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/armclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
var _ Interface = &Client{}
|
||||
|
||||
type resourceTypeMetadata struct {
|
||||
ResourceType string `json:"resourceType"`
|
||||
ZoneMappings []zoneMappings `json:"zoneMappings"`
|
||||
}
|
||||
|
||||
type zoneMappings struct {
|
||||
Location string `json:"location"`
|
||||
Zones []string `json:"zones"`
|
||||
}
|
||||
|
||||
type providerListDataProperty struct {
|
||||
ID string `json:"id"`
|
||||
ResourceTypes []resourceTypeMetadata `json:"resourceTypes"`
|
||||
}
|
||||
|
||||
type providerListData struct {
|
||||
ProviderListDataProperties []providerListDataProperty `json:"value"`
|
||||
}
|
||||
|
||||
// Client implements zone client Interface.
|
||||
type Client struct {
|
||||
armClient armclient.Interface
|
||||
subscriptionID string
|
||||
cloudName string
|
||||
}
|
||||
|
||||
// New creates a new zone client with ratelimiting.
|
||||
func New(config *azclients.ClientConfig) *Client {
|
||||
baseURI := config.ResourceManagerEndpoint
|
||||
authorizer := config.Authorizer
|
||||
apiVersion := APIVersion
|
||||
if strings.EqualFold(config.CloudName, AzureStackCloudName) && !config.DisableAzureStackCloud {
|
||||
apiVersion = AzureStackCloudAPIVersion
|
||||
}
|
||||
|
||||
armClient := armclient.New(authorizer, *config, baseURI, apiVersion)
|
||||
client := &Client{
|
||||
armClient: armClient,
|
||||
subscriptionID: config.SubscriptionID,
|
||||
cloudName: config.CloudName,
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
// GetZones gets the region-zone map for the subscription specified
|
||||
func (c *Client) GetZones(ctx context.Context, subscriptionID string) (map[string][]string, *retry.Error) {
|
||||
result, rerr := c.getZones(ctx, subscriptionID)
|
||||
if rerr != nil {
|
||||
|
||||
return result, rerr
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// getZones gets the region-zone map for the subscription specified
|
||||
func (c *Client) getZones(ctx context.Context, subscriptionID string) (map[string][]string, *retry.Error) {
|
||||
resourceID := armclient.GetProviderResourcesListID(subscriptionID)
|
||||
|
||||
response, rerr := c.armClient.GetResource(ctx, resourceID, "")
|
||||
defer c.armClient.CloseResponse(ctx, response)
|
||||
if rerr != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "zone.get.request", resourceID, rerr.Error())
|
||||
return nil, rerr
|
||||
}
|
||||
|
||||
result := providerListData{}
|
||||
err := autorest.Respond(
|
||||
response,
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result))
|
||||
if err != nil {
|
||||
klog.V(5).Infof("Received error in %s: resourceID: %s, error: %s", "zone.get.respond", resourceID, err)
|
||||
return nil, retry.GetError(response, err)
|
||||
}
|
||||
|
||||
regionZoneMap := make(map[string][]string)
|
||||
expectedID := fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Compute", subscriptionID)
|
||||
if len(result.ProviderListDataProperties) != 0 {
|
||||
for _, property := range result.ProviderListDataProperties {
|
||||
if strings.EqualFold(property.ID, expectedID) {
|
||||
for _, resourceType := range property.ResourceTypes {
|
||||
if strings.EqualFold(resourceType.ResourceType, "virtualMachines") {
|
||||
if len(resourceType.ZoneMappings) != 0 {
|
||||
for _, zoneMapping := range resourceType.ZoneMappings {
|
||||
location := strings.ToLower(strings.ReplaceAll(zoneMapping.Location, " ", ""))
|
||||
regionZoneMap[location] = zoneMapping.Zones
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return regionZoneMap, nil
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/zoneclient/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/zoneclient/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package zoneclient implements the client for ARM.
|
||||
package zoneclient // import "sigs.k8s.io/cloud-provider-azure/pkg/azureclients/zoneclient"
|
||||
38
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/zoneclient/interface.go
generated
vendored
Normal file
38
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/azureclients/zoneclient/interface.go
generated
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package zoneclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
const (
|
||||
// APIVersion is the API version for provider list api.
|
||||
APIVersion = "2020-06-01"
|
||||
// AzureStackCloudAPIVersion is the API version for Azure Stack
|
||||
AzureStackCloudAPIVersion = "2019-07-01"
|
||||
// AzureStackCloudName is the cloud name of Azure Stack
|
||||
AzureStackCloudName = "AZURESTACKCLOUD"
|
||||
)
|
||||
|
||||
// Interface is the client interface for ARM.
|
||||
// Don't forget to run "hack/update-mock-clients.sh" command to generate the mock client.
|
||||
type Interface interface {
|
||||
GetZones(ctx context.Context, subscriptionID string) (map[string][]string, *retry.Error)
|
||||
}
|
||||
175
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/cache/azure_cache.go
generated
vendored
Normal file
175
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/cache/azure_cache.go
generated
vendored
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// AzureCacheReadType defines the read type for cache data
|
||||
type AzureCacheReadType int
|
||||
|
||||
const (
|
||||
// CacheReadTypeDefault returns data from cache if cache entry not expired
|
||||
// if cache entry expired, then it will refetch the data using getter
|
||||
// save the entry in cache and then return
|
||||
CacheReadTypeDefault AzureCacheReadType = iota
|
||||
// CacheReadTypeUnsafe returns data from cache even if the cache entry is
|
||||
// active/expired. If entry doesn't exist in cache, then data is fetched
|
||||
// using getter, saved in cache and returned
|
||||
CacheReadTypeUnsafe
|
||||
// CacheReadTypeForceRefresh force refreshes the cache even if the cache entry
|
||||
// is not expired
|
||||
CacheReadTypeForceRefresh
|
||||
)
|
||||
|
||||
// GetFunc defines a getter function for timedCache.
|
||||
type GetFunc func(key string) (interface{}, error)
|
||||
|
||||
// AzureCacheEntry is the internal structure stores inside TTLStore.
|
||||
type AzureCacheEntry struct {
|
||||
Key string
|
||||
Data interface{}
|
||||
|
||||
// The lock to ensure not updating same entry simultaneously.
|
||||
Lock sync.Mutex
|
||||
// time when entry was fetched and created
|
||||
CreatedOn time.Time
|
||||
}
|
||||
|
||||
// cacheKeyFunc defines the key function required in TTLStore.
|
||||
func cacheKeyFunc(obj interface{}) (string, error) {
|
||||
return obj.(*AzureCacheEntry).Key, nil
|
||||
}
|
||||
|
||||
// TimedCache is a cache with TTL.
|
||||
type TimedCache struct {
|
||||
Store cache.Store
|
||||
Lock sync.Mutex
|
||||
Getter GetFunc
|
||||
TTL time.Duration
|
||||
}
|
||||
|
||||
// NewTimedcache creates a new TimedCache.
|
||||
func NewTimedcache(ttl time.Duration, getter GetFunc) (*TimedCache, error) {
|
||||
if getter == nil {
|
||||
return nil, fmt.Errorf("getter is not provided")
|
||||
}
|
||||
|
||||
return &TimedCache{
|
||||
Getter: getter,
|
||||
// switch to using NewStore instead of NewTTLStore so that we can
|
||||
// reuse entries for calls that are fine with reading expired/stalled data.
|
||||
// with NewTTLStore, entries are not returned if they have already expired.
|
||||
Store: cache.NewStore(cacheKeyFunc),
|
||||
TTL: ttl,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// getInternal returns AzureCacheEntry by key. If the key is not cached yet,
|
||||
// it returns a AzureCacheEntry with nil data.
|
||||
func (t *TimedCache) getInternal(key string) (*AzureCacheEntry, error) {
|
||||
entry, exists, err := t.Store.GetByKey(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// if entry exists, return the entry
|
||||
if exists {
|
||||
return entry.(*AzureCacheEntry), nil
|
||||
}
|
||||
|
||||
// lock here to ensure if entry doesn't exist, we add a new entry
|
||||
// avoiding overwrites
|
||||
t.Lock.Lock()
|
||||
defer t.Lock.Unlock()
|
||||
|
||||
// Another goroutine might have written the same key.
|
||||
entry, exists, err = t.Store.GetByKey(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if exists {
|
||||
return entry.(*AzureCacheEntry), nil
|
||||
}
|
||||
|
||||
// Still not found, add new entry with nil data.
|
||||
// Note the data will be filled later by getter.
|
||||
newEntry := &AzureCacheEntry{
|
||||
Key: key,
|
||||
Data: nil,
|
||||
}
|
||||
_ = t.Store.Add(newEntry)
|
||||
return newEntry, nil
|
||||
}
|
||||
|
||||
// Get returns the requested item by key.
|
||||
func (t *TimedCache) Get(key string, crt AzureCacheReadType) (interface{}, error) {
|
||||
entry, err := t.getInternal(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
entry.Lock.Lock()
|
||||
defer entry.Lock.Unlock()
|
||||
|
||||
// entry exists and if cache is not force refreshed
|
||||
if entry.Data != nil && crt != CacheReadTypeForceRefresh {
|
||||
// allow unsafe read, so return data even if expired
|
||||
if crt == CacheReadTypeUnsafe {
|
||||
return entry.Data, nil
|
||||
}
|
||||
// if cached data is not expired, return cached data
|
||||
if crt == CacheReadTypeDefault && time.Since(entry.CreatedOn) < t.TTL {
|
||||
return entry.Data, nil
|
||||
}
|
||||
}
|
||||
// Data is not cached yet, cache data is expired or requested force refresh
|
||||
// cache it by getter. entry is locked before getting to ensure concurrent
|
||||
// gets don't result in multiple ARM calls.
|
||||
data, err := t.Getter(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// set the data in cache and also set the last update time
|
||||
// to now as the data was recently fetched
|
||||
entry.Data = data
|
||||
entry.CreatedOn = time.Now().UTC()
|
||||
|
||||
return entry.Data, nil
|
||||
}
|
||||
|
||||
// Delete removes an item from the cache.
|
||||
func (t *TimedCache) Delete(key string) error {
|
||||
return t.Store.Delete(&AzureCacheEntry{
|
||||
Key: key,
|
||||
})
|
||||
}
|
||||
|
||||
// Set sets the data cache for the key.
|
||||
// It is only used for testing.
|
||||
func (t *TimedCache) Set(key string, data interface{}) {
|
||||
_ = t.Store.Add(&AzureCacheEntry{
|
||||
Key: key,
|
||||
Data: data,
|
||||
CreatedOn: time.Now().UTC(),
|
||||
})
|
||||
}
|
||||
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/cache/doc.go
generated
vendored
Normal file
18
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/cache/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package cache is an implementation of Azure caches.
|
||||
package cache // import "sigs.k8s.io/cloud-provider-azure/pkg/cache"
|
||||
1222
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure.go
generated
vendored
Normal file
1222
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
543
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_backoff.go
generated
vendored
Normal file
543
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_backoff.go
generated
vendored
Normal file
|
|
@ -0,0 +1,543 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-12-01/compute"
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
azcache "sigs.k8s.io/cloud-provider-azure/pkg/cache"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/consts"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
var (
|
||||
pipErrorMessageRE = regexp.MustCompile(`(?:.*)/subscriptions/(?:.*)/resourceGroups/(.*)/providers/Microsoft.Network/publicIPAddresses/([^\s]+)(?:.*)`)
|
||||
)
|
||||
|
||||
// RequestBackoff if backoff is disabled in cloud provider it
|
||||
// returns a new Backoff object steps = 1
|
||||
// This is to make sure that the requested command executes
|
||||
// at least once
|
||||
func (az *Cloud) RequestBackoff() (resourceRequestBackoff wait.Backoff) {
|
||||
if az.CloudProviderBackoff {
|
||||
return az.ResourceRequestBackoff
|
||||
}
|
||||
resourceRequestBackoff = wait.Backoff{
|
||||
Steps: 1,
|
||||
}
|
||||
return resourceRequestBackoff
|
||||
}
|
||||
|
||||
// Event creates a event for the specified object.
|
||||
func (az *Cloud) Event(obj runtime.Object, eventType, reason, message string) {
|
||||
if obj != nil && reason != "" {
|
||||
az.eventRecorder.Event(obj, eventType, reason, message)
|
||||
}
|
||||
}
|
||||
|
||||
// GetVirtualMachineWithRetry invokes az.getVirtualMachine with exponential backoff retry
|
||||
func (az *Cloud) GetVirtualMachineWithRetry(name types.NodeName, crt azcache.AzureCacheReadType) (compute.VirtualMachine, error) {
|
||||
var machine compute.VirtualMachine
|
||||
var retryErr error
|
||||
err := wait.ExponentialBackoff(az.RequestBackoff(), func() (bool, error) {
|
||||
machine, retryErr = az.getVirtualMachine(name, crt)
|
||||
if errors.Is(retryErr, cloudprovider.InstanceNotFound) {
|
||||
return true, cloudprovider.InstanceNotFound
|
||||
}
|
||||
if retryErr != nil {
|
||||
klog.Errorf("GetVirtualMachineWithRetry(%s): backoff failure, will retry, err=%v", name, retryErr)
|
||||
return false, nil
|
||||
}
|
||||
klog.V(2).Infof("GetVirtualMachineWithRetry(%s): backoff success", name)
|
||||
return true, nil
|
||||
})
|
||||
if errors.Is(err, wait.ErrWaitTimeout) {
|
||||
err = retryErr
|
||||
}
|
||||
return machine, err
|
||||
}
|
||||
|
||||
// ListVirtualMachines invokes az.VirtualMachinesClient.List with exponential backoff retry
|
||||
func (az *Cloud) ListVirtualMachines(resourceGroup string) ([]compute.VirtualMachine, error) {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
allNodes, rerr := az.VirtualMachinesClient.List(ctx, resourceGroup)
|
||||
if rerr != nil {
|
||||
klog.Errorf("VirtualMachinesClient.List(%v) failure with err=%v", resourceGroup, rerr)
|
||||
return nil, rerr.Error()
|
||||
}
|
||||
klog.V(2).Infof("VirtualMachinesClient.List(%v) success", resourceGroup)
|
||||
return allNodes, nil
|
||||
}
|
||||
|
||||
// getPrivateIPsForMachine is wrapper for optional backoff getting private ips
|
||||
// list of a node by name
|
||||
func (az *Cloud) getPrivateIPsForMachine(nodeName types.NodeName) ([]string, error) {
|
||||
return az.getPrivateIPsForMachineWithRetry(nodeName)
|
||||
}
|
||||
|
||||
func (az *Cloud) getPrivateIPsForMachineWithRetry(nodeName types.NodeName) ([]string, error) {
|
||||
var privateIPs []string
|
||||
err := wait.ExponentialBackoff(az.RequestBackoff(), func() (bool, error) {
|
||||
var retryErr error
|
||||
privateIPs, retryErr = az.VMSet.GetPrivateIPsByNodeName(string(nodeName))
|
||||
if retryErr != nil {
|
||||
// won't retry since the instance doesn't exist on Azure.
|
||||
if errors.Is(retryErr, cloudprovider.InstanceNotFound) {
|
||||
return true, retryErr
|
||||
}
|
||||
klog.Errorf("GetPrivateIPsByNodeName(%s): backoff failure, will retry,err=%v", nodeName, retryErr)
|
||||
return false, nil
|
||||
}
|
||||
klog.V(3).Infof("GetPrivateIPsByNodeName(%s): backoff success", nodeName)
|
||||
return true, nil
|
||||
})
|
||||
return privateIPs, err
|
||||
}
|
||||
|
||||
func (az *Cloud) getIPForMachine(nodeName types.NodeName) (string, string, error) {
|
||||
return az.GetIPForMachineWithRetry(nodeName)
|
||||
}
|
||||
|
||||
// GetIPForMachineWithRetry invokes az.getIPForMachine with exponential backoff retry
|
||||
func (az *Cloud) GetIPForMachineWithRetry(name types.NodeName) (string, string, error) {
|
||||
var ip, publicIP string
|
||||
err := wait.ExponentialBackoff(az.RequestBackoff(), func() (bool, error) {
|
||||
var retryErr error
|
||||
ip, publicIP, retryErr = az.VMSet.GetIPByNodeName(string(name))
|
||||
if retryErr != nil {
|
||||
klog.Errorf("GetIPForMachineWithRetry(%s): backoff failure, will retry,err=%v", name, retryErr)
|
||||
return false, nil
|
||||
}
|
||||
klog.V(3).Infof("GetIPForMachineWithRetry(%s): backoff success", name)
|
||||
return true, nil
|
||||
})
|
||||
return ip, publicIP, err
|
||||
}
|
||||
|
||||
// CreateOrUpdateSecurityGroup invokes az.SecurityGroupsClient.CreateOrUpdate with exponential backoff retry
|
||||
func (az *Cloud) CreateOrUpdateSecurityGroup(sg network.SecurityGroup) error {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
rerr := az.SecurityGroupsClient.CreateOrUpdate(ctx, az.SecurityGroupResourceGroup, *sg.Name, sg, to.String(sg.Etag))
|
||||
klog.V(10).Infof("SecurityGroupsClient.CreateOrUpdate(%s): end", *sg.Name)
|
||||
if rerr == nil {
|
||||
// Invalidate the cache right after updating
|
||||
_ = az.nsgCache.Delete(*sg.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
nsgJSON, _ := json.Marshal(sg)
|
||||
klog.Warningf("CreateOrUpdateSecurityGroup(%s) failed: %v, NSG request: %s", to.String(sg.Name), rerr.Error(), string(nsgJSON))
|
||||
|
||||
// Invalidate the cache because ETAG precondition mismatch.
|
||||
if rerr.HTTPStatusCode == http.StatusPreconditionFailed {
|
||||
klog.V(3).Infof("SecurityGroup cache for %s is cleanup because of http.StatusPreconditionFailed", *sg.Name)
|
||||
_ = az.nsgCache.Delete(*sg.Name)
|
||||
}
|
||||
|
||||
// Invalidate the cache because another new operation has canceled the current request.
|
||||
if strings.Contains(strings.ToLower(rerr.Error().Error()), consts.OperationCanceledErrorMessage) {
|
||||
klog.V(3).Infof("SecurityGroup cache for %s is cleanup because CreateOrUpdateSecurityGroup is canceled by another operation", *sg.Name)
|
||||
_ = az.nsgCache.Delete(*sg.Name)
|
||||
}
|
||||
|
||||
return rerr.Error()
|
||||
}
|
||||
|
||||
func cleanupSubnetInFrontendIPConfigurations(lb *network.LoadBalancer) network.LoadBalancer {
|
||||
if lb.LoadBalancerPropertiesFormat == nil || lb.FrontendIPConfigurations == nil {
|
||||
return *lb
|
||||
}
|
||||
|
||||
frontendIPConfigurations := *lb.FrontendIPConfigurations
|
||||
for i := range frontendIPConfigurations {
|
||||
config := frontendIPConfigurations[i]
|
||||
if config.FrontendIPConfigurationPropertiesFormat != nil &&
|
||||
config.Subnet != nil &&
|
||||
config.Subnet.ID != nil {
|
||||
subnet := network.Subnet{
|
||||
ID: config.Subnet.ID,
|
||||
}
|
||||
if config.Subnet.Name != nil {
|
||||
subnet.Name = config.FrontendIPConfigurationPropertiesFormat.Subnet.Name
|
||||
}
|
||||
config.FrontendIPConfigurationPropertiesFormat.Subnet = &subnet
|
||||
frontendIPConfigurations[i] = config
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
lb.FrontendIPConfigurations = &frontendIPConfigurations
|
||||
return *lb
|
||||
}
|
||||
|
||||
// CreateOrUpdateLB invokes az.LoadBalancerClient.CreateOrUpdate with exponential backoff retry
|
||||
func (az *Cloud) CreateOrUpdateLB(service *v1.Service, lb network.LoadBalancer) error {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
lb = cleanupSubnetInFrontendIPConfigurations(&lb)
|
||||
|
||||
rgName := az.getLoadBalancerResourceGroup()
|
||||
rerr := az.LoadBalancerClient.CreateOrUpdate(ctx, rgName, to.String(lb.Name), lb, to.String(lb.Etag))
|
||||
klog.V(10).Infof("LoadBalancerClient.CreateOrUpdate(%s): end", *lb.Name)
|
||||
if rerr == nil {
|
||||
// Invalidate the cache right after updating
|
||||
_ = az.lbCache.Delete(*lb.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
lbJSON, _ := json.Marshal(lb)
|
||||
klog.Warningf("LoadBalancerClient.CreateOrUpdate(%s) failed: %v, LoadBalancer request: %s", to.String(lb.Name), rerr.Error(), string(lbJSON))
|
||||
|
||||
// Invalidate the cache because ETAG precondition mismatch.
|
||||
if rerr.HTTPStatusCode == http.StatusPreconditionFailed {
|
||||
klog.V(3).Infof("LoadBalancer cache for %s is cleanup because of http.StatusPreconditionFailed", to.String(lb.Name))
|
||||
_ = az.lbCache.Delete(*lb.Name)
|
||||
}
|
||||
|
||||
retryErrorMessage := rerr.Error().Error()
|
||||
// Invalidate the cache because another new operation has canceled the current request.
|
||||
if strings.Contains(strings.ToLower(retryErrorMessage), consts.OperationCanceledErrorMessage) {
|
||||
klog.V(3).Infof("LoadBalancer cache for %s is cleanup because CreateOrUpdate is canceled by another operation", to.String(lb.Name))
|
||||
_ = az.lbCache.Delete(*lb.Name)
|
||||
}
|
||||
|
||||
// The LB update may fail because the referenced PIP is not in the Succeeded provisioning state
|
||||
if strings.Contains(strings.ToLower(retryErrorMessage), strings.ToLower(consts.ReferencedResourceNotProvisionedMessageCode)) {
|
||||
matches := pipErrorMessageRE.FindStringSubmatch(retryErrorMessage)
|
||||
if len(matches) != 3 {
|
||||
klog.Errorf("Failed to parse the retry error message %s", retryErrorMessage)
|
||||
return rerr.Error()
|
||||
}
|
||||
pipRG, pipName := matches[1], matches[2]
|
||||
klog.V(3).Infof("The public IP %s referenced by load balancer %s is not in Succeeded provisioning state, will try to update it", pipName, to.String(lb.Name))
|
||||
pip, _, err := az.getPublicIPAddress(pipRG, pipName)
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to get the public IP %s in resource group %s: %v", pipName, pipRG, err)
|
||||
return rerr.Error()
|
||||
}
|
||||
// Perform a dummy update to fix the provisioning state
|
||||
err = az.CreateOrUpdatePIP(service, pipRG, pip)
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to update the public IP %s in resource group %s: %v", pipName, pipRG, err)
|
||||
return rerr.Error()
|
||||
}
|
||||
// Invalidate the LB cache, return the error, and the controller manager
|
||||
// would retry the LB update in the next reconcile loop
|
||||
_ = az.lbCache.Delete(*lb.Name)
|
||||
}
|
||||
|
||||
return rerr.Error()
|
||||
}
|
||||
|
||||
func (az *Cloud) CreateOrUpdateLBBackendPool(lbName string, backendPool network.BackendAddressPool) error {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
klog.V(4).Infof("CreateOrUpdateLBBackendPool: updating backend pool %s in LB %s", to.String(backendPool.Name), lbName)
|
||||
rerr := az.LoadBalancerClient.CreateOrUpdateBackendPools(ctx, az.getLoadBalancerResourceGroup(), lbName, to.String(backendPool.Name), backendPool, to.String(backendPool.Etag))
|
||||
if rerr == nil {
|
||||
// Invalidate the cache right after updating
|
||||
_ = az.lbCache.Delete(lbName)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Invalidate the cache because ETAG precondition mismatch.
|
||||
if rerr.HTTPStatusCode == http.StatusPreconditionFailed {
|
||||
klog.V(3).Infof("LoadBalancer cache for %s is cleanup because of http.StatusPreconditionFailed", lbName)
|
||||
_ = az.lbCache.Delete(lbName)
|
||||
}
|
||||
|
||||
retryErrorMessage := rerr.Error().Error()
|
||||
// Invalidate the cache because another new operation has canceled the current request.
|
||||
if strings.Contains(strings.ToLower(retryErrorMessage), consts.OperationCanceledErrorMessage) {
|
||||
klog.V(3).Infof("LoadBalancer cache for %s is cleanup because CreateOrUpdate is canceled by another operation", lbName)
|
||||
_ = az.lbCache.Delete(lbName)
|
||||
}
|
||||
|
||||
return rerr.Error()
|
||||
}
|
||||
|
||||
// ListManagedLBs invokes az.LoadBalancerClient.List and filter out
|
||||
// those that are not managed by cloud provider azure or not associated to a managed VMSet.
|
||||
func (az *Cloud) ListManagedLBs(service *v1.Service, nodes []*v1.Node, clusterName string) ([]network.LoadBalancer, error) {
|
||||
allLBs, err := az.ListLB(service)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if allLBs == nil {
|
||||
klog.Warningf("ListManagedLBs: no LBs found")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// return early if wantLb=false
|
||||
if nodes == nil {
|
||||
return allLBs, nil
|
||||
}
|
||||
|
||||
agentPoolLBs := make([]network.LoadBalancer, 0)
|
||||
agentPoolVMSetNames, err := az.VMSet.GetAgentPoolVMSetNames(nodes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ListManagedLBs: failed to get agent pool vmSet names: %w", err)
|
||||
}
|
||||
|
||||
agentPoolVMSetNamesSet := sets.NewString()
|
||||
if agentPoolVMSetNames != nil && len(*agentPoolVMSetNames) > 0 {
|
||||
for _, vmSetName := range *agentPoolVMSetNames {
|
||||
klog.V(5).Infof("ListManagedLBs: found agent pool vmSet name %s", vmSetName)
|
||||
agentPoolVMSetNamesSet.Insert(strings.ToLower(vmSetName))
|
||||
}
|
||||
}
|
||||
|
||||
for _, lb := range allLBs {
|
||||
vmSetNameFromLBName := az.mapLoadBalancerNameToVMSet(to.String(lb.Name), clusterName)
|
||||
if strings.EqualFold(strings.TrimSuffix(to.String(lb.Name), consts.InternalLoadBalancerNameSuffix), clusterName) ||
|
||||
agentPoolVMSetNamesSet.Has(strings.ToLower(vmSetNameFromLBName)) {
|
||||
agentPoolLBs = append(agentPoolLBs, lb)
|
||||
klog.V(4).Infof("ListManagedLBs: found agent pool LB %s", to.String(lb.Name))
|
||||
}
|
||||
}
|
||||
|
||||
return agentPoolLBs, nil
|
||||
}
|
||||
|
||||
// ListLB invokes az.LoadBalancerClient.List with exponential backoff retry
|
||||
func (az *Cloud) ListLB(service *v1.Service) ([]network.LoadBalancer, error) {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
rgName := az.getLoadBalancerResourceGroup()
|
||||
allLBs, rerr := az.LoadBalancerClient.List(ctx, rgName)
|
||||
if rerr != nil {
|
||||
if rerr.IsNotFound() {
|
||||
return nil, nil
|
||||
}
|
||||
az.Event(service, v1.EventTypeWarning, "ListLoadBalancers", rerr.Error().Error())
|
||||
klog.Errorf("LoadBalancerClient.List(%v) failure with err=%v", rgName, rerr)
|
||||
return nil, rerr.Error()
|
||||
}
|
||||
klog.V(2).Infof("LoadBalancerClient.List(%v) success", rgName)
|
||||
return allLBs, nil
|
||||
}
|
||||
|
||||
// ListPIP list the PIP resources in the given resource group
|
||||
func (az *Cloud) ListPIP(service *v1.Service, pipResourceGroup string) ([]network.PublicIPAddress, error) {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
allPIPs, rerr := az.PublicIPAddressesClient.List(ctx, pipResourceGroup)
|
||||
if rerr != nil {
|
||||
if rerr.IsNotFound() {
|
||||
return nil, nil
|
||||
}
|
||||
az.Event(service, v1.EventTypeWarning, "ListPublicIPs", rerr.Error().Error())
|
||||
klog.Errorf("PublicIPAddressesClient.List(%v) failure with err=%v", pipResourceGroup, rerr)
|
||||
return nil, rerr.Error()
|
||||
}
|
||||
|
||||
klog.V(2).Infof("PublicIPAddressesClient.List(%v) success", pipResourceGroup)
|
||||
return allPIPs, nil
|
||||
}
|
||||
|
||||
// CreateOrUpdatePIP invokes az.PublicIPAddressesClient.CreateOrUpdate with exponential backoff retry
|
||||
func (az *Cloud) CreateOrUpdatePIP(service *v1.Service, pipResourceGroup string, pip network.PublicIPAddress) error {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
rerr := az.PublicIPAddressesClient.CreateOrUpdate(ctx, pipResourceGroup, to.String(pip.Name), pip)
|
||||
klog.V(10).Infof("PublicIPAddressesClient.CreateOrUpdate(%s, %s): end", pipResourceGroup, to.String(pip.Name))
|
||||
if rerr != nil {
|
||||
pipJSON, _ := json.Marshal(pip)
|
||||
klog.Warningf("PublicIPAddressesClient.CreateOrUpdate(%s, %s) failed: %s, PublicIP request: %s", pipResourceGroup, to.String(pip.Name), rerr.Error().Error(), string(pipJSON))
|
||||
az.Event(service, v1.EventTypeWarning, "CreateOrUpdatePublicIPAddress", rerr.Error().Error())
|
||||
return rerr.Error()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateOrUpdateInterface invokes az.PublicIPAddressesClient.CreateOrUpdate with exponential backoff retry
|
||||
func (az *Cloud) CreateOrUpdateInterface(service *v1.Service, nic network.Interface) error {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
rerr := az.InterfacesClient.CreateOrUpdate(ctx, az.ResourceGroup, *nic.Name, nic)
|
||||
klog.V(10).Infof("InterfacesClient.CreateOrUpdate(%s): end", *nic.Name)
|
||||
if rerr != nil {
|
||||
klog.Errorf("InterfacesClient.CreateOrUpdate(%s) failed: %s", *nic.Name, rerr.Error().Error())
|
||||
az.Event(service, v1.EventTypeWarning, "CreateOrUpdateInterface", rerr.Error().Error())
|
||||
return rerr.Error()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeletePublicIP invokes az.PublicIPAddressesClient.Delete with exponential backoff retry
|
||||
func (az *Cloud) DeletePublicIP(service *v1.Service, pipResourceGroup string, pipName string) error {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
rerr := az.PublicIPAddressesClient.Delete(ctx, pipResourceGroup, pipName)
|
||||
if rerr != nil {
|
||||
klog.Errorf("PublicIPAddressesClient.Delete(%s) failed: %s", pipName, rerr.Error().Error())
|
||||
az.Event(service, v1.EventTypeWarning, "DeletePublicIPAddress", rerr.Error().Error())
|
||||
|
||||
if strings.Contains(rerr.Error().Error(), consts.CannotDeletePublicIPErrorMessageCode) {
|
||||
klog.Warningf("DeletePublicIP for public IP %s failed with error %v, this is because other resources are referencing the public IP. The deletion of the service will continue.", pipName, rerr.Error())
|
||||
return nil
|
||||
}
|
||||
return rerr.Error()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteLB invokes az.LoadBalancerClient.Delete with exponential backoff retry
|
||||
func (az *Cloud) DeleteLB(service *v1.Service, lbName string) *retry.Error {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
rgName := az.getLoadBalancerResourceGroup()
|
||||
rerr := az.LoadBalancerClient.Delete(ctx, rgName, lbName)
|
||||
if rerr == nil {
|
||||
// Invalidate the cache right after updating
|
||||
_ = az.lbCache.Delete(lbName)
|
||||
return nil
|
||||
}
|
||||
|
||||
klog.Errorf("LoadBalancerClient.Delete(%s) failed: %s", lbName, rerr.Error().Error())
|
||||
az.Event(service, v1.EventTypeWarning, "DeleteLoadBalancer", rerr.Error().Error())
|
||||
return rerr
|
||||
}
|
||||
|
||||
// CreateOrUpdateRouteTable invokes az.RouteTablesClient.CreateOrUpdate with exponential backoff retry
|
||||
func (az *Cloud) CreateOrUpdateRouteTable(routeTable network.RouteTable) error {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
rerr := az.RouteTablesClient.CreateOrUpdate(ctx, az.RouteTableResourceGroup, az.RouteTableName, routeTable, to.String(routeTable.Etag))
|
||||
if rerr == nil {
|
||||
// Invalidate the cache right after updating
|
||||
_ = az.rtCache.Delete(*routeTable.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
rtJSON, _ := json.Marshal(routeTable)
|
||||
klog.Warningf("RouteTablesClient.CreateOrUpdate(%s) failed: %v, RouteTable request: %s", to.String(routeTable.Name), rerr.Error(), string(rtJSON))
|
||||
|
||||
// Invalidate the cache because etag mismatch.
|
||||
if rerr.HTTPStatusCode == http.StatusPreconditionFailed {
|
||||
klog.V(3).Infof("Route table cache for %s is cleanup because of http.StatusPreconditionFailed", *routeTable.Name)
|
||||
_ = az.rtCache.Delete(*routeTable.Name)
|
||||
}
|
||||
// Invalidate the cache because another new operation has canceled the current request.
|
||||
if strings.Contains(strings.ToLower(rerr.Error().Error()), consts.OperationCanceledErrorMessage) {
|
||||
klog.V(3).Infof("Route table cache for %s is cleanup because CreateOrUpdateRouteTable is canceled by another operation", *routeTable.Name)
|
||||
_ = az.rtCache.Delete(*routeTable.Name)
|
||||
}
|
||||
klog.Errorf("RouteTablesClient.CreateOrUpdate(%s) failed: %v", az.RouteTableName, rerr.Error())
|
||||
return rerr.Error()
|
||||
}
|
||||
|
||||
// CreateOrUpdateRoute invokes az.RoutesClient.CreateOrUpdate with exponential backoff retry
|
||||
func (az *Cloud) CreateOrUpdateRoute(route network.Route) error {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
rerr := az.RoutesClient.CreateOrUpdate(ctx, az.RouteTableResourceGroup, az.RouteTableName, *route.Name, route, to.String(route.Etag))
|
||||
klog.V(10).Infof("RoutesClient.CreateOrUpdate(%s): end", *route.Name)
|
||||
if rerr == nil {
|
||||
_ = az.rtCache.Delete(az.RouteTableName)
|
||||
return nil
|
||||
}
|
||||
|
||||
if rerr.HTTPStatusCode == http.StatusPreconditionFailed {
|
||||
klog.V(3).Infof("Route cache for %s is cleanup because of http.StatusPreconditionFailed", *route.Name)
|
||||
_ = az.rtCache.Delete(az.RouteTableName)
|
||||
}
|
||||
// Invalidate the cache because another new operation has canceled the current request.
|
||||
if strings.Contains(strings.ToLower(rerr.Error().Error()), consts.OperationCanceledErrorMessage) {
|
||||
klog.V(3).Infof("Route cache for %s is cleanup because CreateOrUpdateRouteTable is canceled by another operation", *route.Name)
|
||||
_ = az.rtCache.Delete(az.RouteTableName)
|
||||
}
|
||||
return rerr.Error()
|
||||
}
|
||||
|
||||
// DeleteRouteWithName invokes az.RoutesClient.CreateOrUpdate with exponential backoff retry
|
||||
func (az *Cloud) DeleteRouteWithName(routeName string) error {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
rerr := az.RoutesClient.Delete(ctx, az.RouteTableResourceGroup, az.RouteTableName, routeName)
|
||||
klog.V(10).Infof("RoutesClient.Delete(%s,%s): end", az.RouteTableName, routeName)
|
||||
if rerr == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
klog.Errorf("RoutesClient.Delete(%s, %s) failed: %v", az.RouteTableName, routeName, rerr.Error())
|
||||
return rerr.Error()
|
||||
}
|
||||
|
||||
// CreateOrUpdateVMSS invokes az.VirtualMachineScaleSetsClient.Update().
|
||||
func (az *Cloud) CreateOrUpdateVMSS(resourceGroupName string, VMScaleSetName string, parameters compute.VirtualMachineScaleSet) *retry.Error {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
// When vmss is being deleted, CreateOrUpdate API would report "the vmss is being deleted" error.
|
||||
// Since it is being deleted, we shouldn't send more CreateOrUpdate requests for it.
|
||||
klog.V(3).Infof("CreateOrUpdateVMSS: verify the status of the vmss being created or updated")
|
||||
vmss, rerr := az.VirtualMachineScaleSetsClient.Get(ctx, resourceGroupName, VMScaleSetName)
|
||||
if rerr != nil {
|
||||
klog.Errorf("CreateOrUpdateVMSS: error getting vmss(%s): %v", VMScaleSetName, rerr)
|
||||
return rerr
|
||||
}
|
||||
if vmss.ProvisioningState != nil && strings.EqualFold(*vmss.ProvisioningState, consts.VirtualMachineScaleSetsDeallocating) {
|
||||
klog.V(3).Infof("CreateOrUpdateVMSS: found vmss %s being deleted, skipping", VMScaleSetName)
|
||||
return nil
|
||||
}
|
||||
|
||||
rerr = az.VirtualMachineScaleSetsClient.CreateOrUpdate(ctx, resourceGroupName, VMScaleSetName, parameters)
|
||||
klog.V(10).Infof("UpdateVmssVMWithRetry: VirtualMachineScaleSetsClient.CreateOrUpdate(%s): end", VMScaleSetName)
|
||||
if rerr != nil {
|
||||
klog.Errorf("CreateOrUpdateVMSS: error CreateOrUpdate vmss(%s): %v", VMScaleSetName, rerr)
|
||||
return rerr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
90
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_config.go
generated
vendored
Normal file
90
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_config.go
generated
vendored
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
// The config type for Azure cloud provider secret. Supported values are:
|
||||
// * file : The values are read from local cloud-config file.
|
||||
// * secret : The values from secret would override all configures from local cloud-config file.
|
||||
// * merge : The values from secret would override only configurations that are explicitly set in the secret. This is the default value.
|
||||
type cloudConfigType string
|
||||
|
||||
const (
|
||||
cloudConfigTypeFile cloudConfigType = "file"
|
||||
cloudConfigTypeSecret cloudConfigType = "secret"
|
||||
cloudConfigTypeMerge cloudConfigType = "merge"
|
||||
)
|
||||
|
||||
// InitializeCloudFromSecret initializes Azure cloud provider from Kubernetes secret.
|
||||
func (az *Cloud) InitializeCloudFromSecret() error {
|
||||
config, err := az.GetConfigFromSecret()
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to get cloud-config from secret: %v", err)
|
||||
return fmt.Errorf("InitializeCloudFromSecret: failed to get cloud config from secret %s/%s: %w", az.SecretNamespace, az.SecretName, err)
|
||||
}
|
||||
|
||||
if config == nil {
|
||||
// Skip re-initialization if the config is not override.
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := az.InitializeCloudFromConfig(config, true, true); err != nil {
|
||||
klog.Errorf("Failed to initialize Azure cloud provider: %v", err)
|
||||
return fmt.Errorf("InitializeCloudFromSecret: failed to initialize Azure cloud provider: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (az *Cloud) GetConfigFromSecret() (*Config, error) {
|
||||
// Read config from file and no override, return nil.
|
||||
if az.Config.CloudConfigType == cloudConfigTypeFile {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
secret, err := az.KubeClient.CoreV1().Secrets(az.SecretNamespace).Get(context.TODO(), az.SecretName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get secret %s/%s: %w", az.SecretNamespace, az.SecretName, err)
|
||||
}
|
||||
|
||||
cloudConfigData, ok := secret.Data[az.CloudConfigKey]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cloud-config is not set in the secret (%s/%s)", az.SecretNamespace, az.SecretName)
|
||||
}
|
||||
|
||||
config := Config{}
|
||||
if az.Config.CloudConfigType == "" || az.Config.CloudConfigType == cloudConfigTypeMerge {
|
||||
// Merge cloud config, set default value to existing config.
|
||||
config = az.Config
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(cloudConfigData, &config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse Azure cloud-config: %w", err)
|
||||
}
|
||||
|
||||
return &config, nil
|
||||
}
|
||||
657
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_controller_common.go
generated
vendored
Normal file
657
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_controller_common.go
generated
vendored
Normal file
|
|
@ -0,0 +1,657 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-12-01/compute"
|
||||
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
kwait "k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
volerr "k8s.io/cloud-provider/volume/errors"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
azcache "sigs.k8s.io/cloud-provider-azure/pkg/cache"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/consts"
|
||||
)
|
||||
|
||||
const (
|
||||
// Disk Caching is not supported for disks 4 TiB and larger
|
||||
// https://docs.microsoft.com/en-us/azure/virtual-machines/premium-storage-performance#disk-caching
|
||||
diskCachingLimit = 4096 // GiB
|
||||
|
||||
maxLUN = 64 // max number of LUNs per VM
|
||||
errStatusCode400 = "statuscode=400"
|
||||
errInvalidParameter = `code="invalidparameter"`
|
||||
errTargetInstanceIds = `target="instanceids"`
|
||||
sourceSnapshot = "snapshot"
|
||||
sourceVolume = "volume"
|
||||
attachDiskMapKeySuffix = "attachdiskmap"
|
||||
detachDiskMapKeySuffix = "detachdiskmap"
|
||||
|
||||
// WriteAcceleratorEnabled support for Azure Write Accelerator on Azure Disks
|
||||
// https://docs.microsoft.com/azure/virtual-machines/windows/how-to-enable-write-accelerator
|
||||
WriteAcceleratorEnabled = "writeacceleratorenabled"
|
||||
|
||||
// see https://docs.microsoft.com/en-us/rest/api/compute/disks/createorupdate#create-a-managed-disk-by-copying-a-snapshot.
|
||||
diskSnapshotPath = "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/snapshots/%s"
|
||||
|
||||
// see https://docs.microsoft.com/en-us/rest/api/compute/disks/createorupdate#create-a-managed-disk-from-an-existing-managed-disk-in-the-same-or-different-subscription.
|
||||
managedDiskPath = "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/disks/%s"
|
||||
)
|
||||
|
||||
var defaultBackOff = kwait.Backoff{
|
||||
Steps: 20,
|
||||
Duration: 2 * time.Second,
|
||||
Factor: 1.5,
|
||||
Jitter: 0.0,
|
||||
}
|
||||
|
||||
var (
|
||||
managedDiskPathRE = regexp.MustCompile(`.*/subscriptions/(?:.*)/resourceGroups/(?:.*)/providers/Microsoft.Compute/disks/(.+)`)
|
||||
diskSnapshotPathRE = regexp.MustCompile(`.*/subscriptions/(?:.*)/resourceGroups/(?:.*)/providers/Microsoft.Compute/snapshots/(.+)`)
|
||||
)
|
||||
|
||||
type controllerCommon struct {
|
||||
subscriptionID string
|
||||
location string
|
||||
extendedLocation *ExtendedLocation
|
||||
storageEndpointSuffix string
|
||||
resourceGroup string
|
||||
diskStateMap sync.Map // <diskURI, attaching/detaching state>
|
||||
lockMap *lockMap
|
||||
cloud *Cloud
|
||||
// disk queue that is waiting for attach or detach on specific node
|
||||
// <nodeName, map<diskURI, *AttachDiskOptions/DetachDiskOptions>>
|
||||
attachDiskMap sync.Map
|
||||
detachDiskMap sync.Map
|
||||
// attach/detach disk rate limiter
|
||||
diskOpRateLimiter flowcontrol.RateLimiter
|
||||
}
|
||||
|
||||
// AttachDiskOptions attach disk options
|
||||
type AttachDiskOptions struct {
|
||||
cachingMode compute.CachingTypes
|
||||
diskName string
|
||||
diskEncryptionSetID string
|
||||
writeAcceleratorEnabled bool
|
||||
lun int32
|
||||
}
|
||||
|
||||
// ExtendedLocation contains additional info about the location of resources.
|
||||
type ExtendedLocation struct {
|
||||
// Name - The name of the extended location.
|
||||
Name string `json:"name,omitempty"`
|
||||
// Type - The type of the extended location.
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// getNodeVMSet gets the VMSet interface based on config.VMType and the real virtual machine type.
|
||||
func (c *controllerCommon) getNodeVMSet(nodeName types.NodeName, crt azcache.AzureCacheReadType) (VMSet, error) {
|
||||
// 1. vmType is standard, return cloud.VMSet directly.
|
||||
if c.cloud.VMType == consts.VMTypeStandard {
|
||||
return c.cloud.VMSet, nil
|
||||
}
|
||||
|
||||
// 2. vmType is Virtual Machine Scale Set (vmss), convert vmSet to ScaleSet.
|
||||
ss, ok := c.cloud.VMSet.(*ScaleSet)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("error of converting vmSet (%q) to ScaleSet with vmType %q", c.cloud.VMSet, c.cloud.VMType)
|
||||
}
|
||||
|
||||
// 3. If the node is managed by availability set, then return ss.availabilitySet.
|
||||
managedByAS, err := ss.isNodeManagedByAvailabilitySet(mapNodeNameToVMName(nodeName), crt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if managedByAS {
|
||||
// vm is managed by availability set.
|
||||
return ss.availabilitySet, nil
|
||||
}
|
||||
|
||||
// 4. Node is managed by vmss
|
||||
return ss, nil
|
||||
}
|
||||
|
||||
// AttachDisk attaches a disk to vm
|
||||
// parameter async indicates whether allow multiple batch disk attach on one node in parallel
|
||||
// return (lun, error)
|
||||
func (c *controllerCommon) AttachDisk(ctx context.Context, async bool, diskName, diskURI string, nodeName types.NodeName,
|
||||
cachingMode compute.CachingTypes, disk *compute.Disk) (int32, error) {
|
||||
diskEncryptionSetID := ""
|
||||
writeAcceleratorEnabled := false
|
||||
|
||||
// there is possibility that disk is nil when GetDisk is throttled
|
||||
// don't check disk state when GetDisk is throttled
|
||||
if disk != nil {
|
||||
if disk.ManagedBy != nil && (disk.MaxShares == nil || *disk.MaxShares <= 1) {
|
||||
vmset, err := c.getNodeVMSet(nodeName, azcache.CacheReadTypeUnsafe)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
attachedNode, err := vmset.GetNodeNameByProviderID(*disk.ManagedBy)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
if strings.EqualFold(string(nodeName), string(attachedNode)) {
|
||||
klog.Warningf("volume %q is actually attached to current node %q, invalidate vm cache and return error", diskURI, nodeName)
|
||||
// update VM(invalidate vm cache)
|
||||
if errUpdate := c.UpdateVM(nodeName); errUpdate != nil {
|
||||
return -1, errUpdate
|
||||
}
|
||||
lun, _, err := c.GetDiskLun(diskName, diskURI, nodeName)
|
||||
return lun, err
|
||||
}
|
||||
|
||||
attachErr := fmt.Sprintf(
|
||||
"disk(%s) already attached to node(%s), could not be attached to node(%s)",
|
||||
diskURI, *disk.ManagedBy, nodeName)
|
||||
klog.V(2).Infof("found dangling volume %s attached to node %s, could not be attached to node(%s)", diskURI, attachedNode, nodeName)
|
||||
return -1, volerr.NewDanglingError(attachErr, attachedNode, "")
|
||||
}
|
||||
|
||||
if disk.DiskProperties != nil {
|
||||
if disk.DiskProperties.DiskSizeGB != nil && *disk.DiskProperties.DiskSizeGB >= diskCachingLimit && cachingMode != compute.CachingTypesNone {
|
||||
// Disk Caching is not supported for disks 4 TiB and larger
|
||||
// https://docs.microsoft.com/en-us/azure/virtual-machines/premium-storage-performance#disk-caching
|
||||
cachingMode = compute.CachingTypesNone
|
||||
klog.Warningf("size of disk(%s) is %dGB which is bigger than limit(%dGB), set cacheMode as None",
|
||||
diskURI, *disk.DiskProperties.DiskSizeGB, diskCachingLimit)
|
||||
}
|
||||
|
||||
if disk.DiskProperties.Encryption != nil &&
|
||||
disk.DiskProperties.Encryption.DiskEncryptionSetID != nil {
|
||||
diskEncryptionSetID = *disk.DiskProperties.Encryption.DiskEncryptionSetID
|
||||
}
|
||||
|
||||
if disk.DiskProperties.DiskState != compute.Unattached && (disk.MaxShares == nil || *disk.MaxShares <= 1) {
|
||||
return -1, fmt.Errorf("state of disk(%s) is %s, not in expected %s state", diskURI, disk.DiskProperties.DiskState, compute.Unattached)
|
||||
}
|
||||
}
|
||||
|
||||
if v, ok := disk.Tags[WriteAcceleratorEnabled]; ok {
|
||||
if v != nil && strings.EqualFold(*v, "true") {
|
||||
writeAcceleratorEnabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
options := AttachDiskOptions{
|
||||
lun: -1,
|
||||
diskName: diskName,
|
||||
cachingMode: cachingMode,
|
||||
diskEncryptionSetID: diskEncryptionSetID,
|
||||
writeAcceleratorEnabled: writeAcceleratorEnabled,
|
||||
}
|
||||
node := strings.ToLower(string(nodeName))
|
||||
diskuri := strings.ToLower(diskURI)
|
||||
if err := c.insertAttachDiskRequest(diskuri, node, &options); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
c.lockMap.LockEntry(node)
|
||||
unlock := false
|
||||
defer func() {
|
||||
if !unlock {
|
||||
c.lockMap.UnlockEntry(node)
|
||||
}
|
||||
}()
|
||||
|
||||
diskMap, err := c.cleanAttachDiskRequests(node)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
lun, err := c.SetDiskLun(nodeName, diskuri, diskMap)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
klog.V(2).Infof("Trying to attach volume %q lun %d to node %q, diskMap: %s", diskURI, lun, nodeName, diskMap)
|
||||
if len(diskMap) == 0 {
|
||||
return lun, nil
|
||||
}
|
||||
|
||||
vmset, err := c.getNodeVMSet(nodeName, azcache.CacheReadTypeUnsafe)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
c.diskStateMap.Store(disk, "attaching")
|
||||
defer c.diskStateMap.Delete(disk)
|
||||
future, err := vmset.AttachDisk(nodeName, diskMap)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
if async && c.diskOpRateLimiter.TryAccept() {
|
||||
// unlock and wait for attach disk complete
|
||||
unlock = true
|
||||
c.lockMap.UnlockEntry(node)
|
||||
} else {
|
||||
klog.Warningf("azureDisk - switch to batch operation due to rate limited(async: %t), QPS: %f", async, c.diskOpRateLimiter.QPS())
|
||||
}
|
||||
resourceGroup, err := getResourceGroupFromDiskURI(diskURI)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return lun, vmset.WaitForUpdateResult(ctx, future, resourceGroup, "attach_disk")
|
||||
}
|
||||
|
||||
func (c *controllerCommon) insertAttachDiskRequest(diskURI, nodeName string, options *AttachDiskOptions) error {
|
||||
var diskMap map[string]*AttachDiskOptions
|
||||
attachDiskMapKey := nodeName + attachDiskMapKeySuffix
|
||||
c.lockMap.LockEntry(attachDiskMapKey)
|
||||
defer c.lockMap.UnlockEntry(attachDiskMapKey)
|
||||
v, ok := c.attachDiskMap.Load(nodeName)
|
||||
if ok {
|
||||
if diskMap, ok = v.(map[string]*AttachDiskOptions); !ok {
|
||||
return fmt.Errorf("convert attachDiskMap failure on node(%s)", nodeName)
|
||||
}
|
||||
} else {
|
||||
diskMap = make(map[string]*AttachDiskOptions)
|
||||
c.attachDiskMap.Store(nodeName, diskMap)
|
||||
}
|
||||
// insert attach disk request to queue
|
||||
_, ok = diskMap[diskURI]
|
||||
if ok {
|
||||
klog.V(2).Infof("azureDisk - duplicated attach disk(%s) request on node(%s)", diskURI, nodeName)
|
||||
} else {
|
||||
diskMap[diskURI] = options
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// clean up attach disk requests
|
||||
// return original attach disk requests
|
||||
func (c *controllerCommon) cleanAttachDiskRequests(nodeName string) (map[string]*AttachDiskOptions, error) {
|
||||
var diskMap map[string]*AttachDiskOptions
|
||||
|
||||
attachDiskMapKey := nodeName + attachDiskMapKeySuffix
|
||||
c.lockMap.LockEntry(attachDiskMapKey)
|
||||
defer c.lockMap.UnlockEntry(attachDiskMapKey)
|
||||
v, ok := c.attachDiskMap.Load(nodeName)
|
||||
if !ok {
|
||||
return diskMap, nil
|
||||
}
|
||||
if diskMap, ok = v.(map[string]*AttachDiskOptions); !ok {
|
||||
return diskMap, fmt.Errorf("convert attachDiskMap failure on node(%s)", nodeName)
|
||||
}
|
||||
c.attachDiskMap.Store(nodeName, make(map[string]*AttachDiskOptions))
|
||||
return diskMap, nil
|
||||
}
|
||||
|
||||
// DetachDisk detaches a disk from VM
|
||||
func (c *controllerCommon) DetachDisk(ctx context.Context, diskName, diskURI string, nodeName types.NodeName) error {
|
||||
if _, err := c.cloud.InstanceID(context.TODO(), nodeName); err != nil {
|
||||
if errors.Is(err, cloudprovider.InstanceNotFound) {
|
||||
// if host doesn't exist, no need to detach
|
||||
klog.Warningf("azureDisk - failed to get azure instance id(%q), DetachDisk(%s) will assume disk is already detached",
|
||||
nodeName, diskURI)
|
||||
return nil
|
||||
}
|
||||
klog.Warningf("failed to get azure instance id (%v)", err)
|
||||
return fmt.Errorf("failed to get azure instance id for node %q: %w", nodeName, err)
|
||||
}
|
||||
|
||||
vmset, err := c.getNodeVMSet(nodeName, azcache.CacheReadTypeUnsafe)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
node := strings.ToLower(string(nodeName))
|
||||
disk := strings.ToLower(diskURI)
|
||||
if err := c.insertDetachDiskRequest(diskName, disk, node); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.lockMap.LockEntry(node)
|
||||
defer c.lockMap.UnlockEntry(node)
|
||||
diskMap, err := c.cleanDetachDiskRequests(node)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
klog.V(2).Infof("Trying to detach volume %q from node %q, diskMap: %s", diskURI, nodeName, diskMap)
|
||||
if len(diskMap) > 0 {
|
||||
c.diskStateMap.Store(disk, "detaching")
|
||||
defer c.diskStateMap.Delete(disk)
|
||||
if err = vmset.DetachDisk(nodeName, diskMap); err != nil {
|
||||
if isInstanceNotFoundError(err) {
|
||||
// if host doesn't exist, no need to detach
|
||||
klog.Warningf("azureDisk - got InstanceNotFoundError(%v), DetachDisk(%s) will assume disk is already detached",
|
||||
err, diskURI)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lun, _, errGetLun := c.GetDiskLun(diskName, diskURI, nodeName)
|
||||
if errGetLun == nil || !strings.Contains(errGetLun.Error(), consts.CannotFindDiskLUN) {
|
||||
return fmt.Errorf("disk(%s) is still attatched to node(%s) on lun(%d), error: %v", diskURI, nodeName, lun, errGetLun)
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
klog.Errorf("azureDisk - detach disk(%s, %s) failed, err: %v", diskName, diskURI, err)
|
||||
return err
|
||||
}
|
||||
|
||||
klog.V(2).Infof("azureDisk - detach disk(%s, %s) succeeded", diskName, diskURI)
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateVM updates a vm
|
||||
func (c *controllerCommon) UpdateVM(nodeName types.NodeName) error {
|
||||
vmset, err := c.getNodeVMSet(nodeName, azcache.CacheReadTypeUnsafe)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
node := strings.ToLower(string(nodeName))
|
||||
c.lockMap.LockEntry(node)
|
||||
defer c.lockMap.UnlockEntry(node)
|
||||
return vmset.UpdateVM(nodeName)
|
||||
}
|
||||
|
||||
func (c *controllerCommon) insertDetachDiskRequest(diskName, diskURI, nodeName string) error {
|
||||
var diskMap map[string]string
|
||||
detachDiskMapKey := nodeName + detachDiskMapKeySuffix
|
||||
c.lockMap.LockEntry(detachDiskMapKey)
|
||||
defer c.lockMap.UnlockEntry(detachDiskMapKey)
|
||||
v, ok := c.detachDiskMap.Load(nodeName)
|
||||
if ok {
|
||||
if diskMap, ok = v.(map[string]string); !ok {
|
||||
return fmt.Errorf("convert detachDiskMap failure on node(%s)", nodeName)
|
||||
}
|
||||
} else {
|
||||
diskMap = make(map[string]string)
|
||||
c.detachDiskMap.Store(nodeName, diskMap)
|
||||
}
|
||||
// insert detach disk request to queue
|
||||
_, ok = diskMap[diskURI]
|
||||
if ok {
|
||||
klog.V(2).Infof("azureDisk - duplicated detach disk(%s) request on node(%s)", diskURI, nodeName)
|
||||
} else {
|
||||
diskMap[diskURI] = diskName
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// clean up detach disk requests
|
||||
// return original detach disk requests
|
||||
func (c *controllerCommon) cleanDetachDiskRequests(nodeName string) (map[string]string, error) {
|
||||
var diskMap map[string]string
|
||||
|
||||
detachDiskMapKey := nodeName + detachDiskMapKeySuffix
|
||||
c.lockMap.LockEntry(detachDiskMapKey)
|
||||
defer c.lockMap.UnlockEntry(detachDiskMapKey)
|
||||
v, ok := c.detachDiskMap.Load(nodeName)
|
||||
if !ok {
|
||||
return diskMap, nil
|
||||
}
|
||||
if diskMap, ok = v.(map[string]string); !ok {
|
||||
return diskMap, fmt.Errorf("convert detachDiskMap failure on node(%s)", nodeName)
|
||||
}
|
||||
// clean up original requests in disk map
|
||||
c.detachDiskMap.Store(nodeName, make(map[string]string))
|
||||
return diskMap, nil
|
||||
}
|
||||
|
||||
// getNodeDataDisks invokes vmSet interfaces to get data disks for the node.
|
||||
func (c *controllerCommon) getNodeDataDisks(nodeName types.NodeName, crt azcache.AzureCacheReadType) ([]compute.DataDisk, *string, error) {
|
||||
vmset, err := c.getNodeVMSet(nodeName, crt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return vmset.GetDataDisks(nodeName, crt)
|
||||
}
|
||||
|
||||
// GetDiskLun finds the lun on the host that the vhd is attached to, given a vhd's diskName and diskURI.
|
||||
func (c *controllerCommon) GetDiskLun(diskName, diskURI string, nodeName types.NodeName) (int32, *string, error) {
|
||||
// getNodeDataDisks need to fetch the cached data/fresh data if cache expired here
|
||||
// to ensure we get LUN based on latest entry.
|
||||
disks, provisioningState, err := c.getNodeDataDisks(nodeName, azcache.CacheReadTypeDefault)
|
||||
if err != nil {
|
||||
klog.Errorf("error of getting data disks for node %q: %v", nodeName, err)
|
||||
return -1, provisioningState, err
|
||||
}
|
||||
|
||||
for _, disk := range disks {
|
||||
if disk.Lun != nil && (disk.Name != nil && diskName != "" && strings.EqualFold(*disk.Name, diskName)) ||
|
||||
(disk.Vhd != nil && disk.Vhd.URI != nil && diskURI != "" && strings.EqualFold(*disk.Vhd.URI, diskURI)) ||
|
||||
(disk.ManagedDisk != nil && strings.EqualFold(*disk.ManagedDisk.ID, diskURI)) {
|
||||
if disk.ToBeDetached != nil && *disk.ToBeDetached {
|
||||
klog.Warningf("azureDisk - find disk(ToBeDetached): lun %d name %q uri %q", *disk.Lun, diskName, diskURI)
|
||||
} else {
|
||||
// found the disk
|
||||
klog.V(2).Infof("azureDisk - find disk: lun %d name %q uri %q", *disk.Lun, diskName, diskURI)
|
||||
return *disk.Lun, provisioningState, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1, provisioningState, fmt.Errorf("%s for disk %s", consts.CannotFindDiskLUN, diskName)
|
||||
}
|
||||
|
||||
// SetDiskLun find unused luns and allocate lun for every disk in diskMap.
|
||||
// Return lun of diskURI, -1 if all luns are used.
|
||||
func (c *controllerCommon) SetDiskLun(nodeName types.NodeName, diskURI string, diskMap map[string]*AttachDiskOptions) (int32, error) {
|
||||
disks, _, err := c.getNodeDataDisks(nodeName, azcache.CacheReadTypeDefault)
|
||||
if err != nil {
|
||||
klog.Errorf("error of getting data disks for node %q: %v", nodeName, err)
|
||||
return -1, err
|
||||
}
|
||||
|
||||
lun := int32(-1)
|
||||
_, isDiskInMap := diskMap[diskURI]
|
||||
used := make([]bool, maxLUN)
|
||||
for _, disk := range disks {
|
||||
if disk.Lun != nil {
|
||||
used[*disk.Lun] = true
|
||||
if !isDiskInMap {
|
||||
// find lun of diskURI since diskURI is not in diskMap
|
||||
if disk.ManagedDisk != nil && strings.EqualFold(*disk.ManagedDisk.ID, diskURI) {
|
||||
lun = *disk.Lun
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !isDiskInMap && lun < 0 {
|
||||
return -1, fmt.Errorf("could not find disk(%s) in current disk list(len: %d) nor in diskMap(%v)", diskURI, len(disks), diskMap)
|
||||
}
|
||||
if len(diskMap) == 0 {
|
||||
// attach disk request is empty, return directly
|
||||
return lun, nil
|
||||
}
|
||||
|
||||
// allocate lun for every disk in diskMap
|
||||
var diskLuns []int32
|
||||
count := 0
|
||||
for k, v := range used {
|
||||
if !v {
|
||||
diskLuns = append(diskLuns, int32(k))
|
||||
count++
|
||||
if count >= len(diskMap) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(diskLuns) != len(diskMap) {
|
||||
return -1, fmt.Errorf("could not find enough disk luns(current: %d) for diskMap(%v, len=%d), diskURI(%s)",
|
||||
len(diskLuns), diskMap, len(diskMap), diskURI)
|
||||
}
|
||||
|
||||
count = 0
|
||||
for uri, opt := range diskMap {
|
||||
if opt == nil {
|
||||
return -1, fmt.Errorf("unexpected nil pointer in diskMap(%v), diskURI(%s)", diskMap, diskURI)
|
||||
}
|
||||
if strings.EqualFold(uri, diskURI) {
|
||||
lun = diskLuns[count]
|
||||
}
|
||||
opt.lun = diskLuns[count]
|
||||
count++
|
||||
}
|
||||
if lun < 0 {
|
||||
return lun, fmt.Errorf("could not find lun of diskURI(%s), diskMap(%v)", diskURI, diskMap)
|
||||
}
|
||||
return lun, nil
|
||||
}
|
||||
|
||||
// DisksAreAttached checks if a list of volumes are attached to the node with the specified NodeName.
|
||||
func (c *controllerCommon) DisksAreAttached(diskNames []string, nodeName types.NodeName) (map[string]bool, error) {
|
||||
attached := make(map[string]bool)
|
||||
for _, diskName := range diskNames {
|
||||
attached[diskName] = false
|
||||
}
|
||||
|
||||
// doing stalled read for getNodeDataDisks to ensure we don't call ARM
|
||||
// for every reconcile call. The cache is invalidated after Attach/Detach
|
||||
// disk. So the new entry will be fetched and cached the first time reconcile
|
||||
// loop runs after the Attach/Disk OP which will reflect the latest model.
|
||||
disks, _, err := c.getNodeDataDisks(nodeName, azcache.CacheReadTypeUnsafe)
|
||||
if err != nil {
|
||||
if errors.Is(err, cloudprovider.InstanceNotFound) {
|
||||
// if host doesn't exist, no need to detach
|
||||
klog.Warningf("azureDisk - Cannot find node %q, DisksAreAttached will assume disks %v are not attached to it.",
|
||||
nodeName, diskNames)
|
||||
return attached, nil
|
||||
}
|
||||
|
||||
return attached, err
|
||||
}
|
||||
|
||||
for _, disk := range disks {
|
||||
for _, diskName := range diskNames {
|
||||
if disk.Name != nil && diskName != "" && strings.EqualFold(*disk.Name, diskName) {
|
||||
attached[diskName] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return attached, nil
|
||||
}
|
||||
|
||||
func filterDetachingDisks(unfilteredDisks []compute.DataDisk) []compute.DataDisk {
|
||||
filteredDisks := []compute.DataDisk{}
|
||||
for _, disk := range unfilteredDisks {
|
||||
if disk.ToBeDetached != nil && *disk.ToBeDetached {
|
||||
if disk.Name != nil {
|
||||
klog.V(2).Infof("Filtering disk: %s with ToBeDetached flag set.", *disk.Name)
|
||||
}
|
||||
} else {
|
||||
filteredDisks = append(filteredDisks, disk)
|
||||
}
|
||||
}
|
||||
return filteredDisks
|
||||
}
|
||||
|
||||
func (c *controllerCommon) filterNonExistingDisks(ctx context.Context, unfilteredDisks []compute.DataDisk) []compute.DataDisk {
|
||||
filteredDisks := []compute.DataDisk{}
|
||||
for _, disk := range unfilteredDisks {
|
||||
filter := false
|
||||
if disk.ManagedDisk != nil && disk.ManagedDisk.ID != nil {
|
||||
diskURI := *disk.ManagedDisk.ID
|
||||
exist, err := c.cloud.checkDiskExists(ctx, diskURI)
|
||||
if err != nil {
|
||||
klog.Errorf("checkDiskExists(%s) failed with error: %v", diskURI, err)
|
||||
} else {
|
||||
// only filter disk when checkDiskExists returns <false, nil>
|
||||
filter = !exist
|
||||
if filter {
|
||||
klog.Errorf("disk(%s) does not exist, removed from data disk list", diskURI)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !filter {
|
||||
filteredDisks = append(filteredDisks, disk)
|
||||
}
|
||||
}
|
||||
return filteredDisks
|
||||
}
|
||||
|
||||
func (c *controllerCommon) checkDiskExists(ctx context.Context, diskURI string) (bool, error) {
|
||||
diskName := path.Base(diskURI)
|
||||
resourceGroup, err := getResourceGroupFromDiskURI(diskURI)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if _, rerr := c.cloud.DisksClient.Get(ctx, resourceGroup, diskName); rerr != nil {
|
||||
if rerr.HTTPStatusCode == http.StatusNotFound {
|
||||
return false, nil
|
||||
}
|
||||
return false, rerr.Error()
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func getValidCreationData(subscriptionID, resourceGroup, sourceResourceID, sourceType string) (compute.CreationData, error) {
|
||||
if sourceResourceID == "" {
|
||||
return compute.CreationData{
|
||||
CreateOption: compute.Empty,
|
||||
}, nil
|
||||
}
|
||||
|
||||
switch sourceType {
|
||||
case sourceSnapshot:
|
||||
if match := diskSnapshotPathRE.FindString(sourceResourceID); match == "" {
|
||||
sourceResourceID = fmt.Sprintf(diskSnapshotPath, subscriptionID, resourceGroup, sourceResourceID)
|
||||
}
|
||||
|
||||
case sourceVolume:
|
||||
if match := managedDiskPathRE.FindString(sourceResourceID); match == "" {
|
||||
sourceResourceID = fmt.Sprintf(managedDiskPath, subscriptionID, resourceGroup, sourceResourceID)
|
||||
}
|
||||
default:
|
||||
return compute.CreationData{
|
||||
CreateOption: compute.Empty,
|
||||
}, nil
|
||||
}
|
||||
|
||||
splits := strings.Split(sourceResourceID, "/")
|
||||
if len(splits) > 9 {
|
||||
if sourceType == sourceSnapshot {
|
||||
return compute.CreationData{}, fmt.Errorf("sourceResourceID(%s) is invalid, correct format: %s", sourceResourceID, diskSnapshotPathRE)
|
||||
}
|
||||
return compute.CreationData{}, fmt.Errorf("sourceResourceID(%s) is invalid, correct format: %s", sourceResourceID, managedDiskPathRE)
|
||||
}
|
||||
return compute.CreationData{
|
||||
CreateOption: compute.Copy,
|
||||
SourceResourceID: &sourceResourceID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func isInstanceNotFoundError(err error) bool {
|
||||
errMsg := strings.ToLower(err.Error())
|
||||
if strings.Contains(errMsg, strings.ToLower(consts.VmssVMNotActiveErrorMessage)) {
|
||||
return true
|
||||
}
|
||||
return strings.Contains(errMsg, errStatusCode400) && strings.Contains(errMsg, errInvalidParameter) && strings.Contains(errMsg, errTargetInstanceIds)
|
||||
}
|
||||
250
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_controller_standard.go
generated
vendored
Normal file
250
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_controller_standard.go
generated
vendored
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-12-01/compute"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
azcache "sigs.k8s.io/cloud-provider-azure/pkg/cache"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/consts"
|
||||
)
|
||||
|
||||
// AttachDisk attaches a disk to vm
|
||||
func (as *availabilitySet) AttachDisk(nodeName types.NodeName, diskMap map[string]*AttachDiskOptions) (*azure.Future, error) {
|
||||
vm, err := as.getVirtualMachine(nodeName, azcache.CacheReadTypeDefault)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vmName := mapNodeNameToVMName(nodeName)
|
||||
nodeResourceGroup, err := as.GetNodeResourceGroup(vmName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
disks := make([]compute.DataDisk, len(*vm.StorageProfile.DataDisks))
|
||||
copy(disks, *vm.StorageProfile.DataDisks)
|
||||
|
||||
for k, v := range diskMap {
|
||||
diskURI := k
|
||||
opt := v
|
||||
attached := false
|
||||
for _, disk := range *vm.StorageProfile.DataDisks {
|
||||
if disk.ManagedDisk != nil && strings.EqualFold(*disk.ManagedDisk.ID, diskURI) {
|
||||
attached = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if attached {
|
||||
klog.V(2).Infof("azureDisk - disk(%s) already attached to node(%s)", diskURI, nodeName)
|
||||
continue
|
||||
}
|
||||
|
||||
managedDisk := &compute.ManagedDiskParameters{ID: &diskURI}
|
||||
if opt.diskEncryptionSetID == "" {
|
||||
if vm.StorageProfile.OsDisk != nil &&
|
||||
vm.StorageProfile.OsDisk.ManagedDisk != nil &&
|
||||
vm.StorageProfile.OsDisk.ManagedDisk.DiskEncryptionSet != nil &&
|
||||
vm.StorageProfile.OsDisk.ManagedDisk.DiskEncryptionSet.ID != nil {
|
||||
// set diskEncryptionSet as value of os disk by default
|
||||
opt.diskEncryptionSetID = *vm.StorageProfile.OsDisk.ManagedDisk.DiskEncryptionSet.ID
|
||||
}
|
||||
}
|
||||
if opt.diskEncryptionSetID != "" {
|
||||
managedDisk.DiskEncryptionSet = &compute.DiskEncryptionSetParameters{ID: &opt.diskEncryptionSetID}
|
||||
}
|
||||
disks = append(disks,
|
||||
compute.DataDisk{
|
||||
Name: &opt.diskName,
|
||||
Lun: &opt.lun,
|
||||
Caching: opt.cachingMode,
|
||||
CreateOption: "attach",
|
||||
ManagedDisk: managedDisk,
|
||||
WriteAcceleratorEnabled: to.BoolPtr(opt.writeAcceleratorEnabled),
|
||||
})
|
||||
}
|
||||
|
||||
newVM := compute.VirtualMachineUpdate{
|
||||
VirtualMachineProperties: &compute.VirtualMachineProperties{
|
||||
StorageProfile: &compute.StorageProfile{
|
||||
DataDisks: &disks,
|
||||
},
|
||||
},
|
||||
}
|
||||
klog.V(2).Infof("azureDisk - update(%s): vm(%s) - attach disk list(%s)", nodeResourceGroup, vmName, diskMap)
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
// Invalidate the cache right after updating
|
||||
defer func() {
|
||||
_ = as.cloud.vmCache.Delete(vmName)
|
||||
}()
|
||||
|
||||
future, rerr := as.VirtualMachinesClient.UpdateAsync(ctx, nodeResourceGroup, vmName, newVM, "attach_disk")
|
||||
if rerr != nil {
|
||||
klog.Errorf("azureDisk - attach disk list(%s) on rg(%s) vm(%s) failed, err: %v", diskMap, nodeResourceGroup, vmName, rerr)
|
||||
if rerr.HTTPStatusCode == http.StatusNotFound {
|
||||
klog.Errorf("azureDisk - begin to filterNonExistingDisks(%v) on rg(%s) vm(%s)", diskMap, nodeResourceGroup, vmName)
|
||||
disks := as.filterNonExistingDisks(ctx, *newVM.VirtualMachineProperties.StorageProfile.DataDisks)
|
||||
newVM.VirtualMachineProperties.StorageProfile.DataDisks = &disks
|
||||
future, rerr = as.VirtualMachinesClient.UpdateAsync(ctx, nodeResourceGroup, vmName, newVM, "attach_disk")
|
||||
}
|
||||
}
|
||||
|
||||
klog.V(2).Infof("azureDisk - update(%s): vm(%s) - attach disk list(%s) returned with %v", nodeResourceGroup, vmName, diskMap, rerr)
|
||||
if rerr != nil {
|
||||
return future, rerr.Error()
|
||||
}
|
||||
return future, nil
|
||||
}
|
||||
|
||||
// WaitForUpdateResult waits for the response of the update request
|
||||
func (as *availabilitySet) WaitForUpdateResult(ctx context.Context, future *azure.Future, resourceGroupName, source string) error {
|
||||
if rerr := as.VirtualMachinesClient.WaitForUpdateResult(ctx, future, resourceGroupName, source); rerr != nil {
|
||||
return rerr.Error()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DetachDisk detaches a disk from VM
|
||||
func (as *availabilitySet) DetachDisk(nodeName types.NodeName, diskMap map[string]string) error {
|
||||
vm, err := as.getVirtualMachine(nodeName, azcache.CacheReadTypeDefault)
|
||||
if err != nil {
|
||||
// if host doesn't exist, no need to detach
|
||||
klog.Warningf("azureDisk - cannot find node %s, skip detaching disk list(%s)", nodeName, diskMap)
|
||||
return nil
|
||||
}
|
||||
|
||||
vmName := mapNodeNameToVMName(nodeName)
|
||||
nodeResourceGroup, err := as.GetNodeResourceGroup(vmName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
disks := make([]compute.DataDisk, len(*vm.StorageProfile.DataDisks))
|
||||
copy(disks, *vm.StorageProfile.DataDisks)
|
||||
|
||||
bFoundDisk := false
|
||||
for i, disk := range disks {
|
||||
for diskURI, diskName := range diskMap {
|
||||
if disk.Lun != nil && (disk.Name != nil && diskName != "" && strings.EqualFold(*disk.Name, diskName)) ||
|
||||
(disk.Vhd != nil && disk.Vhd.URI != nil && diskURI != "" && strings.EqualFold(*disk.Vhd.URI, diskURI)) ||
|
||||
(disk.ManagedDisk != nil && diskURI != "" && strings.EqualFold(*disk.ManagedDisk.ID, diskURI)) {
|
||||
// found the disk
|
||||
klog.V(2).Infof("azureDisk - detach disk: name %q uri %q", diskName, diskURI)
|
||||
disks[i].ToBeDetached = to.BoolPtr(true)
|
||||
bFoundDisk = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !bFoundDisk {
|
||||
// only log here, next action is to update VM status with original meta data
|
||||
klog.Errorf("detach azure disk on node(%s): disk list(%s) not found", nodeName, diskMap)
|
||||
} else {
|
||||
if strings.EqualFold(as.cloud.Environment.Name, consts.AzureStackCloudName) && !as.Config.DisableAzureStackCloud {
|
||||
// Azure stack does not support ToBeDetached flag, use original way to detach disk
|
||||
newDisks := []compute.DataDisk{}
|
||||
for _, disk := range disks {
|
||||
if !to.Bool(disk.ToBeDetached) {
|
||||
newDisks = append(newDisks, disk)
|
||||
}
|
||||
}
|
||||
disks = newDisks
|
||||
}
|
||||
}
|
||||
|
||||
newVM := compute.VirtualMachineUpdate{
|
||||
VirtualMachineProperties: &compute.VirtualMachineProperties{
|
||||
StorageProfile: &compute.StorageProfile{
|
||||
DataDisks: &disks,
|
||||
},
|
||||
},
|
||||
}
|
||||
klog.V(2).Infof("azureDisk - update(%s): vm(%s) - detach disk list(%s)", nodeResourceGroup, vmName, nodeName, diskMap)
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
// Invalidate the cache right after updating
|
||||
defer func() {
|
||||
_ = as.cloud.vmCache.Delete(vmName)
|
||||
}()
|
||||
|
||||
rerr := as.VirtualMachinesClient.Update(ctx, nodeResourceGroup, vmName, newVM, "detach_disk")
|
||||
if rerr != nil {
|
||||
klog.Errorf("azureDisk - detach disk list(%s) on rg(%s) vm(%s) failed, err: %v", diskMap, nodeResourceGroup, vmName, rerr)
|
||||
if rerr.HTTPStatusCode == http.StatusNotFound {
|
||||
klog.Errorf("azureDisk - begin to filterNonExistingDisks(%v) on rg(%s) vm(%s)", diskMap, nodeResourceGroup, vmName)
|
||||
disks := as.filterNonExistingDisks(ctx, *vm.StorageProfile.DataDisks)
|
||||
newVM.VirtualMachineProperties.StorageProfile.DataDisks = &disks
|
||||
rerr = as.VirtualMachinesClient.Update(ctx, nodeResourceGroup, vmName, newVM, "detach_disk")
|
||||
}
|
||||
}
|
||||
|
||||
klog.V(2).Infof("azureDisk - update(%s): vm(%s) - detach disk list(%s) returned with %v", nodeResourceGroup, vmName, diskMap, rerr)
|
||||
if rerr != nil {
|
||||
return rerr.Error()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateVM updates a vm
|
||||
func (as *availabilitySet) UpdateVM(nodeName types.NodeName) error {
|
||||
vmName := mapNodeNameToVMName(nodeName)
|
||||
nodeResourceGroup, err := as.GetNodeResourceGroup(vmName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
klog.V(2).Infof("azureDisk - update(%s): vm(%s)", nodeResourceGroup, vmName)
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
// Invalidate the cache right after updating
|
||||
defer func() {
|
||||
_ = as.cloud.vmCache.Delete(vmName)
|
||||
}()
|
||||
|
||||
rerr := as.VirtualMachinesClient.Update(ctx, nodeResourceGroup, vmName, compute.VirtualMachineUpdate{}, "update_vm")
|
||||
klog.V(2).Infof("azureDisk - update(%s): vm(%s) - returned with %v", nodeResourceGroup, vmName, rerr)
|
||||
if rerr != nil {
|
||||
return rerr.Error()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetDataDisks gets a list of data disks attached to the node.
|
||||
func (as *availabilitySet) GetDataDisks(nodeName types.NodeName, crt azcache.AzureCacheReadType) ([]compute.DataDisk, *string, error) {
|
||||
vm, err := as.getVirtualMachine(nodeName, crt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if vm.StorageProfile.DataDisks == nil {
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
return *vm.StorageProfile.DataDisks, vm.ProvisioningState, nil
|
||||
}
|
||||
262
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_controller_vmss.go
generated
vendored
Normal file
262
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_controller_vmss.go
generated
vendored
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-12-01/compute"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
azcache "sigs.k8s.io/cloud-provider-azure/pkg/cache"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/consts"
|
||||
)
|
||||
|
||||
// AttachDisk attaches a disk to vm
|
||||
func (ss *ScaleSet) AttachDisk(nodeName types.NodeName, diskMap map[string]*AttachDiskOptions) (*azure.Future, error) {
|
||||
vmName := mapNodeNameToVMName(nodeName)
|
||||
ssName, instanceID, vm, err := ss.getVmssVM(vmName, azcache.CacheReadTypeDefault)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nodeResourceGroup, err := ss.GetNodeResourceGroup(vmName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
disks := []compute.DataDisk{}
|
||||
if vm.StorageProfile != nil && vm.StorageProfile.DataDisks != nil {
|
||||
disks = make([]compute.DataDisk, len(*vm.StorageProfile.DataDisks))
|
||||
copy(disks, *vm.StorageProfile.DataDisks)
|
||||
}
|
||||
|
||||
for k, v := range diskMap {
|
||||
diskURI := k
|
||||
opt := v
|
||||
attached := false
|
||||
for _, disk := range *vm.StorageProfile.DataDisks {
|
||||
if disk.ManagedDisk != nil && strings.EqualFold(*disk.ManagedDisk.ID, diskURI) {
|
||||
attached = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if attached {
|
||||
klog.V(2).Infof("azureDisk - disk(%s) already attached to node(%s)", diskURI, nodeName)
|
||||
continue
|
||||
}
|
||||
|
||||
managedDisk := &compute.ManagedDiskParameters{ID: &diskURI}
|
||||
if opt.diskEncryptionSetID == "" {
|
||||
if vm.StorageProfile.OsDisk != nil &&
|
||||
vm.StorageProfile.OsDisk.ManagedDisk != nil &&
|
||||
vm.StorageProfile.OsDisk.ManagedDisk.DiskEncryptionSet != nil &&
|
||||
vm.StorageProfile.OsDisk.ManagedDisk.DiskEncryptionSet.ID != nil {
|
||||
// set diskEncryptionSet as value of os disk by default
|
||||
opt.diskEncryptionSetID = *vm.StorageProfile.OsDisk.ManagedDisk.DiskEncryptionSet.ID
|
||||
}
|
||||
}
|
||||
if opt.diskEncryptionSetID != "" {
|
||||
managedDisk.DiskEncryptionSet = &compute.DiskEncryptionSetParameters{ID: &opt.diskEncryptionSetID}
|
||||
}
|
||||
disks = append(disks,
|
||||
compute.DataDisk{
|
||||
Name: &opt.diskName,
|
||||
Lun: &opt.lun,
|
||||
Caching: opt.cachingMode,
|
||||
CreateOption: "attach",
|
||||
ManagedDisk: managedDisk,
|
||||
WriteAcceleratorEnabled: to.BoolPtr(opt.writeAcceleratorEnabled),
|
||||
})
|
||||
}
|
||||
|
||||
newVM := compute.VirtualMachineScaleSetVM{
|
||||
VirtualMachineScaleSetVMProperties: &compute.VirtualMachineScaleSetVMProperties{
|
||||
StorageProfile: &compute.StorageProfile{
|
||||
DataDisks: &disks,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
// Invalidate the cache right after updating
|
||||
defer func() {
|
||||
_ = ss.deleteCacheForNode(vmName)
|
||||
}()
|
||||
|
||||
klog.V(2).Infof("azureDisk - update(%s): vm(%s) - attach disk list(%s)", nodeResourceGroup, nodeName, diskMap)
|
||||
future, rerr := ss.VirtualMachineScaleSetVMsClient.UpdateAsync(ctx, nodeResourceGroup, ssName, instanceID, newVM, "attach_disk")
|
||||
if rerr != nil {
|
||||
klog.Errorf("azureDisk - attach disk list(%s) on rg(%s) vm(%s) failed, err: %v", diskMap, nodeResourceGroup, nodeName, rerr)
|
||||
if rerr.HTTPStatusCode == http.StatusNotFound {
|
||||
klog.Errorf("azureDisk - begin to filterNonExistingDisks(%v) on rg(%s) vm(%s)", diskMap, nodeResourceGroup, nodeName)
|
||||
disks := ss.filterNonExistingDisks(ctx, *newVM.VirtualMachineScaleSetVMProperties.StorageProfile.DataDisks)
|
||||
newVM.VirtualMachineScaleSetVMProperties.StorageProfile.DataDisks = &disks
|
||||
future, rerr = ss.VirtualMachineScaleSetVMsClient.UpdateAsync(ctx, nodeResourceGroup, ssName, instanceID, newVM, "attach_disk")
|
||||
}
|
||||
}
|
||||
|
||||
klog.V(2).Infof("azureDisk - update(%s): vm(%s) - attach disk list(%s, %s) returned with %v", nodeResourceGroup, nodeName, diskMap, rerr)
|
||||
if rerr != nil {
|
||||
return future, rerr.Error()
|
||||
}
|
||||
return future, nil
|
||||
}
|
||||
|
||||
// WaitForUpdateResult waits for the response of the update request
|
||||
func (ss *ScaleSet) WaitForUpdateResult(ctx context.Context, future *azure.Future, resourceGroupName, source string) error {
|
||||
if rerr := ss.VirtualMachineScaleSetVMsClient.WaitForUpdateResult(ctx, future, resourceGroupName, source); rerr != nil {
|
||||
return rerr.Error()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DetachDisk detaches a disk from VM
|
||||
func (ss *ScaleSet) DetachDisk(nodeName types.NodeName, diskMap map[string]string) error {
|
||||
vmName := mapNodeNameToVMName(nodeName)
|
||||
ssName, instanceID, vm, err := ss.getVmssVM(vmName, azcache.CacheReadTypeDefault)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nodeResourceGroup, err := ss.GetNodeResourceGroup(vmName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
disks := []compute.DataDisk{}
|
||||
if vm.StorageProfile != nil && vm.StorageProfile.DataDisks != nil {
|
||||
disks = make([]compute.DataDisk, len(*vm.StorageProfile.DataDisks))
|
||||
copy(disks, *vm.StorageProfile.DataDisks)
|
||||
}
|
||||
bFoundDisk := false
|
||||
for i, disk := range disks {
|
||||
for diskURI, diskName := range diskMap {
|
||||
if disk.Lun != nil && (disk.Name != nil && diskName != "" && strings.EqualFold(*disk.Name, diskName)) ||
|
||||
(disk.Vhd != nil && disk.Vhd.URI != nil && diskURI != "" && strings.EqualFold(*disk.Vhd.URI, diskURI)) ||
|
||||
(disk.ManagedDisk != nil && diskURI != "" && strings.EqualFold(*disk.ManagedDisk.ID, diskURI)) {
|
||||
// found the disk
|
||||
klog.V(2).Infof("azureDisk - detach disk: name %q uri %q", diskName, diskURI)
|
||||
disks[i].ToBeDetached = to.BoolPtr(true)
|
||||
bFoundDisk = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !bFoundDisk {
|
||||
// only log here, next action is to update VM status with original meta data
|
||||
klog.Errorf("detach azure disk on node(%s): disk list(%s) not found", nodeName, diskMap)
|
||||
} else {
|
||||
if strings.EqualFold(ss.cloud.Environment.Name, consts.AzureStackCloudName) && !ss.Config.DisableAzureStackCloud {
|
||||
// Azure stack does not support ToBeDetached flag, use original way to detach disk
|
||||
newDisks := []compute.DataDisk{}
|
||||
for _, disk := range disks {
|
||||
if !to.Bool(disk.ToBeDetached) {
|
||||
newDisks = append(newDisks, disk)
|
||||
}
|
||||
}
|
||||
disks = newDisks
|
||||
}
|
||||
}
|
||||
|
||||
newVM := compute.VirtualMachineScaleSetVM{
|
||||
VirtualMachineScaleSetVMProperties: &compute.VirtualMachineScaleSetVMProperties{
|
||||
StorageProfile: &compute.StorageProfile{
|
||||
DataDisks: &disks,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
// Invalidate the cache right after updating
|
||||
defer func() {
|
||||
_ = ss.deleteCacheForNode(vmName)
|
||||
}()
|
||||
|
||||
klog.V(2).Infof("azureDisk - update(%s): vm(%s) - detach disk list(%s)", nodeResourceGroup, nodeName, diskMap)
|
||||
rerr := ss.VirtualMachineScaleSetVMsClient.Update(ctx, nodeResourceGroup, ssName, instanceID, newVM, "detach_disk")
|
||||
if rerr != nil {
|
||||
klog.Errorf("azureDisk - detach disk list(%s) on rg(%s) vm(%s) failed, err: %v", diskMap, nodeResourceGroup, nodeName, rerr)
|
||||
if rerr.HTTPStatusCode == http.StatusNotFound {
|
||||
klog.Errorf("azureDisk - begin to filterNonExistingDisks(%v) on rg(%s) vm(%s)", diskMap, nodeResourceGroup, nodeName)
|
||||
disks := ss.filterNonExistingDisks(ctx, *newVM.VirtualMachineScaleSetVMProperties.StorageProfile.DataDisks)
|
||||
newVM.VirtualMachineScaleSetVMProperties.StorageProfile.DataDisks = &disks
|
||||
rerr = ss.VirtualMachineScaleSetVMsClient.Update(ctx, nodeResourceGroup, ssName, instanceID, newVM, "detach_disk")
|
||||
}
|
||||
}
|
||||
|
||||
klog.V(2).Infof("azureDisk - update(%s): vm(%s) - detach disk(%v) returned with %v", nodeResourceGroup, nodeName, diskMap, rerr)
|
||||
if rerr != nil {
|
||||
return rerr.Error()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateVM updates a vm
|
||||
func (ss *ScaleSet) UpdateVM(nodeName types.NodeName) error {
|
||||
vmName := mapNodeNameToVMName(nodeName)
|
||||
ssName, instanceID, _, err := ss.getVmssVM(vmName, azcache.CacheReadTypeDefault)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nodeResourceGroup, err := ss.GetNodeResourceGroup(vmName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
// Invalidate the cache right after updating
|
||||
defer func() {
|
||||
_ = ss.deleteCacheForNode(vmName)
|
||||
}()
|
||||
|
||||
klog.V(2).Infof("azureDisk - update(%s): vm(%s)", nodeResourceGroup, nodeName)
|
||||
rerr := ss.VirtualMachineScaleSetVMsClient.Update(ctx, nodeResourceGroup, ssName, instanceID, compute.VirtualMachineScaleSetVM{}, "update_vmss_instance")
|
||||
|
||||
klog.V(2).Infof("azureDisk - update(%s): vm(%s) - returned with %v", nodeResourceGroup, nodeName, rerr)
|
||||
if rerr != nil {
|
||||
return rerr.Error()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetDataDisks gets a list of data disks attached to the node.
|
||||
func (ss *ScaleSet) GetDataDisks(nodeName types.NodeName, crt azcache.AzureCacheReadType) ([]compute.DataDisk, *string, error) {
|
||||
_, _, vm, err := ss.getVmssVM(string(nodeName), crt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if vm.StorageProfile == nil || vm.StorageProfile.DataDisks == nil {
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
return *vm.StorageProfile.DataDisks, vm.ProvisioningState, nil
|
||||
}
|
||||
130
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_fakes.go
generated
vendored
Normal file
130
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_fakes.go
generated
vendored
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/client-go/tools/record"
|
||||
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/auth"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/diskclient/mockdiskclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/interfaceclient/mockinterfaceclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/loadbalancerclient/mockloadbalancerclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/publicipclient/mockpublicipclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routeclient/mockrouteclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/routetableclient/mockroutetableclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/securitygroupclient/mocksecuritygroupclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/snapshotclient/mocksnapshotclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/subnetclient/mocksubnetclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmclient/mockvmclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmssclient/mockvmssclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/vmssvmclient/mockvmssvmclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/consts"
|
||||
)
|
||||
|
||||
var (
|
||||
errPreconditionFailedEtagMismatch = fmt.Errorf("PreconditionFailedEtagMismatch")
|
||||
)
|
||||
|
||||
// NewTestScaleSet creates a fake ScaleSet for unit test
|
||||
func NewTestScaleSet(ctrl *gomock.Controller) (*ScaleSet, error) {
|
||||
return newTestScaleSetWithState(ctrl)
|
||||
}
|
||||
|
||||
func newTestScaleSetWithState(ctrl *gomock.Controller) (*ScaleSet, error) {
|
||||
cloud := GetTestCloud(ctrl)
|
||||
ss, err := newScaleSet(cloud)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ss.(*ScaleSet), nil
|
||||
}
|
||||
|
||||
// GetTestCloud returns a fake azure cloud for unit tests in Azure related CSI drivers
|
||||
func GetTestCloud(ctrl *gomock.Controller) (az *Cloud) {
|
||||
az = &Cloud{
|
||||
Config: Config{
|
||||
AzureAuthConfig: auth.AzureAuthConfig{
|
||||
TenantID: "tenant",
|
||||
SubscriptionID: "subscription",
|
||||
},
|
||||
ResourceGroup: "rg",
|
||||
VnetResourceGroup: "rg",
|
||||
RouteTableResourceGroup: "rg",
|
||||
SecurityGroupResourceGroup: "rg",
|
||||
Location: "westus",
|
||||
VnetName: "vnet",
|
||||
SubnetName: "subnet",
|
||||
SecurityGroupName: "nsg",
|
||||
RouteTableName: "rt",
|
||||
PrimaryAvailabilitySetName: "as",
|
||||
PrimaryScaleSetName: "vmss",
|
||||
MaximumLoadBalancerRuleCount: 250,
|
||||
VMType: consts.VMTypeStandard,
|
||||
LoadBalancerBackendPoolConfigurationType: consts.LoadBalancerBackendPoolConfigurationTypeNodeIPConfiguration,
|
||||
},
|
||||
nodeZones: map[string]sets.String{},
|
||||
nodeInformerSynced: func() bool { return true },
|
||||
nodeResourceGroups: map[string]string{},
|
||||
unmanagedNodes: sets.NewString(),
|
||||
excludeLoadBalancerNodes: sets.NewString(),
|
||||
nodePrivateIPs: map[string]sets.String{},
|
||||
routeCIDRs: map[string]string{},
|
||||
eventRecorder: &record.FakeRecorder{},
|
||||
}
|
||||
az.DisksClient = mockdiskclient.NewMockInterface(ctrl)
|
||||
az.SnapshotsClient = mocksnapshotclient.NewMockInterface(ctrl)
|
||||
az.InterfacesClient = mockinterfaceclient.NewMockInterface(ctrl)
|
||||
az.LoadBalancerClient = mockloadbalancerclient.NewMockInterface(ctrl)
|
||||
az.PublicIPAddressesClient = mockpublicipclient.NewMockInterface(ctrl)
|
||||
az.RoutesClient = mockrouteclient.NewMockInterface(ctrl)
|
||||
az.RouteTablesClient = mockroutetableclient.NewMockInterface(ctrl)
|
||||
az.SecurityGroupsClient = mocksecuritygroupclient.NewMockInterface(ctrl)
|
||||
az.SubnetsClient = mocksubnetclient.NewMockInterface(ctrl)
|
||||
az.VirtualMachineScaleSetsClient = mockvmssclient.NewMockInterface(ctrl)
|
||||
az.VirtualMachineScaleSetVMsClient = mockvmssvmclient.NewMockInterface(ctrl)
|
||||
az.VirtualMachinesClient = mockvmclient.NewMockInterface(ctrl)
|
||||
az.VMSet, _ = newAvailabilitySet(az)
|
||||
az.vmCache, _ = az.newVMCache()
|
||||
az.lbCache, _ = az.newLBCache()
|
||||
az.nsgCache, _ = az.newNSGCache()
|
||||
az.rtCache, _ = az.newRouteTableCache()
|
||||
az.LoadBalancerBackendPool = NewMockBackendPool(ctrl)
|
||||
|
||||
_ = initDiskControllers(az)
|
||||
|
||||
az.regionZonesMap = map[string][]string{az.Location: {"1", "2", "3"}}
|
||||
|
||||
return az
|
||||
}
|
||||
|
||||
// GetTestCloudWithExtendedLocation returns a fake azure cloud for unit tests in Azure related CSI drivers with extended location.
|
||||
func GetTestCloudWithExtendedLocation(ctrl *gomock.Controller) (az *Cloud) {
|
||||
az = GetTestCloud(ctrl)
|
||||
az.Config.ExtendedLocationName = "microsoftlosangeles1"
|
||||
az.Config.ExtendedLocationType = "EdgeZone"
|
||||
az.controllerCommon.extendedLocation = &ExtendedLocation{
|
||||
Name: az.Config.ExtendedLocationName,
|
||||
Type: az.Config.ExtendedLocationType,
|
||||
}
|
||||
return az
|
||||
}
|
||||
40
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_file.go
generated
vendored
Normal file
40
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_file.go
generated
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2021-02-01/storage"
|
||||
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/fileclient"
|
||||
)
|
||||
|
||||
// create file share
|
||||
func (az *Cloud) createFileShare(resourceGroupName, accountName string, shareOptions *fileclient.ShareOptions) error {
|
||||
return az.FileClient.CreateFileShare(resourceGroupName, accountName, shareOptions)
|
||||
}
|
||||
|
||||
func (az *Cloud) deleteFileShare(resourceGroupName, accountName, name string) error {
|
||||
return az.FileClient.DeleteFileShare(resourceGroupName, accountName, name)
|
||||
}
|
||||
|
||||
func (az *Cloud) resizeFileShare(resourceGroupName, accountName, name string, sizeGiB int) error {
|
||||
return az.FileClient.ResizeFileShare(resourceGroupName, accountName, name, sizeGiB)
|
||||
}
|
||||
|
||||
func (az *Cloud) getFileShare(resourceGroupName, accountName, name string) (storage.FileShare, error) {
|
||||
return az.FileClient.GetFileShare(resourceGroupName, accountName, name)
|
||||
}
|
||||
257
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_instance_metadata.go
generated
vendored
Normal file
257
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_instance_metadata.go
generated
vendored
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
azcache "sigs.k8s.io/cloud-provider-azure/pkg/cache"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/consts"
|
||||
)
|
||||
|
||||
// NetworkMetadata contains metadata about an instance's network
|
||||
type NetworkMetadata struct {
|
||||
Interface []NetworkInterface `json:"interface"`
|
||||
}
|
||||
|
||||
// NetworkInterface represents an instances network interface.
|
||||
type NetworkInterface struct {
|
||||
IPV4 NetworkData `json:"ipv4"`
|
||||
IPV6 NetworkData `json:"ipv6"`
|
||||
MAC string `json:"macAddress"`
|
||||
}
|
||||
|
||||
// NetworkData contains IP information for a network.
|
||||
type NetworkData struct {
|
||||
IPAddress []IPAddress `json:"ipAddress"`
|
||||
Subnet []Subnet `json:"subnet"`
|
||||
}
|
||||
|
||||
// IPAddress represents IP address information.
|
||||
type IPAddress struct {
|
||||
PrivateIP string `json:"privateIpAddress"`
|
||||
PublicIP string `json:"publicIpAddress"`
|
||||
}
|
||||
|
||||
// Subnet represents subnet information.
|
||||
type Subnet struct {
|
||||
Address string `json:"address"`
|
||||
Prefix string `json:"prefix"`
|
||||
}
|
||||
|
||||
// ComputeMetadata represents compute information
|
||||
type ComputeMetadata struct {
|
||||
Environment string `json:"azEnvironment,omitempty"`
|
||||
SKU string `json:"sku,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Zone string `json:"zone,omitempty"`
|
||||
VMSize string `json:"vmSize,omitempty"`
|
||||
OSType string `json:"osType,omitempty"`
|
||||
Location string `json:"location,omitempty"`
|
||||
FaultDomain string `json:"platformFaultDomain,omitempty"`
|
||||
UpdateDomain string `json:"platformUpdateDomain,omitempty"`
|
||||
ResourceGroup string `json:"resourceGroupName,omitempty"`
|
||||
VMScaleSetName string `json:"vmScaleSetName,omitempty"`
|
||||
SubscriptionID string `json:"subscriptionId,omitempty"`
|
||||
}
|
||||
|
||||
// InstanceMetadata represents instance information.
|
||||
type InstanceMetadata struct {
|
||||
Compute *ComputeMetadata `json:"compute,omitempty"`
|
||||
Network *NetworkMetadata `json:"network,omitempty"`
|
||||
}
|
||||
|
||||
// PublicIPMetadata represents the public IP metadata.
|
||||
type PublicIPMetadata struct {
|
||||
FrontendIPAddress string `json:"frontendIpAddress,omitempty"`
|
||||
PrivateIPAddress string `json:"privateIpAddress,omitempty"`
|
||||
}
|
||||
|
||||
// LoadbalancerProfile represents load balancer profile in IMDS.
|
||||
type LoadbalancerProfile struct {
|
||||
PublicIPAddresses []PublicIPMetadata `json:"publicIpAddresses,omitempty"`
|
||||
}
|
||||
|
||||
// LoadBalancerMetadata represents load balancer metadata.
|
||||
type LoadBalancerMetadata struct {
|
||||
LoadBalancer *LoadbalancerProfile `json:"loadbalancer,omitempty"`
|
||||
}
|
||||
|
||||
// InstanceMetadataService knows how to query the Azure instance metadata server.
|
||||
type InstanceMetadataService struct {
|
||||
imdsServer string
|
||||
imsCache *azcache.TimedCache
|
||||
}
|
||||
|
||||
// NewInstanceMetadataService creates an instance of the InstanceMetadataService accessor object.
|
||||
func NewInstanceMetadataService(imdsServer string) (*InstanceMetadataService, error) {
|
||||
ims := &InstanceMetadataService{
|
||||
imdsServer: imdsServer,
|
||||
}
|
||||
|
||||
imsCache, err := azcache.NewTimedcache(consts.MetadataCacheTTL, ims.getMetadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ims.imsCache = imsCache
|
||||
return ims, nil
|
||||
}
|
||||
|
||||
func (ims *InstanceMetadataService) getMetadata(key string) (interface{}, error) {
|
||||
instanceMetadata, err := ims.getInstanceMetadata(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if instanceMetadata.Network != nil && len(instanceMetadata.Network.Interface) > 0 {
|
||||
netInterface := instanceMetadata.Network.Interface[0]
|
||||
if (len(netInterface.IPV4.IPAddress) > 0 && len(netInterface.IPV4.IPAddress[0].PublicIP) > 0) ||
|
||||
(len(netInterface.IPV6.IPAddress) > 0 && len(netInterface.IPV6.IPAddress[0].PublicIP) > 0) {
|
||||
// Return if public IP address has already part of instance metadata.
|
||||
return instanceMetadata, nil
|
||||
}
|
||||
|
||||
loadBalancerMetadata, err := ims.getLoadBalancerMetadata()
|
||||
if err != nil || loadBalancerMetadata == nil || loadBalancerMetadata.LoadBalancer == nil {
|
||||
// Log a warning since loadbalancer metadata may not be available when the VM
|
||||
// is not in standard LoadBalancer backend address pool.
|
||||
klog.V(4).Infof("Warning: failed to get loadbalancer metadata: %v", err)
|
||||
return instanceMetadata, nil
|
||||
}
|
||||
|
||||
publicIPs := loadBalancerMetadata.LoadBalancer.PublicIPAddresses
|
||||
if len(netInterface.IPV4.IPAddress) > 0 && len(netInterface.IPV4.IPAddress[0].PrivateIP) > 0 {
|
||||
for _, pip := range publicIPs {
|
||||
if pip.PrivateIPAddress == netInterface.IPV4.IPAddress[0].PrivateIP {
|
||||
netInterface.IPV4.IPAddress[0].PublicIP = pip.FrontendIPAddress
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(netInterface.IPV6.IPAddress) > 0 && len(netInterface.IPV6.IPAddress[0].PrivateIP) > 0 {
|
||||
for _, pip := range publicIPs {
|
||||
if pip.PrivateIPAddress == netInterface.IPV6.IPAddress[0].PrivateIP {
|
||||
netInterface.IPV6.IPAddress[0].PublicIP = pip.FrontendIPAddress
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return instanceMetadata, nil
|
||||
}
|
||||
|
||||
func (ims *InstanceMetadataService) getInstanceMetadata(key string) (*InstanceMetadata, error) {
|
||||
req, err := http.NewRequest("GET", ims.imdsServer+consts.ImdsInstanceURI, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Add("Metadata", "True")
|
||||
req.Header.Add("User-Agent", "golang/kubernetes-cloud-provider")
|
||||
|
||||
q := req.URL.Query()
|
||||
q.Add("format", "json")
|
||||
q.Add("api-version", consts.ImdsInstanceAPIVersion)
|
||||
req.URL.RawQuery = q.Encode()
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("failure of getting instance metadata with response %q", resp.Status)
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
obj := InstanceMetadata{}
|
||||
err = json.Unmarshal(data, &obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &obj, nil
|
||||
}
|
||||
|
||||
func (ims *InstanceMetadataService) getLoadBalancerMetadata() (*LoadBalancerMetadata, error) {
|
||||
req, err := http.NewRequest("GET", ims.imdsServer+consts.ImdsLoadBalancerURI, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Add("Metadata", "True")
|
||||
req.Header.Add("User-Agent", "golang/kubernetes-cloud-provider")
|
||||
|
||||
q := req.URL.Query()
|
||||
q.Add("format", "json")
|
||||
q.Add("api-version", consts.ImdsLoadBalancerAPIVersion)
|
||||
req.URL.RawQuery = q.Encode()
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("failure of getting loadbalancer metadata with response %q", resp.Status)
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
obj := LoadBalancerMetadata{}
|
||||
err = json.Unmarshal(data, &obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &obj, nil
|
||||
}
|
||||
|
||||
// GetMetadata gets instance metadata from cache.
|
||||
// crt determines if we can get data from stalled cache/need fresh if cache expired.
|
||||
func (ims *InstanceMetadataService) GetMetadata(crt azcache.AzureCacheReadType) (*InstanceMetadata, error) {
|
||||
cache, err := ims.imsCache.Get(consts.MetadataCacheKey, crt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Cache shouldn't be nil, but added a check in case something is wrong.
|
||||
if cache == nil {
|
||||
return nil, fmt.Errorf("failure of getting instance metadata")
|
||||
}
|
||||
|
||||
if metadata, ok := cache.(*InstanceMetadata); ok {
|
||||
return metadata, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("failure of getting instance metadata")
|
||||
}
|
||||
542
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_instances.go
generated
vendored
Normal file
542
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_instances.go
generated
vendored
Normal file
|
|
@ -0,0 +1,542 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-12-01/compute"
|
||||
azcache "sigs.k8s.io/cloud-provider-azure/pkg/cache"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/consts"
|
||||
)
|
||||
|
||||
const (
|
||||
vmPowerStatePrefix = "PowerState/"
|
||||
vmPowerStateStopped = "stopped"
|
||||
vmPowerStateDeallocated = "deallocated"
|
||||
vmPowerStateDeallocating = "deallocating"
|
||||
|
||||
// nodeNameEnvironmentName is the environment variable name for getting node name.
|
||||
// It is only used for out-of-tree cloud provider.
|
||||
nodeNameEnvironmentName = "NODE_NAME"
|
||||
)
|
||||
|
||||
var (
|
||||
errNodeNotInitialized = fmt.Errorf("providerID is empty, the node is not initialized yet")
|
||||
)
|
||||
|
||||
func (az *Cloud) addressGetter(nodeName types.NodeName) ([]v1.NodeAddress, error) {
|
||||
ip, publicIP, err := az.getIPForMachine(nodeName)
|
||||
if err != nil {
|
||||
klog.V(2).Infof("NodeAddresses(%s) abort backoff: %v", nodeName, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addresses := []v1.NodeAddress{
|
||||
{Type: v1.NodeInternalIP, Address: ip},
|
||||
{Type: v1.NodeHostName, Address: string(nodeName)},
|
||||
}
|
||||
if len(publicIP) > 0 {
|
||||
addresses = append(addresses, v1.NodeAddress{
|
||||
Type: v1.NodeExternalIP,
|
||||
Address: publicIP,
|
||||
})
|
||||
}
|
||||
return addresses, nil
|
||||
}
|
||||
|
||||
// NodeAddresses returns the addresses of the specified instance.
|
||||
func (az *Cloud) NodeAddresses(ctx context.Context, name types.NodeName) ([]v1.NodeAddress, error) {
|
||||
// Returns nil for unmanaged nodes because azure cloud provider couldn't fetch information for them.
|
||||
unmanaged, err := az.IsNodeUnmanaged(string(name))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if unmanaged {
|
||||
klog.V(4).Infof("NodeAddresses: omitting unmanaged node %q", name)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if az.UseInstanceMetadata {
|
||||
metadata, err := az.Metadata.GetMetadata(azcache.CacheReadTypeDefault)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if metadata.Compute == nil || metadata.Network == nil {
|
||||
return nil, fmt.Errorf("failure of getting instance metadata")
|
||||
}
|
||||
|
||||
isLocalInstance, err := az.isCurrentInstance(name, metadata.Compute.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Not local instance, get addresses from Azure ARM API.
|
||||
if !isLocalInstance {
|
||||
if az.VMSet != nil {
|
||||
return az.addressGetter(name)
|
||||
}
|
||||
|
||||
// vmSet == nil indicates credentials are not provided.
|
||||
return nil, fmt.Errorf("no credentials provided for Azure cloud provider")
|
||||
}
|
||||
|
||||
return az.getLocalInstanceNodeAddresses(metadata.Network.Interface, string(name))
|
||||
}
|
||||
|
||||
return az.addressGetter(name)
|
||||
}
|
||||
|
||||
func (az *Cloud) getLocalInstanceNodeAddresses(netInterfaces []NetworkInterface, nodeName string) ([]v1.NodeAddress, error) {
|
||||
if len(netInterfaces) == 0 {
|
||||
return nil, fmt.Errorf("no interface is found for the instance")
|
||||
}
|
||||
|
||||
// Use ip address got from instance metadata.
|
||||
netInterface := netInterfaces[0]
|
||||
addresses := []v1.NodeAddress{
|
||||
{Type: v1.NodeHostName, Address: nodeName},
|
||||
}
|
||||
if len(netInterface.IPV4.IPAddress) > 0 && len(netInterface.IPV4.IPAddress[0].PrivateIP) > 0 {
|
||||
address := netInterface.IPV4.IPAddress[0]
|
||||
addresses = append(addresses, v1.NodeAddress{
|
||||
Type: v1.NodeInternalIP,
|
||||
Address: address.PrivateIP,
|
||||
})
|
||||
if len(address.PublicIP) > 0 {
|
||||
addresses = append(addresses, v1.NodeAddress{
|
||||
Type: v1.NodeExternalIP,
|
||||
Address: address.PublicIP,
|
||||
})
|
||||
}
|
||||
}
|
||||
if len(netInterface.IPV6.IPAddress) > 0 && len(netInterface.IPV6.IPAddress[0].PrivateIP) > 0 {
|
||||
address := netInterface.IPV6.IPAddress[0]
|
||||
addresses = append(addresses, v1.NodeAddress{
|
||||
Type: v1.NodeInternalIP,
|
||||
Address: address.PrivateIP,
|
||||
})
|
||||
if len(address.PublicIP) > 0 {
|
||||
addresses = append(addresses, v1.NodeAddress{
|
||||
Type: v1.NodeExternalIP,
|
||||
Address: address.PublicIP,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if len(addresses) == 1 {
|
||||
// No IP addresses is got from instance metadata service, clean up cache and report errors.
|
||||
_ = az.Metadata.imsCache.Delete(consts.MetadataCacheKey)
|
||||
return nil, fmt.Errorf("get empty IP addresses from instance metadata service")
|
||||
}
|
||||
return addresses, nil
|
||||
}
|
||||
|
||||
// NodeAddressesByProviderID returns the node addresses of an instances with the specified unique providerID
|
||||
// This method will not be called from the node that is requesting this ID. i.e. metadata service
|
||||
// and other local methods cannot be used here
|
||||
func (az *Cloud) NodeAddressesByProviderID(ctx context.Context, providerID string) ([]v1.NodeAddress, error) {
|
||||
if providerID == "" {
|
||||
return nil, errNodeNotInitialized
|
||||
}
|
||||
|
||||
// Returns nil for unmanaged nodes because azure cloud provider couldn't fetch information for them.
|
||||
if az.IsNodeUnmanagedByProviderID(providerID) {
|
||||
klog.V(4).Infof("NodeAddressesByProviderID: omitting unmanaged node %q", providerID)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if az.VMSet == nil {
|
||||
// vmSet == nil indicates credentials are not provided.
|
||||
return nil, fmt.Errorf("no credentials provided for Azure cloud provider")
|
||||
}
|
||||
|
||||
name, err := az.VMSet.GetNodeNameByProviderID(providerID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return az.NodeAddresses(ctx, name)
|
||||
}
|
||||
|
||||
// InstanceExistsByProviderID returns true if the instance with the given provider id still exists and is running.
|
||||
// If false is returned with no error, the instance will be immediately deleted by the cloud controller manager.
|
||||
func (az *Cloud) InstanceExistsByProviderID(ctx context.Context, providerID string) (bool, error) {
|
||||
if providerID == "" {
|
||||
return false, errNodeNotInitialized
|
||||
}
|
||||
|
||||
// Returns true for unmanaged nodes because azure cloud provider always assumes them exists.
|
||||
if az.IsNodeUnmanagedByProviderID(providerID) {
|
||||
klog.V(4).Infof("InstanceExistsByProviderID: assuming unmanaged node %q exists", providerID)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if az.VMSet == nil {
|
||||
// vmSet == nil indicates credentials are not provided.
|
||||
return false, fmt.Errorf("no credentials provided for Azure cloud provider")
|
||||
}
|
||||
|
||||
name, err := az.VMSet.GetNodeNameByProviderID(providerID)
|
||||
if err != nil {
|
||||
if errors.Is(err, cloudprovider.InstanceNotFound) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
_, err = az.InstanceID(ctx, name)
|
||||
if err != nil {
|
||||
if errors.Is(err, cloudprovider.InstanceNotFound) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// InstanceExists returns true if the instance for the given node exists according to the cloud provider.
|
||||
// Use the node.name or node.spec.providerID field to find the node in the cloud provider.
|
||||
func (az *Cloud) InstanceExists(ctx context.Context, node *v1.Node) (bool, error) {
|
||||
if node == nil {
|
||||
return false, nil
|
||||
}
|
||||
providerID := node.Spec.ProviderID
|
||||
if providerID == "" {
|
||||
var err error
|
||||
providerID, err = cloudprovider.GetInstanceProviderID(ctx, az, types.NodeName(node.Name))
|
||||
if err != nil {
|
||||
klog.Errorf("InstanceExists: failed to get the provider ID by node name %s: %v", node.Name, err)
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
return az.InstanceExistsByProviderID(ctx, providerID)
|
||||
}
|
||||
|
||||
// InstanceShutdownByProviderID returns true if the instance is in safe state to detach volumes
|
||||
func (az *Cloud) InstanceShutdownByProviderID(ctx context.Context, providerID string) (bool, error) {
|
||||
if providerID == "" {
|
||||
return false, nil
|
||||
}
|
||||
if az.VMSet == nil {
|
||||
// vmSet == nil indicates credentials are not provided.
|
||||
return false, fmt.Errorf("no credentials provided for Azure cloud provider")
|
||||
}
|
||||
|
||||
nodeName, err := az.VMSet.GetNodeNameByProviderID(providerID)
|
||||
if err != nil {
|
||||
// Returns false, so the controller manager will continue to check InstanceExistsByProviderID().
|
||||
if errors.Is(err, cloudprovider.InstanceNotFound) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
powerStatus, err := az.VMSet.GetPowerStatusByNodeName(string(nodeName))
|
||||
if err != nil {
|
||||
// Returns false, so the controller manager will continue to check InstanceExistsByProviderID().
|
||||
if errors.Is(err, cloudprovider.InstanceNotFound) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
klog.V(3).Infof("InstanceShutdownByProviderID gets power status %q for node %q", powerStatus, nodeName)
|
||||
|
||||
provisioningState, err := az.VMSet.GetProvisioningStateByNodeName(string(nodeName))
|
||||
if err != nil {
|
||||
// Returns false, so the controller manager will continue to check InstanceExistsByProviderID().
|
||||
if errors.Is(err, cloudprovider.InstanceNotFound) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
klog.V(3).Infof("InstanceShutdownByProviderID gets provisioning state %q for node %q", provisioningState, nodeName)
|
||||
|
||||
status := strings.ToLower(powerStatus)
|
||||
provisioningSucceeded := strings.EqualFold(strings.ToLower(provisioningState), strings.ToLower(string(compute.ProvisioningStateSucceeded)))
|
||||
return provisioningSucceeded && (status == vmPowerStateStopped || status == vmPowerStateDeallocated || status == vmPowerStateDeallocating), nil
|
||||
}
|
||||
|
||||
// InstanceShutdown returns true if the instance is shutdown according to the cloud provider.
|
||||
// Use the node.name or node.spec.providerID field to find the node in the cloud provider.
|
||||
func (az *Cloud) InstanceShutdown(ctx context.Context, node *v1.Node) (bool, error) {
|
||||
if node == nil {
|
||||
return false, nil
|
||||
}
|
||||
providerID := node.Spec.ProviderID
|
||||
if providerID == "" {
|
||||
var err error
|
||||
providerID, err = cloudprovider.GetInstanceProviderID(ctx, az, types.NodeName(node.Name))
|
||||
if err != nil {
|
||||
// Returns false, so the controller manager will continue to check InstanceExistsByProviderID().
|
||||
if strings.Contains(err.Error(), cloudprovider.InstanceNotFound.Error()) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
klog.Errorf("InstanceShutdown: failed to get the provider ID by node name %s: %v", node.Name, err)
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
return az.InstanceShutdownByProviderID(ctx, providerID)
|
||||
}
|
||||
|
||||
func (az *Cloud) isCurrentInstance(name types.NodeName, metadataVMName string) (bool, error) {
|
||||
var err error
|
||||
nodeName := mapNodeNameToVMName(name)
|
||||
|
||||
// VMSS vmName is not same with hostname, use hostname instead.
|
||||
if az.VMType == consts.VMTypeVMSS {
|
||||
metadataVMName, err = os.Hostname()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Use name from env variable "NODE_NAME" if it is set.
|
||||
nodeNameEnv := os.Getenv(nodeNameEnvironmentName)
|
||||
if nodeNameEnv != "" {
|
||||
metadataVMName = nodeNameEnv
|
||||
}
|
||||
}
|
||||
|
||||
metadataVMName = strings.ToLower(metadataVMName)
|
||||
return metadataVMName == nodeName, nil
|
||||
}
|
||||
|
||||
// InstanceID returns the cloud provider ID of the specified instance.
|
||||
// Note that if the instance does not exist or is no longer running, we must return ("", cloudprovider.InstanceNotFound)
|
||||
func (az *Cloud) InstanceID(ctx context.Context, name types.NodeName) (string, error) {
|
||||
nodeName := mapNodeNameToVMName(name)
|
||||
unmanaged, err := az.IsNodeUnmanaged(nodeName)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if unmanaged {
|
||||
// InstanceID is same with nodeName for unmanaged nodes.
|
||||
klog.V(4).Infof("InstanceID: getting ID %q for unmanaged node %q", name, name)
|
||||
return nodeName, nil
|
||||
}
|
||||
|
||||
if az.UseInstanceMetadata {
|
||||
metadata, err := az.Metadata.GetMetadata(azcache.CacheReadTypeDefault)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if metadata.Compute == nil {
|
||||
return "", fmt.Errorf("failure of getting instance metadata")
|
||||
}
|
||||
|
||||
isLocalInstance, err := az.isCurrentInstance(name, metadata.Compute.Name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Not local instance, get instanceID from Azure ARM API.
|
||||
if !isLocalInstance {
|
||||
if az.VMSet != nil {
|
||||
return az.VMSet.GetInstanceIDByNodeName(nodeName)
|
||||
}
|
||||
|
||||
// vmSet == nil indicates credentials are not provided.
|
||||
return "", fmt.Errorf("no credentials provided for Azure cloud provider")
|
||||
}
|
||||
return az.getLocalInstanceProviderID(metadata, nodeName)
|
||||
}
|
||||
|
||||
return az.VMSet.GetInstanceIDByNodeName(nodeName)
|
||||
}
|
||||
|
||||
func (az *Cloud) getLocalInstanceProviderID(metadata *InstanceMetadata, nodeName string) (string, error) {
|
||||
// Get resource group name and subscription ID.
|
||||
resourceGroup := strings.ToLower(metadata.Compute.ResourceGroup)
|
||||
subscriptionID := strings.ToLower(metadata.Compute.SubscriptionID)
|
||||
|
||||
// Compose instanceID based on nodeName for standard instance.
|
||||
if metadata.Compute.VMScaleSetName == "" {
|
||||
return az.getStandardMachineID(subscriptionID, resourceGroup, nodeName), nil
|
||||
}
|
||||
|
||||
// Get scale set name and instanceID from vmName for vmss.
|
||||
ssName, instanceID, err := extractVmssVMName(metadata.Compute.Name)
|
||||
if err != nil {
|
||||
if errors.Is(err, ErrorNotVmssInstance) {
|
||||
// Compose machineID for standard Node.
|
||||
return az.getStandardMachineID(subscriptionID, resourceGroup, nodeName), nil
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
// Compose instanceID based on ssName and instanceID for vmss instance.
|
||||
return az.getVmssMachineID(subscriptionID, resourceGroup, ssName, instanceID), nil
|
||||
}
|
||||
|
||||
// InstanceTypeByProviderID returns the cloudprovider instance type of the node with the specified unique providerID
|
||||
// This method will not be called from the node that is requesting this ID. i.e. metadata service
|
||||
// and other local methods cannot be used here
|
||||
func (az *Cloud) InstanceTypeByProviderID(ctx context.Context, providerID string) (string, error) {
|
||||
if providerID == "" {
|
||||
return "", errNodeNotInitialized
|
||||
}
|
||||
|
||||
// Returns "" for unmanaged nodes because azure cloud provider couldn't fetch information for them.
|
||||
if az.IsNodeUnmanagedByProviderID(providerID) {
|
||||
klog.V(4).Infof("InstanceTypeByProviderID: omitting unmanaged node %q", providerID)
|
||||
return "", nil
|
||||
}
|
||||
|
||||
if az.VMSet == nil {
|
||||
// vmSet == nil indicates credentials are not provided.
|
||||
return "", fmt.Errorf("no credentials provided for Azure cloud provider")
|
||||
}
|
||||
|
||||
name, err := az.VMSet.GetNodeNameByProviderID(providerID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return az.InstanceType(ctx, name)
|
||||
}
|
||||
|
||||
// InstanceType returns the type of the specified instance.
|
||||
// Note that if the instance does not exist or is no longer running, we must return ("", cloudprovider.InstanceNotFound)
|
||||
// (Implementer Note): This is used by kubelet. Kubelet will label the node. Real log from kubelet:
|
||||
// Adding node label from cloud provider: beta.kubernetes.io/instance-type=[value]
|
||||
func (az *Cloud) InstanceType(ctx context.Context, name types.NodeName) (string, error) {
|
||||
// Returns "" for unmanaged nodes because azure cloud provider couldn't fetch information for them.
|
||||
unmanaged, err := az.IsNodeUnmanaged(string(name))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if unmanaged {
|
||||
klog.V(4).Infof("InstanceType: omitting unmanaged node %q", name)
|
||||
return "", nil
|
||||
}
|
||||
|
||||
if az.UseInstanceMetadata {
|
||||
metadata, err := az.Metadata.GetMetadata(azcache.CacheReadTypeDefault)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if metadata.Compute == nil {
|
||||
return "", fmt.Errorf("failure of getting instance metadata")
|
||||
}
|
||||
|
||||
isLocalInstance, err := az.isCurrentInstance(name, metadata.Compute.Name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if !isLocalInstance {
|
||||
if az.VMSet != nil {
|
||||
return az.VMSet.GetInstanceTypeByNodeName(string(name))
|
||||
}
|
||||
|
||||
// vmSet == nil indicates credentials are not provided.
|
||||
return "", fmt.Errorf("no credentials provided for Azure cloud provider")
|
||||
}
|
||||
|
||||
if metadata.Compute.VMSize != "" {
|
||||
return metadata.Compute.VMSize, nil
|
||||
}
|
||||
}
|
||||
|
||||
if az.VMSet == nil {
|
||||
// vmSet == nil indicates credentials are not provided.
|
||||
return "", fmt.Errorf("no credentials provided for Azure cloud provider")
|
||||
}
|
||||
|
||||
return az.VMSet.GetInstanceTypeByNodeName(string(name))
|
||||
}
|
||||
|
||||
// AddSSHKeyToAllInstances adds an SSH public key as a legal identity for all instances
|
||||
// expected format for the key is standard ssh-keygen format: <protocol> <blob>
|
||||
func (az *Cloud) AddSSHKeyToAllInstances(ctx context.Context, user string, keyData []byte) error {
|
||||
return cloudprovider.NotImplemented
|
||||
}
|
||||
|
||||
// CurrentNodeName returns the name of the node we are currently running on.
|
||||
// On Azure this is the hostname, so we just return the hostname.
|
||||
func (az *Cloud) CurrentNodeName(ctx context.Context, hostname string) (types.NodeName, error) {
|
||||
return types.NodeName(hostname), nil
|
||||
}
|
||||
|
||||
// InstanceMetadata returns the instance's metadata. The values returned in InstanceMetadata are
|
||||
// translated into specific fields in the Node object on registration.
|
||||
// Use the node.name or node.spec.providerID field to find the node in the cloud provider.
|
||||
func (az *Cloud) InstanceMetadata(ctx context.Context, node *v1.Node) (*cloudprovider.InstanceMetadata, error) {
|
||||
if node == nil {
|
||||
return &cloudprovider.InstanceMetadata{}, nil
|
||||
}
|
||||
|
||||
meta := cloudprovider.InstanceMetadata{}
|
||||
|
||||
if node.Spec.ProviderID != "" {
|
||||
meta.ProviderID = node.Spec.ProviderID
|
||||
} else {
|
||||
providerID, err := cloudprovider.GetInstanceProviderID(ctx, az, types.NodeName(node.Name))
|
||||
if err != nil {
|
||||
klog.Errorf("InstanceMetadata: failed to get the provider ID by node name %s: %v", node.Name, err)
|
||||
return nil, err
|
||||
}
|
||||
meta.ProviderID = providerID
|
||||
}
|
||||
|
||||
instanceType, err := az.InstanceType(ctx, types.NodeName(node.Name))
|
||||
if err != nil {
|
||||
klog.Errorf("InstanceMetadata: failed to get the instance type of %s: %v", node.Name, err)
|
||||
return &cloudprovider.InstanceMetadata{}, err
|
||||
}
|
||||
meta.InstanceType = instanceType
|
||||
|
||||
nodeAddresses, err := az.NodeAddresses(ctx, types.NodeName(node.Name))
|
||||
if err != nil {
|
||||
klog.Errorf("InstanceMetadata: failed to get the node address of %s: %v", node.Name, err)
|
||||
return &cloudprovider.InstanceMetadata{}, err
|
||||
}
|
||||
meta.NodeAddresses = nodeAddresses
|
||||
|
||||
zone, err := az.GetZoneByNodeName(ctx, types.NodeName(node.Name))
|
||||
if err != nil {
|
||||
klog.Errorf("InstanceMetadata: failed to get the node zone of %s: %v", node.Name, err)
|
||||
return &cloudprovider.InstanceMetadata{}, err
|
||||
}
|
||||
meta.Zone = zone.FailureDomain
|
||||
meta.Region = zone.Region
|
||||
|
||||
return &meta, nil
|
||||
}
|
||||
|
||||
// mapNodeNameToVMName maps a k8s NodeName to an Azure VM Name
|
||||
// This is a simple string cast.
|
||||
func mapNodeNameToVMName(nodeName types.NodeName) string {
|
||||
return string(nodeName)
|
||||
}
|
||||
3201
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_loadbalancer.go
generated
vendored
Normal file
3201
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_loadbalancer.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
445
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_loadbalancer_backendpool.go
generated
vendored
Normal file
445
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_loadbalancer_backendpool.go
generated
vendored
Normal file
|
|
@ -0,0 +1,445 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
//go:generate sh -c "mockgen -destination=$GOPATH/src/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_mock_loadbalancer_backendpool.go -source=$GOPATH/src/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_loadbalancer_backendpool.go -package=provider BackendPool"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
"k8s.io/klog/v2"
|
||||
utilnet "k8s.io/utils/net"
|
||||
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/consts"
|
||||
)
|
||||
|
||||
type BackendPool interface {
|
||||
// EnsureHostsInPool ensures the nodes join the backend pool of the load balancer
|
||||
EnsureHostsInPool(service *v1.Service, nodes []*v1.Node, backendPoolID, vmSetName, clusterName, lbName string, backendPool network.BackendAddressPool) error
|
||||
|
||||
// CleanupVMSetFromBackendPoolByCondition removes nodes of the unwanted vmSet from the lb backend pool.
|
||||
// This is needed in two scenarios:
|
||||
// 1. When migrating from single SLB to multiple SLBs, the existing
|
||||
// SLB's backend pool contains nodes from different agent pools, while we only want the
|
||||
// nodes from the primary agent pool to join the backend pool.
|
||||
// 2. When migrating from dedicated SLB to shared SLB (or vice versa), we should move the vmSet from
|
||||
// one SLB to another one.
|
||||
CleanupVMSetFromBackendPoolByCondition(slb *network.LoadBalancer, service *v1.Service, nodes []*v1.Node, clusterName string, shouldRemoveVMSetFromSLB func(string) bool) (*network.LoadBalancer, error)
|
||||
|
||||
// ReconcileBackendPools creates the inbound backend pool if it is not existed, and removes nodes that are supposed to be
|
||||
// excluded from the load balancers.
|
||||
ReconcileBackendPools(clusterName string, service *v1.Service, lb *network.LoadBalancer) (bool, bool, error)
|
||||
}
|
||||
|
||||
type backendPoolTypeNodeIPConfig struct {
|
||||
*Cloud
|
||||
}
|
||||
|
||||
func newBackendPoolTypeNodeIPConfig(c *Cloud) BackendPool {
|
||||
return &backendPoolTypeNodeIPConfig{c}
|
||||
}
|
||||
|
||||
func (bc *backendPoolTypeNodeIPConfig) EnsureHostsInPool(service *v1.Service, nodes []*v1.Node, backendPoolID, vmSetName, clusterName, lbName string, backendPool network.BackendAddressPool) error {
|
||||
return bc.VMSet.EnsureHostsInPool(service, nodes, backendPoolID, vmSetName)
|
||||
}
|
||||
|
||||
func (bc *backendPoolTypeNodeIPConfig) CleanupVMSetFromBackendPoolByCondition(slb *network.LoadBalancer, service *v1.Service, nodes []*v1.Node, clusterName string, shouldRemoveVMSetFromSLB func(string) bool) (*network.LoadBalancer, error) {
|
||||
lbBackendPoolName := getBackendPoolName(clusterName, service)
|
||||
lbResourceGroup := bc.getLoadBalancerResourceGroup()
|
||||
lbBackendPoolID := bc.getBackendPoolID(to.String(slb.Name), lbResourceGroup, lbBackendPoolName)
|
||||
newBackendPools := make([]network.BackendAddressPool, 0)
|
||||
if slb.LoadBalancerPropertiesFormat != nil && slb.BackendAddressPools != nil {
|
||||
newBackendPools = *slb.BackendAddressPools
|
||||
}
|
||||
vmSetNameToBackendIPConfigurationsToBeDeleted := make(map[string][]network.InterfaceIPConfiguration)
|
||||
|
||||
for j, bp := range newBackendPools {
|
||||
if strings.EqualFold(to.String(bp.Name), lbBackendPoolName) {
|
||||
klog.V(2).Infof("bc.CleanupVMSetFromBackendPoolByCondition: checking the backend pool %s from standard load balancer %s", to.String(bp.Name), to.String(slb.Name))
|
||||
if bp.BackendAddressPoolPropertiesFormat != nil && bp.BackendIPConfigurations != nil {
|
||||
for i := len(*bp.BackendIPConfigurations) - 1; i >= 0; i-- {
|
||||
ipConf := (*bp.BackendIPConfigurations)[i]
|
||||
ipConfigID := to.String(ipConf.ID)
|
||||
_, vmSetName, err := bc.VMSet.GetNodeNameByIPConfigurationID(ipConfigID)
|
||||
if err != nil && !errors.Is(err, cloudprovider.InstanceNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if shouldRemoveVMSetFromSLB(vmSetName) {
|
||||
klog.V(2).Infof("bc.CleanupVMSetFromBackendPoolByCondition: found unwanted vmSet %s, decouple it from the LB", vmSetName)
|
||||
// construct a backendPool that only contains the IP config of the node to be deleted
|
||||
interfaceIPConfigToBeDeleted := network.InterfaceIPConfiguration{
|
||||
ID: to.StringPtr(ipConfigID),
|
||||
}
|
||||
vmSetNameToBackendIPConfigurationsToBeDeleted[vmSetName] = append(vmSetNameToBackendIPConfigurationsToBeDeleted[vmSetName], interfaceIPConfigToBeDeleted)
|
||||
*bp.BackendIPConfigurations = append((*bp.BackendIPConfigurations)[:i], (*bp.BackendIPConfigurations)[i+1:]...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newBackendPools[j] = bp
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for vmSetName := range vmSetNameToBackendIPConfigurationsToBeDeleted {
|
||||
backendIPConfigurationsToBeDeleted := vmSetNameToBackendIPConfigurationsToBeDeleted[vmSetName]
|
||||
backendpoolToBeDeleted := &[]network.BackendAddressPool{
|
||||
{
|
||||
ID: to.StringPtr(lbBackendPoolID),
|
||||
BackendAddressPoolPropertiesFormat: &network.BackendAddressPoolPropertiesFormat{
|
||||
BackendIPConfigurations: &backendIPConfigurationsToBeDeleted,
|
||||
},
|
||||
},
|
||||
}
|
||||
// decouple the backendPool from the node
|
||||
err := bc.VMSet.EnsureBackendPoolDeleted(service, lbBackendPoolID, vmSetName, backendpoolToBeDeleted, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
slb.BackendAddressPools = &newBackendPools
|
||||
// Proactively disable the etag to prevent etag mismatch error when putting lb later.
|
||||
// This could happen because when we remove the hosts from the lb, the nrp
|
||||
// would put the lb to remove the backend references as well.
|
||||
slb.Etag = nil
|
||||
}
|
||||
|
||||
return slb, nil
|
||||
}
|
||||
|
||||
func (bc *backendPoolTypeNodeIPConfig) ReconcileBackendPools(clusterName string, service *v1.Service, lb *network.LoadBalancer) (bool, bool, error) {
|
||||
var newBackendPools []network.BackendAddressPool
|
||||
var err error
|
||||
if lb.BackendAddressPools != nil {
|
||||
newBackendPools = *lb.BackendAddressPools
|
||||
}
|
||||
|
||||
foundBackendPool := false
|
||||
wantLb := true
|
||||
changed := false
|
||||
lbName := *lb.Name
|
||||
|
||||
serviceName := getServiceName(service)
|
||||
lbBackendPoolName := getBackendPoolName(clusterName, service)
|
||||
lbBackendPoolID := bc.getBackendPoolID(lbName, bc.getLoadBalancerResourceGroup(), lbBackendPoolName)
|
||||
vmSetName := bc.mapLoadBalancerNameToVMSet(lbName, clusterName)
|
||||
|
||||
for _, bp := range newBackendPools {
|
||||
if strings.EqualFold(*bp.Name, lbBackendPoolName) {
|
||||
klog.V(10).Infof("bc.ReconcileBackendPools for service (%s)(%t): lb backendpool - found wanted backendpool. not adding anything", serviceName, wantLb)
|
||||
foundBackendPool = true
|
||||
|
||||
var backendIPConfigurationsToBeDeleted []network.InterfaceIPConfiguration
|
||||
if bp.BackendAddressPoolPropertiesFormat != nil && bp.BackendIPConfigurations != nil {
|
||||
for _, ipConf := range *bp.BackendIPConfigurations {
|
||||
ipConfID := to.String(ipConf.ID)
|
||||
nodeName, _, err := bc.VMSet.GetNodeNameByIPConfigurationID(ipConfID)
|
||||
if err != nil && !errors.Is(err, cloudprovider.InstanceNotFound) {
|
||||
return false, false, err
|
||||
}
|
||||
|
||||
// If a node is not supposed to be included in the LB, it
|
||||
// would not be in the `nodes` slice. We need to check the nodes that
|
||||
// have been added to the LB's backendpool, find the unwanted ones and
|
||||
// delete them from the pool.
|
||||
shouldExcludeLoadBalancer, err := bc.ShouldNodeExcludedFromLoadBalancer(nodeName)
|
||||
if err != nil {
|
||||
klog.Errorf("bc.ReconcileBackendPools: ShouldNodeExcludedFromLoadBalancer(%s) failed with error: %v", nodeName, err)
|
||||
return false, false, err
|
||||
}
|
||||
if shouldExcludeLoadBalancer {
|
||||
klog.V(2).Infof("bc.ReconcileBackendPools for service (%s)(%t): lb backendpool - found unwanted node %s, decouple it from the LB %s", serviceName, wantLb, nodeName, lbName)
|
||||
// construct a backendPool that only contains the IP config of the node to be deleted
|
||||
backendIPConfigurationsToBeDeleted = append(backendIPConfigurationsToBeDeleted, network.InterfaceIPConfiguration{ID: to.StringPtr(ipConfID)})
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(backendIPConfigurationsToBeDeleted) > 0 {
|
||||
backendpoolToBeDeleted := &[]network.BackendAddressPool{
|
||||
{
|
||||
ID: to.StringPtr(lbBackendPoolID),
|
||||
BackendAddressPoolPropertiesFormat: &network.BackendAddressPoolPropertiesFormat{
|
||||
BackendIPConfigurations: &backendIPConfigurationsToBeDeleted,
|
||||
},
|
||||
},
|
||||
}
|
||||
// decouple the backendPool from the node
|
||||
err = bc.VMSet.EnsureBackendPoolDeleted(service, lbBackendPoolID, vmSetName, backendpoolToBeDeleted, false)
|
||||
if err != nil {
|
||||
return false, false, err
|
||||
}
|
||||
}
|
||||
break
|
||||
} else {
|
||||
klog.V(10).Infof("bc.ReconcileBackendPools for service (%s)(%t): lb backendpool - found unmanaged backendpool %s", serviceName, wantLb, *bp.Name)
|
||||
}
|
||||
}
|
||||
|
||||
isBackendPoolPreConfigured := bc.isBackendPoolPreConfigured(service)
|
||||
if !foundBackendPool {
|
||||
isBackendPoolPreConfigured = newBackendPool(lb, isBackendPoolPreConfigured, bc.PreConfiguredBackendPoolLoadBalancerTypes, getServiceName(service), getBackendPoolName(clusterName, service))
|
||||
changed = true
|
||||
}
|
||||
|
||||
return isBackendPoolPreConfigured, changed, err
|
||||
}
|
||||
|
||||
type backendPoolTypeNodeIP struct {
|
||||
*Cloud
|
||||
}
|
||||
|
||||
func newBackendPoolTypeNodeIP(c *Cloud) BackendPool {
|
||||
return &backendPoolTypeNodeIP{c}
|
||||
}
|
||||
|
||||
func (bi *backendPoolTypeNodeIP) EnsureHostsInPool(service *v1.Service, nodes []*v1.Node, backendPoolID, vmSetName, clusterName, lbName string, backendPool network.BackendAddressPool) error {
|
||||
vnetResourceGroup := bi.ResourceGroup
|
||||
if len(bi.VnetResourceGroup) > 0 {
|
||||
vnetResourceGroup = bi.VnetResourceGroup
|
||||
}
|
||||
vnetID := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/virtualNetworks/%s", bi.SubscriptionID, vnetResourceGroup, bi.VnetName)
|
||||
|
||||
changed := false
|
||||
lbBackendPoolName := getBackendPoolName(clusterName, service)
|
||||
if strings.EqualFold(to.String(backendPool.Name), lbBackendPoolName) &&
|
||||
backendPool.BackendAddressPoolPropertiesFormat != nil {
|
||||
if backendPool.LoadBalancerBackendAddresses == nil {
|
||||
lbBackendPoolAddresses := make([]network.LoadBalancerBackendAddress, 0)
|
||||
backendPool.LoadBalancerBackendAddresses = &lbBackendPoolAddresses
|
||||
}
|
||||
|
||||
existingIPs := sets.NewString()
|
||||
for _, loadBalancerBackendAddress := range *backendPool.LoadBalancerBackendAddresses {
|
||||
if loadBalancerBackendAddress.LoadBalancerBackendAddressPropertiesFormat != nil &&
|
||||
loadBalancerBackendAddress.IPAddress != nil {
|
||||
klog.V(4).Infof("bi.EnsureHostsInPool: found existing IP %s in the backend pool %s", to.String(loadBalancerBackendAddress.IPAddress), lbBackendPoolName)
|
||||
existingIPs.Insert(to.String(loadBalancerBackendAddress.IPAddress))
|
||||
}
|
||||
}
|
||||
|
||||
for _, node := range nodes {
|
||||
if isControlPlaneNode(node) {
|
||||
klog.V(4).Infof("bi.EnsureHostsInPool: skipping control plane node %s", node.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
var err error
|
||||
shouldSkip := false
|
||||
useSingleSLB := strings.EqualFold(bi.LoadBalancerSku, consts.LoadBalancerSkuStandard) && !bi.EnableMultipleStandardLoadBalancers
|
||||
if !useSingleSLB {
|
||||
vmSetName, err = bi.VMSet.GetNodeVMSetName(node)
|
||||
if err != nil {
|
||||
klog.Errorf("bi.EnsureHostsInPool: failed to get vmSet name by node name: %s", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
if !strings.EqualFold(vmSetName, bi.mapLoadBalancerNameToVMSet(lbName, clusterName)) {
|
||||
shouldSkip = true
|
||||
|
||||
lbNamePrefix := strings.TrimSuffix(lbName, consts.InternalLoadBalancerNameSuffix)
|
||||
if strings.EqualFold(lbNamePrefix, clusterName) &&
|
||||
strings.EqualFold(bi.LoadBalancerSku, consts.LoadBalancerSkuStandard) &&
|
||||
bi.getVMSetNamesSharingPrimarySLB().Has(vmSetName) {
|
||||
shouldSkip = false
|
||||
}
|
||||
}
|
||||
}
|
||||
if shouldSkip {
|
||||
klog.V(4).Infof("bi.EnsureHostsInPool: skipping attaching node %s to lb %s, because the vmSet of the node is %s", node.Name, lbName, vmSetName)
|
||||
continue
|
||||
}
|
||||
|
||||
privateIP := getNodePrivateIPAddress(service, node)
|
||||
if !existingIPs.Has(privateIP) {
|
||||
name := node.Name
|
||||
if utilnet.IsIPv6String(privateIP) {
|
||||
name = fmt.Sprintf("%s-ipv6", name)
|
||||
}
|
||||
|
||||
klog.V(4).Infof("bi.EnsureHostsInPool: adding %s with ip address %s", name, privateIP)
|
||||
*backendPool.LoadBalancerBackendAddresses = append(*backendPool.LoadBalancerBackendAddresses, network.LoadBalancerBackendAddress{
|
||||
Name: to.StringPtr(name),
|
||||
LoadBalancerBackendAddressPropertiesFormat: &network.LoadBalancerBackendAddressPropertiesFormat{
|
||||
IPAddress: to.StringPtr(privateIP),
|
||||
VirtualNetwork: &network.SubResource{ID: to.StringPtr(vnetID)},
|
||||
},
|
||||
})
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if changed {
|
||||
klog.V(2).Infof("bi.EnsureHostsInPool: updating backend pool %s of load balancer %s", lbBackendPoolName, lbName)
|
||||
if err := bi.CreateOrUpdateLBBackendPool(lbName, backendPool); err != nil {
|
||||
return fmt.Errorf("bi.EnsureHostsInPool: failed to update backend pool %s: %w", lbBackendPoolName, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bi *backendPoolTypeNodeIP) CleanupVMSetFromBackendPoolByCondition(slb *network.LoadBalancer, service *v1.Service, nodes []*v1.Node, clusterName string, shouldRemoveVMSetFromSLB func(string) bool) (*network.LoadBalancer, error) {
|
||||
lbBackendPoolName := getBackendPoolName(clusterName, service)
|
||||
newBackendPools := make([]network.BackendAddressPool, 0)
|
||||
if slb.LoadBalancerPropertiesFormat != nil && slb.BackendAddressPools != nil {
|
||||
newBackendPools = *slb.BackendAddressPools
|
||||
}
|
||||
|
||||
var updatedPrivateIPs bool
|
||||
for j, bp := range newBackendPools {
|
||||
if strings.EqualFold(to.String(bp.Name), lbBackendPoolName) {
|
||||
klog.V(2).Infof("bi.CleanupVMSetFromBackendPoolByCondition: checking the backend pool %s from standard load balancer %s", to.String(bp.Name), to.String(slb.Name))
|
||||
vmIPsToBeDeleted := sets.NewString()
|
||||
for _, node := range nodes {
|
||||
vmSetName, err := bi.VMSet.GetNodeVMSetName(node)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if shouldRemoveVMSetFromSLB(vmSetName) {
|
||||
privateIP := getNodePrivateIPAddress(service, node)
|
||||
klog.V(4).Infof("bi.CleanupVMSetFromBackendPoolByCondition: removing ip %s from the backend pool %s", privateIP, lbBackendPoolName)
|
||||
vmIPsToBeDeleted.Insert(privateIP)
|
||||
}
|
||||
}
|
||||
|
||||
if bp.BackendAddressPoolPropertiesFormat != nil && bp.LoadBalancerBackendAddresses != nil {
|
||||
for i := len(*bp.LoadBalancerBackendAddresses) - 1; i >= 0; i-- {
|
||||
if (*bp.LoadBalancerBackendAddresses)[i].LoadBalancerBackendAddressPropertiesFormat != nil &&
|
||||
vmIPsToBeDeleted.Has(to.String((*bp.LoadBalancerBackendAddresses)[i].IPAddress)) {
|
||||
*bp.LoadBalancerBackendAddresses = append((*bp.LoadBalancerBackendAddresses)[:i], (*bp.LoadBalancerBackendAddresses)[i+1:]...)
|
||||
updatedPrivateIPs = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newBackendPools[j] = bp
|
||||
break
|
||||
}
|
||||
}
|
||||
if updatedPrivateIPs {
|
||||
klog.V(2).Infof("bi.CleanupVMSetFromBackendPoolByCondition: updating lb %s since there are private IP updates", to.String(slb.Name))
|
||||
slb.BackendAddressPools = &newBackendPools
|
||||
|
||||
for _, backendAddressPool := range *slb.BackendAddressPools {
|
||||
if strings.EqualFold(lbBackendPoolName, to.String(backendAddressPool.Name)) {
|
||||
if err := bi.CreateOrUpdateLBBackendPool(to.String(slb.Name), backendAddressPool); err != nil {
|
||||
return nil, fmt.Errorf("bi.CleanupVMSetFromBackendPoolByCondition: failed to create or update backend pool %s: %w", lbBackendPoolName, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return slb, nil
|
||||
}
|
||||
|
||||
func (bi *backendPoolTypeNodeIP) ReconcileBackendPools(clusterName string, service *v1.Service, lb *network.LoadBalancer) (bool, bool, error) {
|
||||
var newBackendPools []network.BackendAddressPool
|
||||
var err error
|
||||
if lb.BackendAddressPools != nil {
|
||||
newBackendPools = *lb.BackendAddressPools
|
||||
}
|
||||
|
||||
foundBackendPool := false
|
||||
wantLb := true
|
||||
changed := false
|
||||
lbName := *lb.Name
|
||||
serviceName := getServiceName(service)
|
||||
lbBackendPoolName := getBackendPoolName(clusterName, service)
|
||||
|
||||
for i, bp := range newBackendPools {
|
||||
if strings.EqualFold(*bp.Name, lbBackendPoolName) {
|
||||
klog.V(10).Infof("bi.ReconcileBackendPools for service (%s)(%t): lb backendpool - found wanted backendpool. not adding anything", serviceName, wantLb)
|
||||
foundBackendPool = true
|
||||
|
||||
var nodeIPAddressesToBeDeleted []string
|
||||
for nodeName := range bi.excludeLoadBalancerNodes {
|
||||
for ip := range bi.nodePrivateIPs[nodeName] {
|
||||
klog.V(2).Infof("bi.ReconcileBackendPools for service (%s)(%t): lb backendpool - found unwanted node private IP %s, decouple it from the LB %s", serviceName, wantLb, ip, lbName)
|
||||
nodeIPAddressesToBeDeleted = append(nodeIPAddressesToBeDeleted, ip)
|
||||
}
|
||||
}
|
||||
if len(nodeIPAddressesToBeDeleted) > 0 {
|
||||
updated := removeNodeIPAddressesFromBackendPool(bp, nodeIPAddressesToBeDeleted)
|
||||
if updated {
|
||||
(*lb.BackendAddressPools)[i] = bp
|
||||
if err := bi.CreateOrUpdateLBBackendPool(lbName, bp); err != nil {
|
||||
return false, false, fmt.Errorf("bi.ReconcileBackendPools for service (%s)(%t): lb backendpool - failed to update backend pool %s for load balancer %s: %w", serviceName, wantLb, lbBackendPoolName, lbName, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
} else {
|
||||
klog.V(10).Infof("bi.ReconcileBackendPools for service (%s)(%t): lb backendpool - found unmanaged backendpool %s", serviceName, wantLb, *bp.Name)
|
||||
}
|
||||
}
|
||||
|
||||
isBackendPoolPreConfigured := bi.isBackendPoolPreConfigured(service)
|
||||
if !foundBackendPool {
|
||||
isBackendPoolPreConfigured = newBackendPool(lb, isBackendPoolPreConfigured, bi.PreConfiguredBackendPoolLoadBalancerTypes, getServiceName(service), getBackendPoolName(clusterName, service))
|
||||
changed = true
|
||||
}
|
||||
|
||||
return isBackendPoolPreConfigured, changed, err
|
||||
}
|
||||
|
||||
func newBackendPool(lb *network.LoadBalancer, isBackendPoolPreConfigured bool, preConfiguredBackendPoolLoadBalancerTypes, serviceName, lbBackendPoolName string) bool {
|
||||
if isBackendPoolPreConfigured {
|
||||
klog.V(2).Infof("newBackendPool for service (%s)(true): lb backendpool - PreConfiguredBackendPoolLoadBalancerTypes %s has been set but can not find corresponding backend pool, ignoring it",
|
||||
serviceName,
|
||||
preConfiguredBackendPoolLoadBalancerTypes)
|
||||
isBackendPoolPreConfigured = false
|
||||
}
|
||||
|
||||
if lb.BackendAddressPools == nil {
|
||||
lb.BackendAddressPools = &[]network.BackendAddressPool{}
|
||||
}
|
||||
*lb.BackendAddressPools = append(*lb.BackendAddressPools, network.BackendAddressPool{
|
||||
Name: to.StringPtr(lbBackendPoolName),
|
||||
BackendAddressPoolPropertiesFormat: &network.BackendAddressPoolPropertiesFormat{},
|
||||
})
|
||||
|
||||
return isBackendPoolPreConfigured
|
||||
}
|
||||
|
||||
func removeNodeIPAddressesFromBackendPool(backendPool network.BackendAddressPool, nodeIPAddresses []string) bool {
|
||||
changed := false
|
||||
nodeIPsSet := sets.NewString(nodeIPAddresses...)
|
||||
if backendPool.BackendAddressPoolPropertiesFormat != nil &&
|
||||
backendPool.LoadBalancerBackendAddresses != nil {
|
||||
for i := len(*backendPool.LoadBalancerBackendAddresses) - 1; i >= 0; i-- {
|
||||
if (*backendPool.LoadBalancerBackendAddresses)[i].LoadBalancerBackendAddressPropertiesFormat != nil {
|
||||
ipAddress := to.String((*backendPool.LoadBalancerBackendAddresses)[i].IPAddress)
|
||||
if nodeIPsSet.Has(ipAddress) {
|
||||
klog.V(4).Infof("removeNodeIPAddressFromBackendPool: removing %s from the backend pool %s", ipAddress, to.String(backendPool.Name))
|
||||
*backendPool.LoadBalancerBackendAddresses = append((*backendPool.LoadBalancerBackendAddresses)[:i], (*backendPool.LoadBalancerBackendAddresses)[i+1:]...)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return changed
|
||||
}
|
||||
431
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_managedDiskController.go
generated
vendored
Normal file
431
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_managedDiskController.go
generated
vendored
Normal file
|
|
@ -0,0 +1,431 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-12-01/compute"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
kwait "k8s.io/apimachinery/pkg/util/wait"
|
||||
cloudvolume "k8s.io/cloud-provider/volume"
|
||||
volumehelpers "k8s.io/cloud-provider/volume/helpers"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/consts"
|
||||
)
|
||||
|
||||
//ManagedDiskController : managed disk controller struct
|
||||
type ManagedDiskController struct {
|
||||
common *controllerCommon
|
||||
}
|
||||
|
||||
// ManagedDiskOptions specifies the options of managed disks.
|
||||
type ManagedDiskOptions struct {
|
||||
// The SKU of storage account.
|
||||
StorageAccountType compute.DiskStorageAccountTypes
|
||||
// The name of the disk.
|
||||
DiskName string
|
||||
// The name of PVC.
|
||||
PVCName string
|
||||
// The name of resource group.
|
||||
ResourceGroup string
|
||||
// The AvailabilityZone to create the disk.
|
||||
AvailabilityZone string
|
||||
// The tags of the disk.
|
||||
Tags map[string]string
|
||||
// IOPS Caps for UltraSSD disk
|
||||
DiskIOPSReadWrite string
|
||||
// Throughput Cap (MBps) for UltraSSD disk
|
||||
DiskMBpsReadWrite string
|
||||
// if SourceResourceID is not empty, then it's a disk copy operation(for snapshot)
|
||||
SourceResourceID string
|
||||
// The type of source
|
||||
SourceType string
|
||||
// ResourceId of the disk encryption set to use for enabling encryption at rest.
|
||||
DiskEncryptionSetID string
|
||||
// The size in GB.
|
||||
SizeGB int
|
||||
// The maximum number of VMs that can attach to the disk at the same time. Value greater than one indicates a disk that can be mounted on multiple VMs at the same time.
|
||||
MaxShares int32
|
||||
// Logical sector size in bytes for Ultra disks
|
||||
LogicalSectorSize int32
|
||||
// SkipGetDiskOperation indicates whether skip GetDisk operation(mainly due to throttling)
|
||||
SkipGetDiskOperation bool
|
||||
// NetworkAccessPolicy - Possible values include: 'AllowAll', 'AllowPrivate', 'DenyAll'
|
||||
NetworkAccessPolicy compute.NetworkAccessPolicy
|
||||
// DiskAccessID - ARM id of the DiskAccess resource for using private endpoints on disks.
|
||||
DiskAccessID *string
|
||||
// BurstingEnabled - Set to true to enable bursting beyond the provisioned performance target of the disk.
|
||||
BurstingEnabled *bool
|
||||
}
|
||||
|
||||
//CreateManagedDisk : create managed disk
|
||||
func (c *ManagedDiskController) CreateManagedDisk(options *ManagedDiskOptions) (string, error) {
|
||||
var err error
|
||||
klog.V(4).Infof("azureDisk - creating new managed Name:%s StorageAccountType:%s Size:%v", options.DiskName, options.StorageAccountType, options.SizeGB)
|
||||
|
||||
var createZones []string
|
||||
if len(options.AvailabilityZone) > 0 {
|
||||
requestedZone := c.common.cloud.GetZoneID(options.AvailabilityZone)
|
||||
if requestedZone != "" {
|
||||
createZones = append(createZones, requestedZone)
|
||||
}
|
||||
}
|
||||
|
||||
// insert original tags to newTags
|
||||
newTags := make(map[string]*string)
|
||||
azureDDTag := "kubernetes-azure-dd"
|
||||
newTags[consts.CreatedByTag] = &azureDDTag
|
||||
if options.Tags != nil {
|
||||
for k, v := range options.Tags {
|
||||
// Azure won't allow / (forward slash) in tags
|
||||
newKey := strings.Replace(k, "/", "-", -1)
|
||||
newValue := strings.Replace(v, "/", "-", -1)
|
||||
newTags[newKey] = &newValue
|
||||
}
|
||||
}
|
||||
|
||||
diskSizeGB := int32(options.SizeGB)
|
||||
diskSku := options.StorageAccountType
|
||||
|
||||
creationData, err := getValidCreationData(c.common.subscriptionID, options.ResourceGroup, options.SourceResourceID, options.SourceType)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
diskProperties := compute.DiskProperties{
|
||||
DiskSizeGB: &diskSizeGB,
|
||||
CreationData: &creationData,
|
||||
BurstingEnabled: options.BurstingEnabled,
|
||||
}
|
||||
|
||||
if options.NetworkAccessPolicy != "" {
|
||||
diskProperties.NetworkAccessPolicy = options.NetworkAccessPolicy
|
||||
if options.NetworkAccessPolicy == compute.AllowPrivate {
|
||||
if options.DiskAccessID == nil {
|
||||
return "", fmt.Errorf("DiskAccessID should not be empty when NetworkAccessPolicy is AllowPrivate")
|
||||
}
|
||||
diskProperties.DiskAccessID = options.DiskAccessID
|
||||
} else {
|
||||
if options.DiskAccessID != nil {
|
||||
return "", fmt.Errorf("DiskAccessID(%s) must be empty when NetworkAccessPolicy(%s) is not AllowPrivate", *options.DiskAccessID, options.NetworkAccessPolicy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if diskSku == compute.UltraSSDLRS {
|
||||
diskIOPSReadWrite := int64(consts.DefaultDiskIOPSReadWrite)
|
||||
if options.DiskIOPSReadWrite != "" {
|
||||
v, err := strconv.Atoi(options.DiskIOPSReadWrite)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("AzureDisk - failed to parse DiskIOPSReadWrite: %w", err)
|
||||
}
|
||||
diskIOPSReadWrite = int64(v)
|
||||
}
|
||||
diskProperties.DiskIOPSReadWrite = to.Int64Ptr(diskIOPSReadWrite)
|
||||
|
||||
diskMBpsReadWrite := int64(consts.DefaultDiskMBpsReadWrite)
|
||||
if options.DiskMBpsReadWrite != "" {
|
||||
v, err := strconv.Atoi(options.DiskMBpsReadWrite)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("AzureDisk - failed to parse DiskMBpsReadWrite: %w", err)
|
||||
}
|
||||
diskMBpsReadWrite = int64(v)
|
||||
}
|
||||
diskProperties.DiskMBpsReadWrite = to.Int64Ptr(diskMBpsReadWrite)
|
||||
|
||||
if options.LogicalSectorSize != 0 {
|
||||
klog.V(2).Infof("AzureDisk - requested LogicalSectorSize: %v", options.LogicalSectorSize)
|
||||
diskProperties.CreationData.LogicalSectorSize = to.Int32Ptr(options.LogicalSectorSize)
|
||||
}
|
||||
} else {
|
||||
if options.DiskIOPSReadWrite != "" {
|
||||
return "", fmt.Errorf("AzureDisk - DiskIOPSReadWrite parameter is only applicable in UltraSSD_LRS disk type")
|
||||
}
|
||||
if options.DiskMBpsReadWrite != "" {
|
||||
return "", fmt.Errorf("AzureDisk - DiskMBpsReadWrite parameter is only applicable in UltraSSD_LRS disk type")
|
||||
}
|
||||
if options.LogicalSectorSize != 0 {
|
||||
return "", fmt.Errorf("AzureDisk - LogicalSectorSize parameter is only applicable in UltraSSD_LRS disk type")
|
||||
}
|
||||
}
|
||||
|
||||
if options.DiskEncryptionSetID != "" {
|
||||
if strings.Index(strings.ToLower(options.DiskEncryptionSetID), "/subscriptions/") != 0 {
|
||||
return "", fmt.Errorf("AzureDisk - format of DiskEncryptionSetID(%s) is incorrect, correct format: %s", options.DiskEncryptionSetID, consts.DiskEncryptionSetIDFormat)
|
||||
}
|
||||
diskProperties.Encryption = &compute.Encryption{
|
||||
DiskEncryptionSetID: &options.DiskEncryptionSetID,
|
||||
Type: compute.EncryptionTypeEncryptionAtRestWithCustomerKey,
|
||||
}
|
||||
}
|
||||
|
||||
if options.MaxShares > 1 {
|
||||
diskProperties.MaxShares = &options.MaxShares
|
||||
}
|
||||
|
||||
model := compute.Disk{
|
||||
Location: &c.common.location,
|
||||
Tags: newTags,
|
||||
Sku: &compute.DiskSku{
|
||||
Name: diskSku,
|
||||
},
|
||||
DiskProperties: &diskProperties,
|
||||
}
|
||||
|
||||
if el := c.common.extendedLocation; el != nil {
|
||||
model.ExtendedLocation = &compute.ExtendedLocation{
|
||||
Name: to.StringPtr(el.Name),
|
||||
Type: compute.ExtendedLocationTypes(el.Type),
|
||||
}
|
||||
}
|
||||
|
||||
if len(createZones) > 0 {
|
||||
model.Zones = &createZones
|
||||
}
|
||||
|
||||
if options.ResourceGroup == "" {
|
||||
options.ResourceGroup = c.common.resourceGroup
|
||||
}
|
||||
|
||||
cloud := c.common.cloud
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
rerr := cloud.DisksClient.CreateOrUpdate(ctx, options.ResourceGroup, options.DiskName, model)
|
||||
if rerr != nil {
|
||||
return "", rerr.Error()
|
||||
}
|
||||
|
||||
diskID := fmt.Sprintf(managedDiskPath, cloud.subscriptionID, options.ResourceGroup, options.DiskName)
|
||||
|
||||
if options.SkipGetDiskOperation {
|
||||
klog.Warningf("azureDisk - GetDisk(%s, StorageAccountType:%s) is throttled, unable to confirm provisioningState in poll process", options.DiskName, options.StorageAccountType)
|
||||
} else {
|
||||
err = kwait.ExponentialBackoff(defaultBackOff, func() (bool, error) {
|
||||
provisionState, id, err := c.GetDisk(options.ResourceGroup, options.DiskName)
|
||||
if err == nil {
|
||||
if id != "" {
|
||||
diskID = id
|
||||
}
|
||||
} else {
|
||||
// We are waiting for provisioningState==Succeeded
|
||||
// We don't want to hand-off managed disks to k8s while they are
|
||||
//still being provisioned, this is to avoid some race conditions
|
||||
return false, err
|
||||
}
|
||||
if strings.ToLower(provisionState) == "succeeded" {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
klog.Warningf("azureDisk - created new MD Name:%s StorageAccountType:%s Size:%v but was unable to confirm provisioningState in poll process", options.DiskName, options.StorageAccountType, options.SizeGB)
|
||||
}
|
||||
}
|
||||
|
||||
klog.V(2).Infof("azureDisk - created new MD Name:%s StorageAccountType:%s Size:%v", options.DiskName, options.StorageAccountType, options.SizeGB)
|
||||
return diskID, nil
|
||||
}
|
||||
|
||||
//DeleteManagedDisk : delete managed disk
|
||||
func (c *ManagedDiskController) DeleteManagedDisk(ctx context.Context, diskURI string) error {
|
||||
resourceGroup, err := getResourceGroupFromDiskURI(diskURI)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, ok := c.common.diskStateMap.Load(strings.ToLower(diskURI)); ok {
|
||||
return fmt.Errorf("failed to delete disk(%s) since it's in attaching or detaching state", diskURI)
|
||||
}
|
||||
|
||||
diskName := path.Base(diskURI)
|
||||
disk, rerr := c.common.cloud.DisksClient.Get(ctx, resourceGroup, diskName)
|
||||
if rerr != nil {
|
||||
if rerr.HTTPStatusCode == http.StatusNotFound {
|
||||
klog.V(2).Infof("azureDisk - disk(%s) is already deleted", diskURI)
|
||||
return nil
|
||||
}
|
||||
// ignore GetDisk throttling
|
||||
if !rerr.IsThrottled() && !strings.Contains(rerr.RawError.Error(), consts.RateLimited) {
|
||||
return rerr.Error()
|
||||
}
|
||||
}
|
||||
if disk.ManagedBy != nil {
|
||||
return fmt.Errorf("disk(%s) already attached to node(%s), could not be deleted", diskURI, *disk.ManagedBy)
|
||||
}
|
||||
|
||||
if rerr := c.common.cloud.DisksClient.Delete(ctx, resourceGroup, diskName); rerr != nil {
|
||||
return rerr.Error()
|
||||
}
|
||||
// We don't need poll here, k8s will immediately stop referencing the disk
|
||||
// the disk will be eventually deleted - cleanly - by ARM
|
||||
|
||||
klog.V(2).Infof("azureDisk - deleted a managed disk: %s", diskURI)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetDisk return: disk provisionState, diskID, error
|
||||
func (c *ManagedDiskController) GetDisk(resourceGroup, diskName string) (string, string, error) {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
result, rerr := c.common.cloud.DisksClient.Get(ctx, resourceGroup, diskName)
|
||||
if rerr != nil {
|
||||
return "", "", rerr.Error()
|
||||
}
|
||||
|
||||
if result.DiskProperties != nil && (*result.DiskProperties).ProvisioningState != nil {
|
||||
return *(*result.DiskProperties).ProvisioningState, *result.ID, nil
|
||||
}
|
||||
|
||||
return "", "", nil
|
||||
}
|
||||
|
||||
// ResizeDisk Expand the disk to new size
|
||||
func (c *ManagedDiskController) ResizeDisk(diskURI string, oldSize resource.Quantity, newSize resource.Quantity, supportOnlineResize bool) (resource.Quantity, error) {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
diskName := path.Base(diskURI)
|
||||
resourceGroup, err := getResourceGroupFromDiskURI(diskURI)
|
||||
if err != nil {
|
||||
return oldSize, err
|
||||
}
|
||||
|
||||
result, rerr := c.common.cloud.DisksClient.Get(ctx, resourceGroup, diskName)
|
||||
if rerr != nil {
|
||||
return oldSize, rerr.Error()
|
||||
}
|
||||
|
||||
if result.DiskProperties == nil || result.DiskProperties.DiskSizeGB == nil {
|
||||
return oldSize, fmt.Errorf("DiskProperties of disk(%s) is nil", diskName)
|
||||
}
|
||||
|
||||
// Azure resizes in chunks of GiB (not GB)
|
||||
requestGiB, err := volumehelpers.RoundUpToGiBInt32(newSize)
|
||||
if err != nil {
|
||||
return oldSize, err
|
||||
}
|
||||
|
||||
newSizeQuant := resource.MustParse(fmt.Sprintf("%dGi", requestGiB))
|
||||
|
||||
klog.V(2).Infof("azureDisk - begin to resize disk(%s) with new size(%d), old size(%v)", diskName, requestGiB, oldSize)
|
||||
// If disk already of greater or equal size than requested we return
|
||||
if *result.DiskProperties.DiskSizeGB >= requestGiB {
|
||||
return newSizeQuant, nil
|
||||
}
|
||||
|
||||
if !supportOnlineResize && result.DiskProperties.DiskState != compute.Unattached {
|
||||
return oldSize, fmt.Errorf("azureDisk - disk resize is only supported on Unattached disk, current disk state: %s, already attached to %s", result.DiskProperties.DiskState, to.String(result.ManagedBy))
|
||||
}
|
||||
|
||||
diskParameter := compute.DiskUpdate{
|
||||
DiskUpdateProperties: &compute.DiskUpdateProperties{
|
||||
DiskSizeGB: &requestGiB,
|
||||
},
|
||||
}
|
||||
|
||||
ctx, cancel = getContextWithCancel()
|
||||
defer cancel()
|
||||
if rerr := c.common.cloud.DisksClient.Update(ctx, resourceGroup, diskName, diskParameter); rerr != nil {
|
||||
return oldSize, rerr.Error()
|
||||
}
|
||||
|
||||
klog.V(2).Infof("azureDisk - resize disk(%s) with new size(%d) completed", diskName, requestGiB)
|
||||
|
||||
return newSizeQuant, nil
|
||||
}
|
||||
|
||||
// get resource group name from a managed disk URI, e.g. return {group-name} according to
|
||||
// /subscriptions/{sub-id}/resourcegroups/{group-name}/providers/microsoft.compute/disks/{disk-id}
|
||||
// according to https://docs.microsoft.com/en-us/rest/api/compute/disks/get
|
||||
func getResourceGroupFromDiskURI(diskURI string) (string, error) {
|
||||
fields := strings.Split(diskURI, "/")
|
||||
if len(fields) != 9 || strings.ToLower(fields[3]) != "resourcegroups" {
|
||||
return "", fmt.Errorf("invalid disk URI: %s", diskURI)
|
||||
}
|
||||
return fields[4], nil
|
||||
}
|
||||
|
||||
// GetLabelsForVolume implements PVLabeler.GetLabelsForVolume
|
||||
func (c *Cloud) GetLabelsForVolume(ctx context.Context, pv *v1.PersistentVolume) (map[string]string, error) {
|
||||
// Ignore if not AzureDisk.
|
||||
if pv.Spec.AzureDisk == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Ignore any volumes that are being provisioned
|
||||
if pv.Spec.AzureDisk.DiskName == cloudvolume.ProvisionedVolumeName {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return c.GetAzureDiskLabels(pv.Spec.AzureDisk.DataDiskURI)
|
||||
}
|
||||
|
||||
// GetAzureDiskLabels gets availability zone labels for Azuredisk.
|
||||
func (c *Cloud) GetAzureDiskLabels(diskURI string) (map[string]string, error) {
|
||||
// Get disk's resource group.
|
||||
diskName := path.Base(diskURI)
|
||||
resourceGroup, err := getResourceGroupFromDiskURI(diskURI)
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to get resource group for AzureDisk %q: %v", diskName, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
labels := map[string]string{
|
||||
consts.LabelFailureDomainBetaRegion: c.Location,
|
||||
}
|
||||
// no azure credential is set, return nil
|
||||
if c.DisksClient == nil {
|
||||
return labels, nil
|
||||
}
|
||||
// Get information of the disk.
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
disk, rerr := c.DisksClient.Get(ctx, resourceGroup, diskName)
|
||||
if rerr != nil {
|
||||
klog.Errorf("Failed to get information for AzureDisk %q: %v", diskName, rerr)
|
||||
return nil, rerr.Error()
|
||||
}
|
||||
|
||||
// Check whether availability zone is specified.
|
||||
if disk.Zones == nil || len(*disk.Zones) == 0 {
|
||||
klog.V(4).Infof("Azure disk %q is not zoned", diskName)
|
||||
return labels, nil
|
||||
}
|
||||
|
||||
zones := *disk.Zones
|
||||
zoneID, err := strconv.Atoi(zones[0])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse zone %v for AzureDisk %v: %w", zones, diskName, err)
|
||||
}
|
||||
|
||||
zone := c.makeZone(c.Location, zoneID)
|
||||
klog.V(4).Infof("Got zone %q for Azure disk %q", zone, diskName)
|
||||
labels[consts.LabelFailureDomainBetaZone] = zone
|
||||
return labels, nil
|
||||
}
|
||||
94
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_mock_loadbalancer_backendpool.go
generated
vendored
Normal file
94
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_mock_loadbalancer_backendpool.go
generated
vendored
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
network "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
// MockBackendPool is a mock of BackendPool interface
|
||||
type MockBackendPool struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockBackendPoolMockRecorder
|
||||
}
|
||||
|
||||
// MockBackendPoolMockRecorder is the mock recorder for MockBackendPool
|
||||
type MockBackendPoolMockRecorder struct {
|
||||
mock *MockBackendPool
|
||||
}
|
||||
|
||||
// NewMockBackendPool creates a new mock instance
|
||||
func NewMockBackendPool(ctrl *gomock.Controller) *MockBackendPool {
|
||||
mock := &MockBackendPool{ctrl: ctrl}
|
||||
mock.recorder = &MockBackendPoolMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockBackendPool) EXPECT() *MockBackendPoolMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// EnsureHostsInPool mocks base method
|
||||
func (m *MockBackendPool) EnsureHostsInPool(service *v1.Service, nodes []*v1.Node, backendPoolID, vmSetName, clusterName, lbName string, backendPool network.BackendAddressPool) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "EnsureHostsInPool", service, nodes, backendPoolID, vmSetName, clusterName, lbName, backendPool)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// EnsureHostsInPool indicates an expected call of EnsureHostsInPool
|
||||
func (mr *MockBackendPoolMockRecorder) EnsureHostsInPool(service, nodes, backendPoolID, vmSetName, clusterName, lbName, backendPool interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsureHostsInPool", reflect.TypeOf((*MockBackendPool)(nil).EnsureHostsInPool), service, nodes, backendPoolID, vmSetName, clusterName, lbName, backendPool)
|
||||
}
|
||||
|
||||
// CleanupVMSetFromBackendPoolByCondition mocks base method
|
||||
func (m *MockBackendPool) CleanupVMSetFromBackendPoolByCondition(slb *network.LoadBalancer, service *v1.Service, nodes []*v1.Node, clusterName string, shouldRemoveVMSetFromSLB func(string) bool) (*network.LoadBalancer, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CleanupVMSetFromBackendPoolByCondition", slb, service, nodes, clusterName, shouldRemoveVMSetFromSLB)
|
||||
ret0, _ := ret[0].(*network.LoadBalancer)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// CleanupVMSetFromBackendPoolByCondition indicates an expected call of CleanupVMSetFromBackendPoolByCondition
|
||||
func (mr *MockBackendPoolMockRecorder) CleanupVMSetFromBackendPoolByCondition(slb, service, nodes, clusterName, shouldRemoveVMSetFromSLB interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CleanupVMSetFromBackendPoolByCondition", reflect.TypeOf((*MockBackendPool)(nil).CleanupVMSetFromBackendPoolByCondition), slb, service, nodes, clusterName, shouldRemoveVMSetFromSLB)
|
||||
}
|
||||
|
||||
// ReconcileBackendPools mocks base method
|
||||
func (m *MockBackendPool) ReconcileBackendPools(clusterName string, service *v1.Service, lb *network.LoadBalancer) (bool, bool, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ReconcileBackendPools", clusterName, service, lb)
|
||||
ret0, _ := ret[0].(bool)
|
||||
ret1, _ := ret[1].(bool)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// ReconcileBackendPools indicates an expected call of ReconcileBackendPools
|
||||
func (mr *MockBackendPoolMockRecorder) ReconcileBackendPools(clusterName, service, lb interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReconcileBackendPools", reflect.TypeOf((*MockBackendPool)(nil).ReconcileBackendPools), clusterName, service, lb)
|
||||
}
|
||||
414
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_mock_vmsets.go
generated
vendored
Normal file
414
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_mock_vmsets.go
generated
vendored
Normal file
|
|
@ -0,0 +1,414 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
compute "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-12-01/compute"
|
||||
network "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
azure "github.com/Azure/go-autorest/autorest/azure"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
cloud_provider "k8s.io/cloud-provider"
|
||||
cache "sigs.k8s.io/cloud-provider-azure/pkg/cache"
|
||||
)
|
||||
|
||||
// MockVMSet is a mock of VMSet interface
|
||||
type MockVMSet struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockVMSetMockRecorder
|
||||
}
|
||||
|
||||
// MockVMSetMockRecorder is the mock recorder for MockVMSet
|
||||
type MockVMSetMockRecorder struct {
|
||||
mock *MockVMSet
|
||||
}
|
||||
|
||||
// NewMockVMSet creates a new mock instance
|
||||
func NewMockVMSet(ctrl *gomock.Controller) *MockVMSet {
|
||||
mock := &MockVMSet{ctrl: ctrl}
|
||||
mock.recorder = &MockVMSetMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockVMSet) EXPECT() *MockVMSetMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// GetInstanceIDByNodeName mocks base method
|
||||
func (m *MockVMSet) GetInstanceIDByNodeName(name string) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetInstanceIDByNodeName", name)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetInstanceIDByNodeName indicates an expected call of GetInstanceIDByNodeName
|
||||
func (mr *MockVMSetMockRecorder) GetInstanceIDByNodeName(name interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInstanceIDByNodeName", reflect.TypeOf((*MockVMSet)(nil).GetInstanceIDByNodeName), name)
|
||||
}
|
||||
|
||||
// GetInstanceTypeByNodeName mocks base method
|
||||
func (m *MockVMSet) GetInstanceTypeByNodeName(name string) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetInstanceTypeByNodeName", name)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetInstanceTypeByNodeName indicates an expected call of GetInstanceTypeByNodeName
|
||||
func (mr *MockVMSetMockRecorder) GetInstanceTypeByNodeName(name interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInstanceTypeByNodeName", reflect.TypeOf((*MockVMSet)(nil).GetInstanceTypeByNodeName), name)
|
||||
}
|
||||
|
||||
// GetIPByNodeName mocks base method
|
||||
func (m *MockVMSet) GetIPByNodeName(name string) (string, string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetIPByNodeName", name)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(string)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// GetIPByNodeName indicates an expected call of GetIPByNodeName
|
||||
func (mr *MockVMSetMockRecorder) GetIPByNodeName(name interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetIPByNodeName", reflect.TypeOf((*MockVMSet)(nil).GetIPByNodeName), name)
|
||||
}
|
||||
|
||||
// GetPrimaryInterface mocks base method
|
||||
func (m *MockVMSet) GetPrimaryInterface(nodeName string) (network.Interface, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetPrimaryInterface", nodeName)
|
||||
ret0, _ := ret[0].(network.Interface)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetPrimaryInterface indicates an expected call of GetPrimaryInterface
|
||||
func (mr *MockVMSetMockRecorder) GetPrimaryInterface(nodeName interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPrimaryInterface", reflect.TypeOf((*MockVMSet)(nil).GetPrimaryInterface), nodeName)
|
||||
}
|
||||
|
||||
// GetNodeNameByProviderID mocks base method
|
||||
func (m *MockVMSet) GetNodeNameByProviderID(providerID string) (types.NodeName, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetNodeNameByProviderID", providerID)
|
||||
ret0, _ := ret[0].(types.NodeName)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetNodeNameByProviderID indicates an expected call of GetNodeNameByProviderID
|
||||
func (mr *MockVMSetMockRecorder) GetNodeNameByProviderID(providerID interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNodeNameByProviderID", reflect.TypeOf((*MockVMSet)(nil).GetNodeNameByProviderID), providerID)
|
||||
}
|
||||
|
||||
// GetZoneByNodeName mocks base method
|
||||
func (m *MockVMSet) GetZoneByNodeName(name string) (cloud_provider.Zone, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetZoneByNodeName", name)
|
||||
ret0, _ := ret[0].(cloud_provider.Zone)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetZoneByNodeName indicates an expected call of GetZoneByNodeName
|
||||
func (mr *MockVMSetMockRecorder) GetZoneByNodeName(name interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetZoneByNodeName", reflect.TypeOf((*MockVMSet)(nil).GetZoneByNodeName), name)
|
||||
}
|
||||
|
||||
// GetPrimaryVMSetName mocks base method
|
||||
func (m *MockVMSet) GetPrimaryVMSetName() string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetPrimaryVMSetName")
|
||||
ret0, _ := ret[0].(string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetPrimaryVMSetName indicates an expected call of GetPrimaryVMSetName
|
||||
func (mr *MockVMSetMockRecorder) GetPrimaryVMSetName() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPrimaryVMSetName", reflect.TypeOf((*MockVMSet)(nil).GetPrimaryVMSetName))
|
||||
}
|
||||
|
||||
// GetVMSetNames mocks base method
|
||||
func (m *MockVMSet) GetVMSetNames(service *v1.Service, nodes []*v1.Node) (*[]string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetVMSetNames", service, nodes)
|
||||
ret0, _ := ret[0].(*[]string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetVMSetNames indicates an expected call of GetVMSetNames
|
||||
func (mr *MockVMSetMockRecorder) GetVMSetNames(service, nodes interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVMSetNames", reflect.TypeOf((*MockVMSet)(nil).GetVMSetNames), service, nodes)
|
||||
}
|
||||
|
||||
// GetNodeVMSetName mocks base method
|
||||
func (m *MockVMSet) GetNodeVMSetName(node *v1.Node) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetNodeVMSetName", node)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetNodeVMSetName indicates an expected call of GetNodeVMSetName
|
||||
func (mr *MockVMSetMockRecorder) GetNodeVMSetName(node interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNodeVMSetName", reflect.TypeOf((*MockVMSet)(nil).GetNodeVMSetName), node)
|
||||
}
|
||||
|
||||
// EnsureHostsInPool mocks base method
|
||||
func (m *MockVMSet) EnsureHostsInPool(service *v1.Service, nodes []*v1.Node, backendPoolID, vmSetName string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "EnsureHostsInPool", service, nodes, backendPoolID, vmSetName)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// EnsureHostsInPool indicates an expected call of EnsureHostsInPool
|
||||
func (mr *MockVMSetMockRecorder) EnsureHostsInPool(service, nodes, backendPoolID, vmSetName interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsureHostsInPool", reflect.TypeOf((*MockVMSet)(nil).EnsureHostsInPool), service, nodes, backendPoolID, vmSetName)
|
||||
}
|
||||
|
||||
// EnsureHostInPool mocks base method
|
||||
func (m *MockVMSet) EnsureHostInPool(service *v1.Service, nodeName types.NodeName, backendPoolID, vmSetName string) (string, string, string, *compute.VirtualMachineScaleSetVM, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "EnsureHostInPool", service, nodeName, backendPoolID, vmSetName)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(string)
|
||||
ret2, _ := ret[2].(string)
|
||||
ret3, _ := ret[3].(*compute.VirtualMachineScaleSetVM)
|
||||
ret4, _ := ret[4].(error)
|
||||
return ret0, ret1, ret2, ret3, ret4
|
||||
}
|
||||
|
||||
// EnsureHostInPool indicates an expected call of EnsureHostInPool
|
||||
func (mr *MockVMSetMockRecorder) EnsureHostInPool(service, nodeName, backendPoolID, vmSetName interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsureHostInPool", reflect.TypeOf((*MockVMSet)(nil).EnsureHostInPool), service, nodeName, backendPoolID, vmSetName)
|
||||
}
|
||||
|
||||
// EnsureBackendPoolDeleted mocks base method
|
||||
func (m *MockVMSet) EnsureBackendPoolDeleted(service *v1.Service, backendPoolID, vmSetName string, backendAddressPools *[]network.BackendAddressPool, deleteFromVMSet bool) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "EnsureBackendPoolDeleted", service, backendPoolID, vmSetName, backendAddressPools, deleteFromVMSet)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// EnsureBackendPoolDeleted indicates an expected call of EnsureBackendPoolDeleted
|
||||
func (mr *MockVMSetMockRecorder) EnsureBackendPoolDeleted(service, backendPoolID, vmSetName, backendAddressPools, deleteFromVMSet interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsureBackendPoolDeleted", reflect.TypeOf((*MockVMSet)(nil).EnsureBackendPoolDeleted), service, backendPoolID, vmSetName, backendAddressPools, deleteFromVMSet)
|
||||
}
|
||||
|
||||
// EnsureBackendPoolDeletedFromVMSets mocks base method
|
||||
func (m *MockVMSet) EnsureBackendPoolDeletedFromVMSets(vmSetNamesMap map[string]bool, backendPoolID string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "EnsureBackendPoolDeletedFromVMSets", vmSetNamesMap, backendPoolID)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// EnsureBackendPoolDeletedFromVMSets indicates an expected call of EnsureBackendPoolDeletedFromVMSets
|
||||
func (mr *MockVMSetMockRecorder) EnsureBackendPoolDeletedFromVMSets(vmSetNamesMap, backendPoolID interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnsureBackendPoolDeletedFromVMSets", reflect.TypeOf((*MockVMSet)(nil).EnsureBackendPoolDeletedFromVMSets), vmSetNamesMap, backendPoolID)
|
||||
}
|
||||
|
||||
// AttachDisk mocks base method
|
||||
func (m *MockVMSet) AttachDisk(nodeName types.NodeName, diskMap map[string]*AttachDiskOptions) (*azure.Future, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AttachDisk", nodeName, diskMap)
|
||||
ret0, _ := ret[0].(*azure.Future)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AttachDisk indicates an expected call of AttachDisk
|
||||
func (mr *MockVMSetMockRecorder) AttachDisk(nodeName, diskMap interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AttachDisk", reflect.TypeOf((*MockVMSet)(nil).AttachDisk), nodeName, diskMap)
|
||||
}
|
||||
|
||||
// DetachDisk mocks base method
|
||||
func (m *MockVMSet) DetachDisk(nodeName types.NodeName, diskMap map[string]string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DetachDisk", nodeName, diskMap)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// DetachDisk indicates an expected call of DetachDisk
|
||||
func (mr *MockVMSetMockRecorder) DetachDisk(nodeName, diskMap interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DetachDisk", reflect.TypeOf((*MockVMSet)(nil).DetachDisk), nodeName, diskMap)
|
||||
}
|
||||
|
||||
// WaitForUpdateResult mocks base method
|
||||
func (m *MockVMSet) WaitForUpdateResult(ctx context.Context, future *azure.Future, resourceGroupName, source string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "WaitForUpdateResult", ctx, future, resourceGroupName, source)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// WaitForUpdateResult indicates an expected call of WaitForUpdateResult
|
||||
func (mr *MockVMSetMockRecorder) WaitForUpdateResult(ctx, future, resourceGroupName, source interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitForUpdateResult", reflect.TypeOf((*MockVMSet)(nil).WaitForUpdateResult), ctx, future, resourceGroupName, source)
|
||||
}
|
||||
|
||||
// GetDataDisks mocks base method
|
||||
func (m *MockVMSet) GetDataDisks(nodeName types.NodeName, crt cache.AzureCacheReadType) ([]compute.DataDisk, *string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetDataDisks", nodeName, crt)
|
||||
ret0, _ := ret[0].([]compute.DataDisk)
|
||||
ret1, _ := ret[1].(*string)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// GetDataDisks indicates an expected call of GetDataDisks
|
||||
func (mr *MockVMSetMockRecorder) GetDataDisks(nodeName, crt interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDataDisks", reflect.TypeOf((*MockVMSet)(nil).GetDataDisks), nodeName, crt)
|
||||
}
|
||||
|
||||
// UpdateVM mocks base method
|
||||
func (m *MockVMSet) UpdateVM(nodeName types.NodeName) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "UpdateVM", nodeName)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// UpdateVM indicates an expected call of UpdateVM
|
||||
func (mr *MockVMSetMockRecorder) UpdateVM(nodeName interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateVM", reflect.TypeOf((*MockVMSet)(nil).UpdateVM), nodeName)
|
||||
}
|
||||
|
||||
// GetPowerStatusByNodeName mocks base method
|
||||
func (m *MockVMSet) GetPowerStatusByNodeName(name string) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetPowerStatusByNodeName", name)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetPowerStatusByNodeName indicates an expected call of GetPowerStatusByNodeName
|
||||
func (mr *MockVMSetMockRecorder) GetPowerStatusByNodeName(name interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPowerStatusByNodeName", reflect.TypeOf((*MockVMSet)(nil).GetPowerStatusByNodeName), name)
|
||||
}
|
||||
|
||||
// GetProvisioningStateByNodeName mocks base method
|
||||
func (m *MockVMSet) GetProvisioningStateByNodeName(name string) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetProvisioningStateByNodeName", name)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetProvisioningStateByNodeName indicates an expected call of GetProvisioningStateByNodeName
|
||||
func (mr *MockVMSetMockRecorder) GetProvisioningStateByNodeName(name interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProvisioningStateByNodeName", reflect.TypeOf((*MockVMSet)(nil).GetProvisioningStateByNodeName), name)
|
||||
}
|
||||
|
||||
// GetPrivateIPsByNodeName mocks base method
|
||||
func (m *MockVMSet) GetPrivateIPsByNodeName(name string) ([]string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetPrivateIPsByNodeName", name)
|
||||
ret0, _ := ret[0].([]string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetPrivateIPsByNodeName indicates an expected call of GetPrivateIPsByNodeName
|
||||
func (mr *MockVMSetMockRecorder) GetPrivateIPsByNodeName(name interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPrivateIPsByNodeName", reflect.TypeOf((*MockVMSet)(nil).GetPrivateIPsByNodeName), name)
|
||||
}
|
||||
|
||||
// GetNodeNameByIPConfigurationID mocks base method
|
||||
func (m *MockVMSet) GetNodeNameByIPConfigurationID(ipConfigurationID string) (string, string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetNodeNameByIPConfigurationID", ipConfigurationID)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(string)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// GetNodeNameByIPConfigurationID indicates an expected call of GetNodeNameByIPConfigurationID
|
||||
func (mr *MockVMSetMockRecorder) GetNodeNameByIPConfigurationID(ipConfigurationID interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNodeNameByIPConfigurationID", reflect.TypeOf((*MockVMSet)(nil).GetNodeNameByIPConfigurationID), ipConfigurationID)
|
||||
}
|
||||
|
||||
// GetNodeCIDRMasksByProviderID mocks base method
|
||||
func (m *MockVMSet) GetNodeCIDRMasksByProviderID(providerID string) (int, int, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetNodeCIDRMasksByProviderID", providerID)
|
||||
ret0, _ := ret[0].(int)
|
||||
ret1, _ := ret[1].(int)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// GetNodeCIDRMasksByProviderID indicates an expected call of GetNodeCIDRMasksByProviderID
|
||||
func (mr *MockVMSetMockRecorder) GetNodeCIDRMasksByProviderID(providerID interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNodeCIDRMasksByProviderID", reflect.TypeOf((*MockVMSet)(nil).GetNodeCIDRMasksByProviderID), providerID)
|
||||
}
|
||||
|
||||
// GetAgentPoolVMSetNames mocks base method
|
||||
func (m *MockVMSet) GetAgentPoolVMSetNames(nodes []*v1.Node) (*[]string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetAgentPoolVMSetNames", nodes)
|
||||
ret0, _ := ret[0].(*[]string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetAgentPoolVMSetNames indicates an expected call of GetAgentPoolVMSetNames
|
||||
func (mr *MockVMSetMockRecorder) GetAgentPoolVMSetNames(nodes interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAgentPoolVMSetNames", reflect.TypeOf((*MockVMSet)(nil).GetAgentPoolVMSetNames), nodes)
|
||||
}
|
||||
123
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_ratelimit.go
generated
vendored
Normal file
123
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_ratelimit.go
generated
vendored
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
azclients "sigs.k8s.io/cloud-provider-azure/pkg/azureclients"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/consts"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultAtachDetachDiskQPS = 6.0
|
||||
defaultAtachDetachDiskBucket = 10
|
||||
)
|
||||
|
||||
// CloudProviderRateLimitConfig indicates the rate limit config for each clients.
|
||||
type CloudProviderRateLimitConfig struct {
|
||||
// The default rate limit config options.
|
||||
azclients.RateLimitConfig
|
||||
|
||||
// Rate limit config for each clients. Values would override default settings above.
|
||||
RouteRateLimit *azclients.RateLimitConfig `json:"routeRateLimit,omitempty" yaml:"routeRateLimit,omitempty"`
|
||||
SubnetsRateLimit *azclients.RateLimitConfig `json:"subnetsRateLimit,omitempty" yaml:"subnetsRateLimit,omitempty"`
|
||||
InterfaceRateLimit *azclients.RateLimitConfig `json:"interfaceRateLimit,omitempty" yaml:"interfaceRateLimit,omitempty"`
|
||||
RouteTableRateLimit *azclients.RateLimitConfig `json:"routeTableRateLimit,omitempty" yaml:"routeTableRateLimit,omitempty"`
|
||||
LoadBalancerRateLimit *azclients.RateLimitConfig `json:"loadBalancerRateLimit,omitempty" yaml:"loadBalancerRateLimit,omitempty"`
|
||||
PublicIPAddressRateLimit *azclients.RateLimitConfig `json:"publicIPAddressRateLimit,omitempty" yaml:"publicIPAddressRateLimit,omitempty"`
|
||||
SecurityGroupRateLimit *azclients.RateLimitConfig `json:"securityGroupRateLimit,omitempty" yaml:"securityGroupRateLimit,omitempty"`
|
||||
VirtualMachineRateLimit *azclients.RateLimitConfig `json:"virtualMachineRateLimit,omitempty" yaml:"virtualMachineRateLimit,omitempty"`
|
||||
StorageAccountRateLimit *azclients.RateLimitConfig `json:"storageAccountRateLimit,omitempty" yaml:"storageAccountRateLimit,omitempty"`
|
||||
DiskRateLimit *azclients.RateLimitConfig `json:"diskRateLimit,omitempty" yaml:"diskRateLimit,omitempty"`
|
||||
SnapshotRateLimit *azclients.RateLimitConfig `json:"snapshotRateLimit,omitempty" yaml:"snapshotRateLimit,omitempty"`
|
||||
VirtualMachineScaleSetRateLimit *azclients.RateLimitConfig `json:"virtualMachineScaleSetRateLimit,omitempty" yaml:"virtualMachineScaleSetRateLimit,omitempty"`
|
||||
VirtualMachineSizeRateLimit *azclients.RateLimitConfig `json:"virtualMachineSizesRateLimit,omitempty" yaml:"virtualMachineSizesRateLimit,omitempty"`
|
||||
AvailabilitySetRateLimit *azclients.RateLimitConfig `json:"availabilitySetRateLimit,omitempty" yaml:"availabilitySetRateLimit,omitempty"`
|
||||
AttachDetachDiskRateLimit *azclients.RateLimitConfig `json:"attachDetachDiskRateLimit,omitempty" yaml:"attachDetachDiskRateLimit,omitempty"`
|
||||
}
|
||||
|
||||
// InitializeCloudProviderRateLimitConfig initializes rate limit configs.
|
||||
func InitializeCloudProviderRateLimitConfig(config *CloudProviderRateLimitConfig) {
|
||||
if config == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Assign read rate limit defaults if no configuration was passed in.
|
||||
if config.CloudProviderRateLimitQPS == 0 {
|
||||
config.CloudProviderRateLimitQPS = consts.RateLimitQPSDefault
|
||||
}
|
||||
if config.CloudProviderRateLimitBucket == 0 {
|
||||
config.CloudProviderRateLimitBucket = consts.RateLimitBucketDefault
|
||||
}
|
||||
// Assign write rate limit defaults if no configuration was passed in.
|
||||
if config.CloudProviderRateLimitQPSWrite == 0 {
|
||||
config.CloudProviderRateLimitQPSWrite = config.CloudProviderRateLimitQPS
|
||||
}
|
||||
if config.CloudProviderRateLimitBucketWrite == 0 {
|
||||
config.CloudProviderRateLimitBucketWrite = config.CloudProviderRateLimitBucket
|
||||
}
|
||||
|
||||
config.RouteRateLimit = overrideDefaultRateLimitConfig(&config.RateLimitConfig, config.RouteRateLimit)
|
||||
config.SubnetsRateLimit = overrideDefaultRateLimitConfig(&config.RateLimitConfig, config.SubnetsRateLimit)
|
||||
config.InterfaceRateLimit = overrideDefaultRateLimitConfig(&config.RateLimitConfig, config.InterfaceRateLimit)
|
||||
config.RouteTableRateLimit = overrideDefaultRateLimitConfig(&config.RateLimitConfig, config.RouteTableRateLimit)
|
||||
config.LoadBalancerRateLimit = overrideDefaultRateLimitConfig(&config.RateLimitConfig, config.LoadBalancerRateLimit)
|
||||
config.PublicIPAddressRateLimit = overrideDefaultRateLimitConfig(&config.RateLimitConfig, config.PublicIPAddressRateLimit)
|
||||
config.SecurityGroupRateLimit = overrideDefaultRateLimitConfig(&config.RateLimitConfig, config.SecurityGroupRateLimit)
|
||||
config.VirtualMachineRateLimit = overrideDefaultRateLimitConfig(&config.RateLimitConfig, config.VirtualMachineRateLimit)
|
||||
config.StorageAccountRateLimit = overrideDefaultRateLimitConfig(&config.RateLimitConfig, config.StorageAccountRateLimit)
|
||||
config.DiskRateLimit = overrideDefaultRateLimitConfig(&config.RateLimitConfig, config.DiskRateLimit)
|
||||
config.SnapshotRateLimit = overrideDefaultRateLimitConfig(&config.RateLimitConfig, config.SnapshotRateLimit)
|
||||
config.VirtualMachineScaleSetRateLimit = overrideDefaultRateLimitConfig(&config.RateLimitConfig, config.VirtualMachineScaleSetRateLimit)
|
||||
config.VirtualMachineSizeRateLimit = overrideDefaultRateLimitConfig(&config.RateLimitConfig, config.VirtualMachineSizeRateLimit)
|
||||
config.AvailabilitySetRateLimit = overrideDefaultRateLimitConfig(&config.RateLimitConfig, config.AvailabilitySetRateLimit)
|
||||
|
||||
atachDetachDiskRateLimitConfig := azclients.RateLimitConfig{
|
||||
CloudProviderRateLimit: true,
|
||||
CloudProviderRateLimitQPSWrite: defaultAtachDetachDiskQPS,
|
||||
CloudProviderRateLimitBucketWrite: defaultAtachDetachDiskBucket,
|
||||
}
|
||||
config.AttachDetachDiskRateLimit = overrideDefaultRateLimitConfig(&atachDetachDiskRateLimitConfig, config.AttachDetachDiskRateLimit)
|
||||
}
|
||||
|
||||
// overrideDefaultRateLimitConfig overrides the default CloudProviderRateLimitConfig.
|
||||
func overrideDefaultRateLimitConfig(defaults, config *azclients.RateLimitConfig) *azclients.RateLimitConfig {
|
||||
// If config not set, apply defaults.
|
||||
if config == nil {
|
||||
return defaults
|
||||
}
|
||||
|
||||
// Remain disabled if it's set explicitly.
|
||||
if !config.CloudProviderRateLimit {
|
||||
return &azclients.RateLimitConfig{CloudProviderRateLimit: false}
|
||||
}
|
||||
|
||||
// Apply default values.
|
||||
if config.CloudProviderRateLimitQPS == 0 {
|
||||
config.CloudProviderRateLimitQPS = defaults.CloudProviderRateLimitQPS
|
||||
}
|
||||
if config.CloudProviderRateLimitBucket == 0 {
|
||||
config.CloudProviderRateLimitBucket = defaults.CloudProviderRateLimitBucket
|
||||
}
|
||||
if config.CloudProviderRateLimitQPSWrite == 0 {
|
||||
config.CloudProviderRateLimitQPSWrite = defaults.CloudProviderRateLimitQPSWrite
|
||||
}
|
||||
if config.CloudProviderRateLimitBucketWrite == 0 {
|
||||
config.CloudProviderRateLimitBucketWrite = defaults.CloudProviderRateLimitBucketWrite
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
578
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_routes.go
generated
vendored
Normal file
578
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_routes.go
generated
vendored
Normal file
|
|
@ -0,0 +1,578 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
"k8s.io/klog/v2"
|
||||
utilnet "k8s.io/utils/net"
|
||||
|
||||
azcache "sigs.k8s.io/cloud-provider-azure/pkg/cache"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/consts"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/metrics"
|
||||
)
|
||||
|
||||
var (
|
||||
// routeUpdateInterval defines the route reconciling interval.
|
||||
routeUpdateInterval = 30 * time.Second
|
||||
)
|
||||
|
||||
// routeOperation defines the allowed operations for route updating.
|
||||
type routeOperation string
|
||||
|
||||
// copied to minimize the number of cross reference
|
||||
// and exceptions in publishing and allowed imports.
|
||||
const (
|
||||
// Route operations.
|
||||
routeOperationAdd routeOperation = "add"
|
||||
routeOperationDelete routeOperation = "delete"
|
||||
routeTableOperationUpdateTags routeOperation = "updateRouteTableTags"
|
||||
)
|
||||
|
||||
// delayedRouteOperation defines a delayed route operation which is used in delayedRouteUpdater.
|
||||
type delayedRouteOperation struct {
|
||||
route network.Route
|
||||
routeTableTags map[string]*string
|
||||
operation routeOperation
|
||||
result chan error
|
||||
}
|
||||
|
||||
// wait waits for the operation completion and returns the result.
|
||||
func (op *delayedRouteOperation) wait() error {
|
||||
return <-op.result
|
||||
}
|
||||
|
||||
// delayedRouteUpdater defines a delayed route updater, which batches all the
|
||||
// route updating operations within "interval" period.
|
||||
// Example usage:
|
||||
// op, err := updater.addRouteOperation(routeOperationAdd, route)
|
||||
// err = op.wait()
|
||||
type delayedRouteUpdater struct {
|
||||
az *Cloud
|
||||
interval time.Duration
|
||||
|
||||
lock sync.Mutex
|
||||
routesToUpdate []*delayedRouteOperation
|
||||
}
|
||||
|
||||
// newDelayedRouteUpdater creates a new delayedRouteUpdater.
|
||||
func newDelayedRouteUpdater(az *Cloud, interval time.Duration) *delayedRouteUpdater {
|
||||
return &delayedRouteUpdater{
|
||||
az: az,
|
||||
interval: interval,
|
||||
routesToUpdate: make([]*delayedRouteOperation, 0),
|
||||
}
|
||||
}
|
||||
|
||||
// run starts the updater reconciling loop.
|
||||
func (d *delayedRouteUpdater) run() {
|
||||
err := wait.PollImmediateInfinite(d.interval, func() (bool, error) {
|
||||
d.updateRoutes()
|
||||
return false, nil
|
||||
})
|
||||
if err != nil { // this should never happen, if it does, panic
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// updateRoutes invokes route table client to update all routes.
|
||||
func (d *delayedRouteUpdater) updateRoutes() {
|
||||
d.lock.Lock()
|
||||
defer d.lock.Unlock()
|
||||
|
||||
// No need to do any updating.
|
||||
if len(d.routesToUpdate) == 0 {
|
||||
klog.V(4).Info("updateRoutes: nothing to update, returning")
|
||||
return
|
||||
}
|
||||
|
||||
var err error
|
||||
defer func() {
|
||||
// Notify all the goroutines.
|
||||
for _, rt := range d.routesToUpdate {
|
||||
rt.result <- err
|
||||
}
|
||||
// Clear all the jobs.
|
||||
d.routesToUpdate = make([]*delayedRouteOperation, 0)
|
||||
}()
|
||||
|
||||
var (
|
||||
routeTable network.RouteTable
|
||||
existsRouteTable bool
|
||||
)
|
||||
routeTable, existsRouteTable, err = d.az.getRouteTable(azcache.CacheReadTypeDefault)
|
||||
if err != nil {
|
||||
klog.Errorf("getRouteTable() failed with error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// create route table if it doesn't exists yet.
|
||||
if !existsRouteTable {
|
||||
err = d.az.createRouteTable()
|
||||
if err != nil {
|
||||
klog.Errorf("createRouteTable() failed with error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
routeTable, _, err = d.az.getRouteTable(azcache.CacheReadTypeDefault)
|
||||
if err != nil {
|
||||
klog.Errorf("getRouteTable() failed with error: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// reconcile routes.
|
||||
dirty, onlyUpdateTags := false, true
|
||||
routes := []network.Route{}
|
||||
if routeTable.RouteTablePropertiesFormat != nil && routeTable.RouteTablePropertiesFormat.Routes != nil {
|
||||
routes = *routeTable.Routes
|
||||
}
|
||||
|
||||
routes, dirty = d.cleanupOutdatedRoutes(routes)
|
||||
if dirty {
|
||||
onlyUpdateTags = false
|
||||
}
|
||||
|
||||
for _, rt := range d.routesToUpdate {
|
||||
if rt.operation == routeTableOperationUpdateTags {
|
||||
routeTable.Tags = rt.routeTableTags
|
||||
dirty = true
|
||||
continue
|
||||
}
|
||||
|
||||
routeMatch := false
|
||||
onlyUpdateTags = false
|
||||
for i, existingRoute := range routes {
|
||||
if strings.EqualFold(to.String(existingRoute.Name), to.String(rt.route.Name)) {
|
||||
// delete the name-matched routes here (missing routes would be added later if the operation is add).
|
||||
routes = append(routes[:i], routes[i+1:]...)
|
||||
if existingRoute.RoutePropertiesFormat != nil &&
|
||||
rt.route.RoutePropertiesFormat != nil &&
|
||||
strings.EqualFold(to.String(existingRoute.AddressPrefix), to.String(rt.route.AddressPrefix)) &&
|
||||
strings.EqualFold(to.String(existingRoute.NextHopIPAddress), to.String(rt.route.NextHopIPAddress)) {
|
||||
routeMatch = true
|
||||
}
|
||||
if rt.operation == routeOperationDelete {
|
||||
dirty = true
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Add missing routes if the operation is add.
|
||||
if rt.operation == routeOperationAdd {
|
||||
routes = append(routes, rt.route)
|
||||
if !routeMatch {
|
||||
dirty = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if dirty {
|
||||
if !onlyUpdateTags {
|
||||
klog.V(2).Infof("updateRoutes: updating routes")
|
||||
routeTable.Routes = &routes
|
||||
}
|
||||
err = d.az.CreateOrUpdateRouteTable(routeTable)
|
||||
if err != nil {
|
||||
klog.Errorf("CreateOrUpdateRouteTable() failed with error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// wait a while for route updates to take effect.
|
||||
time.Sleep(time.Duration(d.az.Config.RouteUpdateWaitingInSeconds) * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
// cleanupOutdatedRoutes deletes all non-dualstack routes when dualstack is enabled,
|
||||
// and deletes all dualstack routes when dualstack is not enabled.
|
||||
func (d *delayedRouteUpdater) cleanupOutdatedRoutes(existingRoutes []network.Route) (routes []network.Route, changed bool) {
|
||||
for i := len(existingRoutes) - 1; i >= 0; i-- {
|
||||
existingRouteName := to.String(existingRoutes[i].Name)
|
||||
split := strings.Split(existingRouteName, consts.RouteNameSeparator)
|
||||
|
||||
klog.V(4).Infof("cleanupOutdatedRoutes: checking route %s", existingRouteName)
|
||||
|
||||
// filter out unmanaged routes
|
||||
deleteRoute := false
|
||||
if d.az.nodeNames.Has(split[0]) {
|
||||
if d.az.ipv6DualStackEnabled && len(split) == 1 {
|
||||
klog.V(2).Infof("cleanupOutdatedRoutes: deleting outdated non-dualstack route %s", existingRouteName)
|
||||
deleteRoute = true
|
||||
} else if !d.az.ipv6DualStackEnabled && len(split) == 2 {
|
||||
klog.V(2).Infof("cleanupOutdatedRoutes: deleting outdated dualstack route %s", existingRouteName)
|
||||
deleteRoute = true
|
||||
}
|
||||
|
||||
if deleteRoute {
|
||||
existingRoutes = append(existingRoutes[:i], existingRoutes[i+1:]...)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return existingRoutes, changed
|
||||
}
|
||||
|
||||
// addRouteOperation adds the routeOperation to delayedRouteUpdater and returns a delayedRouteOperation.
|
||||
func (d *delayedRouteUpdater) addRouteOperation(operation routeOperation, route network.Route) (*delayedRouteOperation, error) {
|
||||
d.lock.Lock()
|
||||
defer d.lock.Unlock()
|
||||
|
||||
op := &delayedRouteOperation{
|
||||
route: route,
|
||||
operation: operation,
|
||||
result: make(chan error),
|
||||
}
|
||||
d.routesToUpdate = append(d.routesToUpdate, op)
|
||||
return op, nil
|
||||
}
|
||||
|
||||
// addUpdateRouteTableTagsOperation adds a update route table tags operation to delayedRouteUpdater and returns a delayedRouteOperation.
|
||||
func (d *delayedRouteUpdater) addUpdateRouteTableTagsOperation(operation routeOperation, tags map[string]*string) (*delayedRouteOperation, error) {
|
||||
d.lock.Lock()
|
||||
defer d.lock.Unlock()
|
||||
|
||||
op := &delayedRouteOperation{
|
||||
routeTableTags: tags,
|
||||
operation: operation,
|
||||
result: make(chan error),
|
||||
}
|
||||
d.routesToUpdate = append(d.routesToUpdate, op)
|
||||
return op, nil
|
||||
}
|
||||
|
||||
// ListRoutes lists all managed routes that belong to the specified clusterName
|
||||
func (az *Cloud) ListRoutes(ctx context.Context, clusterName string) ([]*cloudprovider.Route, error) {
|
||||
klog.V(10).Infof("ListRoutes: START clusterName=%q", clusterName)
|
||||
routeTable, existsRouteTable, err := az.getRouteTable(azcache.CacheReadTypeDefault)
|
||||
routes, err := processRoutes(az.ipv6DualStackEnabled, routeTable, existsRouteTable, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Compose routes for unmanaged routes so that node controller won't retry creating routes for them.
|
||||
unmanagedNodes, err := az.GetUnmanagedNodes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
az.routeCIDRsLock.Lock()
|
||||
defer az.routeCIDRsLock.Unlock()
|
||||
for _, nodeName := range unmanagedNodes.List() {
|
||||
if cidr, ok := az.routeCIDRs[nodeName]; ok {
|
||||
routes = append(routes, &cloudprovider.Route{
|
||||
Name: nodeName,
|
||||
TargetNode: MapRouteNameToNodeName(az.ipv6DualStackEnabled, nodeName),
|
||||
DestinationCIDR: cidr,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// ensure the route table is tagged as configured
|
||||
tags, changed := az.ensureRouteTableTagged(&routeTable)
|
||||
if changed {
|
||||
klog.V(2).Infof("ListRoutes: updating tags on route table %s", to.String(routeTable.Name))
|
||||
op, err := az.routeUpdater.addUpdateRouteTableTagsOperation(routeTableOperationUpdateTags, tags)
|
||||
if err != nil {
|
||||
klog.Errorf("ListRoutes: failed to add route table operation with error: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Wait for operation complete.
|
||||
err = op.wait()
|
||||
if err != nil {
|
||||
klog.Errorf("ListRoutes: failed to update route table tags with error: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return routes, nil
|
||||
}
|
||||
|
||||
// Injectable for testing
|
||||
func processRoutes(ipv6DualStackEnabled bool, routeTable network.RouteTable, exists bool, err error) ([]*cloudprovider.Route, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return []*cloudprovider.Route{}, nil
|
||||
}
|
||||
|
||||
var kubeRoutes []*cloudprovider.Route
|
||||
if routeTable.RouteTablePropertiesFormat != nil && routeTable.Routes != nil {
|
||||
kubeRoutes = make([]*cloudprovider.Route, len(*routeTable.Routes))
|
||||
for i, route := range *routeTable.Routes {
|
||||
instance := MapRouteNameToNodeName(ipv6DualStackEnabled, *route.Name)
|
||||
cidr := *route.AddressPrefix
|
||||
klog.V(10).Infof("ListRoutes: * instance=%q, cidr=%q", instance, cidr)
|
||||
|
||||
kubeRoutes[i] = &cloudprovider.Route{
|
||||
Name: *route.Name,
|
||||
TargetNode: instance,
|
||||
DestinationCIDR: cidr,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
klog.V(10).Info("ListRoutes: FINISH")
|
||||
return kubeRoutes, nil
|
||||
}
|
||||
|
||||
func (az *Cloud) createRouteTable() error {
|
||||
routeTable := network.RouteTable{
|
||||
Name: to.StringPtr(az.RouteTableName),
|
||||
Location: to.StringPtr(az.Location),
|
||||
RouteTablePropertiesFormat: &network.RouteTablePropertiesFormat{},
|
||||
}
|
||||
|
||||
klog.V(3).Infof("createRouteTableIfNotExists: creating routetable. routeTableName=%q", az.RouteTableName)
|
||||
err := az.CreateOrUpdateRouteTable(routeTable)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Invalidate the cache right after updating
|
||||
_ = az.rtCache.Delete(az.RouteTableName)
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateRoute creates the described managed route
|
||||
// route.Name will be ignored, although the cloud-provider may use nameHint
|
||||
// to create a more user-meaningful name.
|
||||
func (az *Cloud) CreateRoute(ctx context.Context, clusterName string, nameHint string, kubeRoute *cloudprovider.Route) error {
|
||||
mc := metrics.NewMetricContext("routes", "create_route", az.ResourceGroup, az.SubscriptionID, "")
|
||||
isOperationSucceeded := false
|
||||
defer func() {
|
||||
mc.ObserveOperationWithResult(isOperationSucceeded)
|
||||
}()
|
||||
|
||||
// Returns for unmanaged nodes because azure cloud provider couldn't fetch information for them.
|
||||
var targetIP string
|
||||
nodeName := string(kubeRoute.TargetNode)
|
||||
unmanaged, err := az.IsNodeUnmanaged(nodeName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if unmanaged {
|
||||
if az.ipv6DualStackEnabled {
|
||||
//TODO (khenidak) add support for unmanaged nodes when the feature reaches beta
|
||||
return fmt.Errorf("unmanaged nodes are not supported in dual stack mode")
|
||||
}
|
||||
klog.V(2).Infof("CreateRoute: omitting unmanaged node %q", kubeRoute.TargetNode)
|
||||
az.routeCIDRsLock.Lock()
|
||||
defer az.routeCIDRsLock.Unlock()
|
||||
az.routeCIDRs[nodeName] = kubeRoute.DestinationCIDR
|
||||
return nil
|
||||
}
|
||||
|
||||
CIDRv6 := utilnet.IsIPv6CIDRString(kubeRoute.DestinationCIDR)
|
||||
// if single stack IPv4 then get the IP for the primary ip config
|
||||
// single stack IPv6 is supported on dual stack host. So the IPv6 IP is secondary IP for both single stack IPv6 and dual stack
|
||||
// Get all private IPs for the machine and find the first one that matches the IPv6 family
|
||||
if !az.ipv6DualStackEnabled && !CIDRv6 {
|
||||
targetIP, _, err = az.getIPForMachine(kubeRoute.TargetNode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// for dual stack and single stack IPv6 we need to select
|
||||
// a private ip that matches family of the cidr
|
||||
klog.V(4).Infof("CreateRoute: create route instance=%q cidr=%q is in dual stack mode", kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
|
||||
nodePrivateIPs, err := az.getPrivateIPsForMachine(kubeRoute.TargetNode)
|
||||
if nil != err {
|
||||
klog.V(3).Infof("CreateRoute: create route: failed(GetPrivateIPsByNodeName) instance=%q cidr=%q with error=%v", kubeRoute.TargetNode, kubeRoute.DestinationCIDR, err)
|
||||
return err
|
||||
}
|
||||
|
||||
targetIP, err = findFirstIPByFamily(nodePrivateIPs, CIDRv6)
|
||||
if nil != err {
|
||||
klog.V(3).Infof("CreateRoute: create route: failed(findFirstIpByFamily) instance=%q cidr=%q with error=%v", kubeRoute.TargetNode, kubeRoute.DestinationCIDR, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
routeName := mapNodeNameToRouteName(az.ipv6DualStackEnabled, kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
|
||||
route := network.Route{
|
||||
Name: to.StringPtr(routeName),
|
||||
RoutePropertiesFormat: &network.RoutePropertiesFormat{
|
||||
AddressPrefix: to.StringPtr(kubeRoute.DestinationCIDR),
|
||||
NextHopType: network.RouteNextHopTypeVirtualAppliance,
|
||||
NextHopIPAddress: to.StringPtr(targetIP),
|
||||
},
|
||||
}
|
||||
|
||||
klog.V(2).Infof("CreateRoute: creating route for clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
|
||||
op, err := az.routeUpdater.addRouteOperation(routeOperationAdd, route)
|
||||
if err != nil {
|
||||
klog.Errorf("CreateRoute failed for node %q with error: %v", kubeRoute.TargetNode, err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Wait for operation complete.
|
||||
err = op.wait()
|
||||
if err != nil {
|
||||
klog.Errorf("CreateRoute failed for node %q with error: %v", kubeRoute.TargetNode, err)
|
||||
return err
|
||||
}
|
||||
|
||||
klog.V(2).Infof("CreateRoute: route created. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
|
||||
isOperationSucceeded = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteRoute deletes the specified managed route
|
||||
// Route should be as returned by ListRoutes
|
||||
func (az *Cloud) DeleteRoute(ctx context.Context, clusterName string, kubeRoute *cloudprovider.Route) error {
|
||||
mc := metrics.NewMetricContext("routes", "delete_route", az.ResourceGroup, az.SubscriptionID, "")
|
||||
isOperationSucceeded := false
|
||||
defer func() {
|
||||
mc.ObserveOperationWithResult(isOperationSucceeded)
|
||||
}()
|
||||
|
||||
// Returns for unmanaged nodes because azure cloud provider couldn't fetch information for them.
|
||||
nodeName := string(kubeRoute.TargetNode)
|
||||
unmanaged, err := az.IsNodeUnmanaged(nodeName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if unmanaged {
|
||||
klog.V(2).Infof("DeleteRoute: omitting unmanaged node %q", kubeRoute.TargetNode)
|
||||
az.routeCIDRsLock.Lock()
|
||||
defer az.routeCIDRsLock.Unlock()
|
||||
delete(az.routeCIDRs, nodeName)
|
||||
return nil
|
||||
}
|
||||
|
||||
routeName := mapNodeNameToRouteName(az.ipv6DualStackEnabled, kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
|
||||
klog.V(2).Infof("DeleteRoute: deleting route. clusterName=%q instance=%q cidr=%q routeName=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR, routeName)
|
||||
route := network.Route{
|
||||
Name: to.StringPtr(routeName),
|
||||
RoutePropertiesFormat: &network.RoutePropertiesFormat{},
|
||||
}
|
||||
op, err := az.routeUpdater.addRouteOperation(routeOperationDelete, route)
|
||||
if err != nil {
|
||||
klog.Errorf("DeleteRoute failed for node %q with error: %v", kubeRoute.TargetNode, err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Wait for operation complete.
|
||||
err = op.wait()
|
||||
if err != nil {
|
||||
klog.Errorf("DeleteRoute failed for node %q with error: %v", kubeRoute.TargetNode, err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove outdated ipv4 routes as well
|
||||
if az.ipv6DualStackEnabled {
|
||||
routeNameWithoutIPV6Suffix := strings.Split(routeName, consts.RouteNameSeparator)[0]
|
||||
klog.V(2).Infof("DeleteRoute: deleting route. clusterName=%q instance=%q cidr=%q routeName=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR, routeNameWithoutIPV6Suffix)
|
||||
route := network.Route{
|
||||
Name: to.StringPtr(routeNameWithoutIPV6Suffix),
|
||||
RoutePropertiesFormat: &network.RoutePropertiesFormat{},
|
||||
}
|
||||
op, err := az.routeUpdater.addRouteOperation(routeOperationDelete, route)
|
||||
if err != nil {
|
||||
klog.Errorf("DeleteRoute failed for node %q with error: %v", kubeRoute.TargetNode, err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Wait for operation complete.
|
||||
err = op.wait()
|
||||
if err != nil {
|
||||
klog.Errorf("DeleteRoute failed for node %q with error: %v", kubeRoute.TargetNode, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
klog.V(2).Infof("DeleteRoute: route deleted. clusterName=%q instance=%q cidr=%q", clusterName, kubeRoute.TargetNode, kubeRoute.DestinationCIDR)
|
||||
isOperationSucceeded = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// This must be kept in sync with MapRouteNameToNodeName.
|
||||
// These two functions enable stashing the instance name in the route
|
||||
// and then retrieving it later when listing. This is needed because
|
||||
// Azure does not let you put tags/descriptions on the Route itself.
|
||||
func mapNodeNameToRouteName(ipv6DualStackEnabled bool, nodeName types.NodeName, cidr string) string {
|
||||
if !ipv6DualStackEnabled {
|
||||
return string(nodeName)
|
||||
}
|
||||
return fmt.Sprintf(consts.RouteNameFmt, nodeName, cidrtoRfc1035(cidr))
|
||||
}
|
||||
|
||||
// MapRouteNameToNodeName is used with mapNodeNameToRouteName.
|
||||
// See comment on mapNodeNameToRouteName for detailed usage.
|
||||
func MapRouteNameToNodeName(ipv6DualStackEnabled bool, routeName string) types.NodeName {
|
||||
if !ipv6DualStackEnabled {
|
||||
return types.NodeName(routeName)
|
||||
}
|
||||
parts := strings.Split(routeName, consts.RouteNameSeparator)
|
||||
nodeName := parts[0]
|
||||
return types.NodeName(nodeName)
|
||||
|
||||
}
|
||||
|
||||
// given a list of ips, return the first one
|
||||
// that matches the family requested
|
||||
// error if no match, or failure to parse
|
||||
// any of the ips
|
||||
func findFirstIPByFamily(ips []string, v6 bool) (string, error) {
|
||||
for _, ip := range ips {
|
||||
bIPv6 := utilnet.IsIPv6String(ip)
|
||||
if v6 == bIPv6 {
|
||||
return ip, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("no match found matching the ipfamily requested")
|
||||
}
|
||||
|
||||
//strips : . /
|
||||
func cidrtoRfc1035(cidr string) string {
|
||||
cidr = strings.ReplaceAll(cidr, ":", "")
|
||||
cidr = strings.ReplaceAll(cidr, ".", "")
|
||||
cidr = strings.ReplaceAll(cidr, "/", "")
|
||||
return cidr
|
||||
}
|
||||
|
||||
// ensureRouteTableTagged ensures the route table is tagged as configured
|
||||
func (az *Cloud) ensureRouteTableTagged(rt *network.RouteTable) (map[string]*string, bool) {
|
||||
if az.Tags == "" && (az.TagsMap == nil || len(az.TagsMap) == 0) {
|
||||
return nil, false
|
||||
}
|
||||
tags := parseTags(az.Tags, az.TagsMap)
|
||||
if rt.Tags == nil {
|
||||
rt.Tags = make(map[string]*string)
|
||||
}
|
||||
|
||||
tags, changed := az.reconcileTags(rt.Tags, tags)
|
||||
rt.Tags = tags
|
||||
|
||||
return rt.Tags, changed
|
||||
}
|
||||
1306
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_standard.go
generated
vendored
Normal file
1306
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_standard.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
78
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_storage.go
generated
vendored
Normal file
78
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_storage.go
generated
vendored
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2021-02-01/storage"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/azureclients/fileclient"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/consts"
|
||||
)
|
||||
|
||||
// CreateFileShare creates a file share, using a matching storage account type, account kind, etc.
|
||||
// storage account will be created if specified account is not found
|
||||
func (az *Cloud) CreateFileShare(ctx context.Context, accountOptions *AccountOptions, shareOptions *fileclient.ShareOptions) (string, string, error) {
|
||||
if accountOptions == nil {
|
||||
return "", "", fmt.Errorf("account options is nil")
|
||||
}
|
||||
if shareOptions == nil {
|
||||
return "", "", fmt.Errorf("share options is nil")
|
||||
}
|
||||
if accountOptions.ResourceGroup == "" {
|
||||
accountOptions.ResourceGroup = az.resourceGroup
|
||||
}
|
||||
|
||||
accountOptions.EnableHTTPSTrafficOnly = true
|
||||
if shareOptions.Protocol == storage.EnabledProtocolsNFS {
|
||||
accountOptions.EnableHTTPSTrafficOnly = false
|
||||
}
|
||||
|
||||
accountName, accountKey, err := az.EnsureStorageAccount(ctx, accountOptions, consts.FileShareAccountNamePrefix)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("could not get storage key for storage account %s: %w", accountOptions.Name, err)
|
||||
}
|
||||
|
||||
if err := az.createFileShare(accountOptions.ResourceGroup, accountName, shareOptions); err != nil {
|
||||
return "", "", fmt.Errorf("failed to create share %s in account %s: %w", shareOptions.Name, accountName, err)
|
||||
}
|
||||
klog.V(4).Infof("created share %s in account %s", shareOptions.Name, accountOptions.Name)
|
||||
return accountName, accountKey, nil
|
||||
}
|
||||
|
||||
// DeleteFileShare deletes a file share using storage account name and key
|
||||
func (az *Cloud) DeleteFileShare(resourceGroup, accountName, shareName string) error {
|
||||
if err := az.deleteFileShare(resourceGroup, accountName, shareName); err != nil {
|
||||
return err
|
||||
}
|
||||
klog.V(4).Infof("share %s deleted", shareName)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResizeFileShare resizes a file share
|
||||
func (az *Cloud) ResizeFileShare(resourceGroup, accountName, name string, sizeGiB int) error {
|
||||
return az.resizeFileShare(resourceGroup, accountName, name, sizeGiB)
|
||||
}
|
||||
|
||||
// GetFileShare gets a file share
|
||||
func (az *Cloud) GetFileShare(resourceGroupName, accountName, name string) (storage.FileShare, error) {
|
||||
return az.getFileShare(resourceGroupName, accountName, name)
|
||||
}
|
||||
504
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_storageaccount.go
generated
vendored
Normal file
504
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_storageaccount.go
generated
vendored
Normal file
|
|
@ -0,0 +1,504 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-12-01/compute"
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
"github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/2018-09-01/privatedns"
|
||||
"github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2021-02-01/storage"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/consts"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
// SkipMatchingTag skip account matching tag
|
||||
const SkipMatchingTag = "skip-matching"
|
||||
const LocationGlobal = "global"
|
||||
const GroupIDFile = "file"
|
||||
const PrivateDNSZoneName = "privatelink.file.core.windows.net"
|
||||
|
||||
// AccountOptions contains the fields which are used to create storage account.
|
||||
type AccountOptions struct {
|
||||
Name, Type, Kind, ResourceGroup, Location string
|
||||
EnableHTTPSTrafficOnly bool
|
||||
// indicate whether create new account when Name is empty or when account does not exists
|
||||
CreateAccount bool
|
||||
EnableLargeFileShare bool
|
||||
CreatePrivateEndpoint bool
|
||||
DisableFileServiceDeleteRetentionPolicy bool
|
||||
IsHnsEnabled *bool
|
||||
EnableNfsV3 *bool
|
||||
AllowBlobPublicAccess *bool
|
||||
Tags map[string]string
|
||||
VirtualNetworkResourceIDs []string
|
||||
}
|
||||
|
||||
type accountWithLocation struct {
|
||||
Name, StorageType, Location string
|
||||
}
|
||||
|
||||
// getStorageAccounts get matching storage accounts
|
||||
func (az *Cloud) getStorageAccounts(ctx context.Context, accountOptions *AccountOptions) ([]accountWithLocation, error) {
|
||||
if az.StorageAccountClient == nil {
|
||||
return nil, fmt.Errorf("StorageAccountClient is nil")
|
||||
}
|
||||
result, rerr := az.StorageAccountClient.ListByResourceGroup(ctx, accountOptions.ResourceGroup)
|
||||
if rerr != nil {
|
||||
return nil, rerr.Error()
|
||||
}
|
||||
|
||||
accounts := []accountWithLocation{}
|
||||
for _, acct := range result {
|
||||
if acct.Name != nil && acct.Location != nil && acct.Sku != nil {
|
||||
if !(isStorageTypeEqual(acct, accountOptions) &&
|
||||
isAccountKindEqual(acct, accountOptions) &&
|
||||
isLocationEqual(acct, accountOptions) &&
|
||||
AreVNetRulesEqual(acct, accountOptions) &&
|
||||
isLargeFileSharesPropertyEqual(acct, accountOptions) &&
|
||||
isTaggedWithSkip(acct) &&
|
||||
isHnsPropertyEqual(acct, accountOptions) &&
|
||||
isEnableNfsV3PropertyEqual(acct, accountOptions) &&
|
||||
isPrivateEndpointAsExpected(acct, accountOptions)) {
|
||||
continue
|
||||
}
|
||||
accounts = append(accounts, accountWithLocation{Name: *acct.Name, StorageType: string((*acct.Sku).Name), Location: *acct.Location})
|
||||
}
|
||||
}
|
||||
return accounts, nil
|
||||
}
|
||||
|
||||
// GetStorageAccesskey gets the storage account access key
|
||||
func (az *Cloud) GetStorageAccesskey(ctx context.Context, account, resourceGroup string) (string, error) {
|
||||
if az.StorageAccountClient == nil {
|
||||
return "", fmt.Errorf("StorageAccountClient is nil")
|
||||
}
|
||||
|
||||
result, rerr := az.StorageAccountClient.ListKeys(ctx, resourceGroup, account)
|
||||
if rerr != nil {
|
||||
return "", rerr.Error()
|
||||
}
|
||||
if result.Keys == nil {
|
||||
return "", fmt.Errorf("empty keys")
|
||||
}
|
||||
|
||||
for _, k := range *result.Keys {
|
||||
if k.Value != nil && *k.Value != "" {
|
||||
v := *k.Value
|
||||
if ind := strings.LastIndex(v, " "); ind >= 0 {
|
||||
v = v[(ind + 1):]
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("no valid keys")
|
||||
}
|
||||
|
||||
// EnsureStorageAccount search storage account, create one storage account(with genAccountNamePrefix) if not found, return accountName, accountKey
|
||||
func (az *Cloud) EnsureStorageAccount(ctx context.Context, accountOptions *AccountOptions, genAccountNamePrefix string) (string, string, error) {
|
||||
if accountOptions == nil {
|
||||
return "", "", fmt.Errorf("account options is nil")
|
||||
}
|
||||
|
||||
accountName := accountOptions.Name
|
||||
accountType := accountOptions.Type
|
||||
accountKind := accountOptions.Kind
|
||||
resourceGroup := accountOptions.ResourceGroup
|
||||
location := accountOptions.Location
|
||||
enableHTTPSTrafficOnly := accountOptions.EnableHTTPSTrafficOnly
|
||||
|
||||
var createNewAccount bool
|
||||
if len(accountName) == 0 {
|
||||
createNewAccount = true
|
||||
if !accountOptions.CreateAccount {
|
||||
// find a storage account that matches accountType
|
||||
accounts, err := az.getStorageAccounts(ctx, accountOptions)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("could not list storage accounts for account type %s: %w", accountType, err)
|
||||
}
|
||||
|
||||
if len(accounts) > 0 {
|
||||
accountName = accounts[0].Name
|
||||
createNewAccount = false
|
||||
klog.V(4).Infof("found a matching account %s type %s location %s", accounts[0].Name, accounts[0].StorageType, accounts[0].Location)
|
||||
}
|
||||
}
|
||||
|
||||
if len(accountName) == 0 {
|
||||
accountName = generateStorageAccountName(genAccountNamePrefix)
|
||||
}
|
||||
} else {
|
||||
createNewAccount = false
|
||||
if accountOptions.CreateAccount {
|
||||
// check whether account exists
|
||||
if _, err := az.GetStorageAccesskey(ctx, accountName, resourceGroup); err != nil {
|
||||
klog.V(2).Infof("get storage key for storage account %s returned with %v", accountName, err)
|
||||
createNewAccount = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vnetResourceGroup := az.ResourceGroup
|
||||
if len(az.VnetResourceGroup) > 0 {
|
||||
vnetResourceGroup = az.VnetResourceGroup
|
||||
}
|
||||
|
||||
if accountOptions.CreatePrivateEndpoint {
|
||||
// Create DNS zone first, this could make sure driver has write permission on vnetResourceGroup
|
||||
if err := az.createPrivateDNSZone(ctx, vnetResourceGroup); err != nil {
|
||||
return "", "", fmt.Errorf("Failed to create private DNS zone(%s) in resourceGroup(%s), error: %v", PrivateDNSZoneName, vnetResourceGroup, err)
|
||||
}
|
||||
}
|
||||
|
||||
if createNewAccount {
|
||||
// set network rules for storage account
|
||||
var networkRuleSet *storage.NetworkRuleSet
|
||||
virtualNetworkRules := []storage.VirtualNetworkRule{}
|
||||
for i, subnetID := range accountOptions.VirtualNetworkResourceIDs {
|
||||
vnetRule := storage.VirtualNetworkRule{
|
||||
VirtualNetworkResourceID: &accountOptions.VirtualNetworkResourceIDs[i],
|
||||
Action: storage.ActionAllow,
|
||||
}
|
||||
virtualNetworkRules = append(virtualNetworkRules, vnetRule)
|
||||
klog.V(4).Infof("subnetID(%s) has been set", subnetID)
|
||||
}
|
||||
if len(virtualNetworkRules) > 0 {
|
||||
networkRuleSet = &storage.NetworkRuleSet{
|
||||
VirtualNetworkRules: &virtualNetworkRules,
|
||||
DefaultAction: storage.DefaultActionDeny,
|
||||
}
|
||||
}
|
||||
|
||||
if accountOptions.CreatePrivateEndpoint {
|
||||
networkRuleSet = &storage.NetworkRuleSet{
|
||||
DefaultAction: storage.DefaultActionDeny,
|
||||
}
|
||||
}
|
||||
|
||||
if location == "" {
|
||||
location = az.Location
|
||||
}
|
||||
if accountType == "" {
|
||||
accountType = consts.DefaultStorageAccountType
|
||||
}
|
||||
|
||||
// use StorageV2 by default per https://docs.microsoft.com/en-us/azure/storage/common/storage-account-options
|
||||
kind := consts.DefaultStorageAccountKind
|
||||
if accountKind != "" {
|
||||
kind = storage.Kind(accountKind)
|
||||
}
|
||||
if len(accountOptions.Tags) == 0 {
|
||||
accountOptions.Tags = make(map[string]string)
|
||||
}
|
||||
accountOptions.Tags[consts.CreatedByTag] = "azure"
|
||||
tags := convertMapToMapPointer(accountOptions.Tags)
|
||||
|
||||
klog.V(2).Infof("azure - no matching account found, begin to create a new account %s in resource group %s, location: %s, accountType: %s, accountKind: %s, tags: %+v",
|
||||
accountName, resourceGroup, location, accountType, kind, accountOptions.Tags)
|
||||
|
||||
cp := storage.AccountCreateParameters{
|
||||
Sku: &storage.Sku{Name: storage.SkuName(accountType)},
|
||||
Kind: kind,
|
||||
AccountPropertiesCreateParameters: &storage.AccountPropertiesCreateParameters{
|
||||
EnableHTTPSTrafficOnly: &enableHTTPSTrafficOnly,
|
||||
NetworkRuleSet: networkRuleSet,
|
||||
IsHnsEnabled: accountOptions.IsHnsEnabled,
|
||||
EnableNfsV3: accountOptions.EnableNfsV3,
|
||||
MinimumTLSVersion: storage.MinimumTLSVersionTLS12,
|
||||
},
|
||||
Tags: tags,
|
||||
Location: &location}
|
||||
|
||||
if accountOptions.EnableLargeFileShare {
|
||||
klog.V(2).Infof("Enabling LargeFileShare for storage account(%s)", accountName)
|
||||
cp.AccountPropertiesCreateParameters.LargeFileSharesState = storage.LargeFileSharesStateEnabled
|
||||
}
|
||||
if accountOptions.AllowBlobPublicAccess != nil {
|
||||
klog.V(2).Infof("set AllowBlobPublicAccess(%v) for storage account(%s)", *accountOptions.AllowBlobPublicAccess, accountName)
|
||||
cp.AccountPropertiesCreateParameters.AllowBlobPublicAccess = accountOptions.AllowBlobPublicAccess
|
||||
}
|
||||
if az.StorageAccountClient == nil {
|
||||
return "", "", fmt.Errorf("StorageAccountClient is nil")
|
||||
}
|
||||
|
||||
if rerr := az.StorageAccountClient.Create(ctx, resourceGroup, accountName, cp); rerr != nil {
|
||||
return "", "", fmt.Errorf("failed to create storage account %s, error: %v", accountName, rerr)
|
||||
}
|
||||
|
||||
if accountOptions.DisableFileServiceDeleteRetentionPolicy {
|
||||
klog.V(2).Infof("disable DisableFileServiceDeleteRetentionPolicy on account(%s), resource group(%s)", accountName, resourceGroup)
|
||||
prop, err := az.FileClient.GetServiceProperties(resourceGroup, accountName)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
if prop.FileServicePropertiesProperties == nil {
|
||||
return "", "", fmt.Errorf("FileServicePropertiesProperties of account(%s), resource group(%s) is nil", accountName, resourceGroup)
|
||||
}
|
||||
prop.FileServicePropertiesProperties.ShareDeleteRetentionPolicy = &storage.DeleteRetentionPolicy{Enabled: to.BoolPtr(false)}
|
||||
if _, err := az.FileClient.SetServiceProperties(resourceGroup, accountName, prop); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
}
|
||||
|
||||
if accountOptions.CreatePrivateEndpoint {
|
||||
// Get properties of the storageAccount
|
||||
storageAccount, err := az.StorageAccountClient.GetProperties(ctx, resourceGroup, accountName)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("Failed to get the properties of storage account(%s), resourceGroup(%s), error: %v", accountName, resourceGroup, err)
|
||||
}
|
||||
|
||||
// Create private endpoint
|
||||
privateEndpointName := accountName + "-pvtendpoint"
|
||||
if err := az.createPrivateEndpoint(ctx, accountName, storageAccount.ID, privateEndpointName, vnetResourceGroup); err != nil {
|
||||
return "", "", fmt.Errorf("Failed to create private endpoint for storage account(%s), resourceGroup(%s), error: %v", accountName, vnetResourceGroup, err)
|
||||
}
|
||||
|
||||
// Create virtual link to the zone private DNS zone
|
||||
vNetLinkName := accountName + "-vnetlink"
|
||||
if err := az.createVNetLink(ctx, vNetLinkName, vnetResourceGroup); err != nil {
|
||||
return "", "", fmt.Errorf("Failed to create virtual link for vnet(%s) and DNS Zone(%s) in resourceGroup(%s), error: %v", az.VnetName, PrivateDNSZoneName, vnetResourceGroup, err)
|
||||
}
|
||||
|
||||
// Create dns zone group
|
||||
dnsZoneGroupName := accountName + "-dnszonegroup"
|
||||
if err := az.createPrivateDNSZoneGroup(ctx, dnsZoneGroupName, privateEndpointName, vnetResourceGroup); err != nil {
|
||||
return "", "", fmt.Errorf("Failed to create private DNS zone group - privateEndpoint(%s), vNetName(%s), resourceGroup(%s), error: %v", privateEndpointName, az.VnetName, vnetResourceGroup, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// find the access key with this account
|
||||
accountKey, err := az.GetStorageAccesskey(ctx, accountName, resourceGroup)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("could not get storage key for storage account %s: %w", accountName, err)
|
||||
}
|
||||
|
||||
return accountName, accountKey, nil
|
||||
}
|
||||
|
||||
func (az *Cloud) createPrivateEndpoint(ctx context.Context, accountName string, accountID *string, privateEndpointName, vnetResourceGroup string) error {
|
||||
klog.V(2).Infof("Creating private endpoint(%s) for account (%s)", privateEndpointName, accountName)
|
||||
|
||||
subnet, _, err := az.getSubnet(az.VnetName, az.SubnetName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Disable the private endpoint network policies before creating private endpoint
|
||||
subnet.SubnetPropertiesFormat.PrivateEndpointNetworkPolicies = network.VirtualNetworkPrivateEndpointNetworkPoliciesDisabled
|
||||
if rerr := az.SubnetsClient.CreateOrUpdate(ctx, vnetResourceGroup, az.VnetName, az.SubnetName, subnet); rerr != nil {
|
||||
return rerr.Error()
|
||||
}
|
||||
|
||||
//Create private endpoint
|
||||
privateLinkServiceConnectionName := accountName + "-pvtsvcconn"
|
||||
privateLinkServiceConnection := network.PrivateLinkServiceConnection{
|
||||
Name: &privateLinkServiceConnectionName,
|
||||
PrivateLinkServiceConnectionProperties: &network.PrivateLinkServiceConnectionProperties{
|
||||
GroupIds: &[]string{GroupIDFile},
|
||||
PrivateLinkServiceID: accountID,
|
||||
},
|
||||
}
|
||||
privateLinkServiceConnections := []network.PrivateLinkServiceConnection{privateLinkServiceConnection}
|
||||
privateEndpoint := network.PrivateEndpoint{
|
||||
Location: &az.Location,
|
||||
PrivateEndpointProperties: &network.PrivateEndpointProperties{Subnet: &subnet, PrivateLinkServiceConnections: &privateLinkServiceConnections},
|
||||
}
|
||||
return az.privateendpointclient.CreateOrUpdate(ctx, vnetResourceGroup, privateEndpointName, privateEndpoint, true)
|
||||
}
|
||||
|
||||
func (az *Cloud) createPrivateDNSZone(ctx context.Context, vnetResourceGroup string) error {
|
||||
klog.V(2).Infof("Creating private dns zone(%s) in resourceGroup (%s)", PrivateDNSZoneName, vnetResourceGroup)
|
||||
location := LocationGlobal
|
||||
privateDNSZone := privatedns.PrivateZone{Location: &location}
|
||||
if err := az.privatednsclient.CreateOrUpdate(ctx, vnetResourceGroup, PrivateDNSZoneName, privateDNSZone, true); err != nil {
|
||||
if strings.Contains(err.Error(), "exists already") {
|
||||
klog.V(2).Infof("private dns zone(%s) in resourceGroup (%s) already exists", PrivateDNSZoneName, vnetResourceGroup)
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (az *Cloud) createVNetLink(ctx context.Context, vNetLinkName, vnetResourceGroup string) error {
|
||||
klog.V(2).Infof("Creating virtual link for vnet(%s) and DNS Zone(%s) in resourceGroup(%s)", vNetLinkName, PrivateDNSZoneName, vnetResourceGroup)
|
||||
location := LocationGlobal
|
||||
vnetID := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/virtualNetworks/%s", az.SubscriptionID, vnetResourceGroup, az.VnetName)
|
||||
parameters := privatedns.VirtualNetworkLink{
|
||||
Location: &location,
|
||||
VirtualNetworkLinkProperties: &privatedns.VirtualNetworkLinkProperties{
|
||||
VirtualNetwork: &privatedns.SubResource{ID: &vnetID},
|
||||
RegistrationEnabled: to.BoolPtr(true)},
|
||||
}
|
||||
return az.virtualNetworkLinksClient.CreateOrUpdate(ctx, vnetResourceGroup, PrivateDNSZoneName, vNetLinkName, parameters, false)
|
||||
}
|
||||
|
||||
func (az *Cloud) createPrivateDNSZoneGroup(ctx context.Context, dnsZoneGroupName, privateEndpointName, vnetResourceGroup string) error {
|
||||
klog.V(2).Infof("Creating private DNS zone group(%s) with privateEndpoint(%s), vNetName(%s), resourceGroup(%s)", dnsZoneGroupName, privateEndpointName, az.VnetName, vnetResourceGroup)
|
||||
privateDNSZoneID := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Network/privateDnsZones/%s", az.SubscriptionID, vnetResourceGroup, PrivateDNSZoneName)
|
||||
dnsZoneName := PrivateDNSZoneName
|
||||
privateDNSZoneConfig := network.PrivateDNSZoneConfig{
|
||||
Name: &dnsZoneName,
|
||||
PrivateDNSZonePropertiesFormat: &network.PrivateDNSZonePropertiesFormat{
|
||||
PrivateDNSZoneID: &privateDNSZoneID},
|
||||
}
|
||||
privateDNSZoneConfigs := []network.PrivateDNSZoneConfig{privateDNSZoneConfig}
|
||||
privateDNSZoneGroup := network.PrivateDNSZoneGroup{
|
||||
PrivateDNSZoneGroupPropertiesFormat: &network.PrivateDNSZoneGroupPropertiesFormat{
|
||||
PrivateDNSZoneConfigs: &privateDNSZoneConfigs,
|
||||
},
|
||||
}
|
||||
return az.privatednszonegroupclient.CreateOrUpdate(ctx, vnetResourceGroup, privateEndpointName, dnsZoneGroupName, privateDNSZoneGroup, false)
|
||||
}
|
||||
|
||||
// AddStorageAccountTags add tags to storage account
|
||||
func (az *Cloud) AddStorageAccountTags(resourceGroup, account string, tags map[string]*string) *retry.Error {
|
||||
if az.StorageAccountClient == nil {
|
||||
return retry.NewError(false, fmt.Errorf("StorageAccountClient is nil"))
|
||||
}
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
result, rerr := az.StorageAccountClient.GetProperties(ctx, resourceGroup, account)
|
||||
if rerr != nil {
|
||||
return rerr
|
||||
}
|
||||
|
||||
newTags := result.Tags
|
||||
if newTags == nil {
|
||||
newTags = make(map[string]*string)
|
||||
}
|
||||
|
||||
// merge two tag map
|
||||
for k, v := range tags {
|
||||
newTags[k] = v
|
||||
}
|
||||
|
||||
updateParams := storage.AccountUpdateParameters{Tags: newTags}
|
||||
return az.StorageAccountClient.Update(ctx, resourceGroup, account, updateParams)
|
||||
}
|
||||
|
||||
// RemoveStorageAccountTag remove tag from storage account
|
||||
func (az *Cloud) RemoveStorageAccountTag(resourceGroup, account, key string) *retry.Error {
|
||||
if az.StorageAccountClient == nil {
|
||||
return retry.NewError(false, fmt.Errorf("StorageAccountClient is nil"))
|
||||
}
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
result, rerr := az.StorageAccountClient.GetProperties(ctx, resourceGroup, account)
|
||||
if rerr != nil {
|
||||
return rerr
|
||||
}
|
||||
|
||||
if len(result.Tags) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
originalLen := len(result.Tags)
|
||||
delete(result.Tags, key)
|
||||
if originalLen != len(result.Tags) {
|
||||
updateParams := storage.AccountUpdateParameters{Tags: result.Tags}
|
||||
return az.StorageAccountClient.Update(ctx, resourceGroup, account, updateParams)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func isStorageTypeEqual(account storage.Account, accountOptions *AccountOptions) bool {
|
||||
if accountOptions.Type != "" && !strings.EqualFold(accountOptions.Type, string((*account.Sku).Name)) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isAccountKindEqual(account storage.Account, accountOptions *AccountOptions) bool {
|
||||
if accountOptions.Kind != "" && !strings.EqualFold(accountOptions.Kind, string(account.Kind)) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isLocationEqual(account storage.Account, accountOptions *AccountOptions) bool {
|
||||
if accountOptions.Location != "" && !strings.EqualFold(accountOptions.Location, *account.Location) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func AreVNetRulesEqual(account storage.Account, accountOptions *AccountOptions) bool {
|
||||
if len(accountOptions.VirtualNetworkResourceIDs) > 0 {
|
||||
if account.AccountProperties == nil || account.AccountProperties.NetworkRuleSet == nil ||
|
||||
account.AccountProperties.NetworkRuleSet.VirtualNetworkRules == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
found := false
|
||||
for _, subnetID := range accountOptions.VirtualNetworkResourceIDs {
|
||||
for _, rule := range *account.AccountProperties.NetworkRuleSet.VirtualNetworkRules {
|
||||
if strings.EqualFold(to.String(rule.VirtualNetworkResourceID), subnetID) && rule.Action == storage.ActionAllow {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isLargeFileSharesPropertyEqual(account storage.Account, accountOptions *AccountOptions) bool {
|
||||
if account.Sku.Tier != storage.SkuTier(compute.PremiumLRS) && accountOptions.EnableLargeFileShare && (len(account.LargeFileSharesState) == 0 || account.LargeFileSharesState == storage.LargeFileSharesStateDisabled) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isTaggedWithSkip(account storage.Account) bool {
|
||||
if account.Tags != nil {
|
||||
// skip account with SkipMatchingTag tag
|
||||
if _, ok := account.Tags[SkipMatchingTag]; ok {
|
||||
klog.V(2).Infof("found %s tag for account %s, skip matching", SkipMatchingTag, *account.Name)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isHnsPropertyEqual(account storage.Account, accountOptions *AccountOptions) bool {
|
||||
return to.Bool(account.IsHnsEnabled) == to.Bool(accountOptions.IsHnsEnabled)
|
||||
}
|
||||
|
||||
func isEnableNfsV3PropertyEqual(account storage.Account, accountOptions *AccountOptions) bool {
|
||||
return to.Bool(account.EnableNfsV3) == to.Bool(accountOptions.EnableNfsV3)
|
||||
}
|
||||
|
||||
func isPrivateEndpointAsExpected(account storage.Account, accountOptions *AccountOptions) bool {
|
||||
if accountOptions.CreatePrivateEndpoint && account.PrivateEndpointConnections != nil && len(*account.PrivateEndpointConnections) > 0 {
|
||||
return true
|
||||
}
|
||||
if !accountOptions.CreatePrivateEndpoint && (account.PrivateEndpointConnections == nil || len(*account.PrivateEndpointConnections) == 0) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
262
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_utils.go
generated
vendored
Normal file
262
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_utils.go
generated
vendored
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/klog/v2"
|
||||
utilnet "k8s.io/utils/net"
|
||||
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/consts"
|
||||
)
|
||||
|
||||
var strToExtendedLocationType = map[string]network.ExtendedLocationTypes{
|
||||
"edgezone": network.ExtendedLocationTypesEdgeZone,
|
||||
}
|
||||
|
||||
// lockMap used to lock on entries
|
||||
type lockMap struct {
|
||||
sync.Mutex
|
||||
mutexMap map[string]*sync.Mutex
|
||||
}
|
||||
|
||||
// NewLockMap returns a new lock map
|
||||
func newLockMap() *lockMap {
|
||||
return &lockMap{
|
||||
mutexMap: make(map[string]*sync.Mutex),
|
||||
}
|
||||
}
|
||||
|
||||
// LockEntry acquires a lock associated with the specific entry
|
||||
func (lm *lockMap) LockEntry(entry string) {
|
||||
lm.Lock()
|
||||
// check if entry does not exists, then add entry
|
||||
if _, exists := lm.mutexMap[entry]; !exists {
|
||||
lm.addEntry(entry)
|
||||
}
|
||||
|
||||
lm.Unlock()
|
||||
lm.lockEntry(entry)
|
||||
}
|
||||
|
||||
// UnlockEntry release the lock associated with the specific entry
|
||||
func (lm *lockMap) UnlockEntry(entry string) {
|
||||
lm.Lock()
|
||||
defer lm.Unlock()
|
||||
|
||||
if _, exists := lm.mutexMap[entry]; !exists {
|
||||
return
|
||||
}
|
||||
lm.unlockEntry(entry)
|
||||
}
|
||||
|
||||
func (lm *lockMap) addEntry(entry string) {
|
||||
lm.mutexMap[entry] = &sync.Mutex{}
|
||||
}
|
||||
|
||||
func (lm *lockMap) lockEntry(entry string) {
|
||||
lm.mutexMap[entry].Lock()
|
||||
}
|
||||
|
||||
func (lm *lockMap) unlockEntry(entry string) {
|
||||
lm.mutexMap[entry].Unlock()
|
||||
}
|
||||
|
||||
func getContextWithCancel() (context.Context, context.CancelFunc) {
|
||||
return context.WithCancel(context.Background())
|
||||
}
|
||||
|
||||
func convertMapToMapPointer(origin map[string]string) map[string]*string {
|
||||
newly := make(map[string]*string)
|
||||
for k, v := range origin {
|
||||
value := v
|
||||
newly[k] = &value
|
||||
}
|
||||
return newly
|
||||
}
|
||||
|
||||
func parseTags(tags string, tagsMap map[string]string) map[string]*string {
|
||||
formatted := make(map[string]*string)
|
||||
|
||||
if tags != "" {
|
||||
kvs := strings.Split(tags, consts.TagsDelimiter)
|
||||
for _, kv := range kvs {
|
||||
res := strings.Split(kv, consts.TagKeyValueDelimiter)
|
||||
if len(res) != 2 {
|
||||
klog.Warningf("parseTags: error when parsing key-value pair %s, would ignore this one", kv)
|
||||
continue
|
||||
}
|
||||
k, v := strings.TrimSpace(res[0]), strings.TrimSpace(res[1])
|
||||
if k == "" {
|
||||
klog.Warning("parseTags: empty key, ignoring this key-value pair")
|
||||
continue
|
||||
}
|
||||
formatted[k] = to.StringPtr(v)
|
||||
}
|
||||
}
|
||||
|
||||
if len(tagsMap) > 0 {
|
||||
for key, value := range tagsMap {
|
||||
key, value := strings.TrimSpace(key), strings.TrimSpace(value)
|
||||
if key == "" {
|
||||
klog.Warningf("parseTags: empty key, ignoring this key-value pair")
|
||||
continue
|
||||
}
|
||||
|
||||
if found, k := findKeyInMapCaseInsensitive(formatted, key); found && k != key {
|
||||
klog.V(4).Infof("parseTags: found identical keys: %s from tags and %s from tagsMap (case-insensitive), %s will replace %s", k, key, key, k)
|
||||
delete(formatted, k)
|
||||
}
|
||||
formatted[key] = to.StringPtr(value)
|
||||
}
|
||||
}
|
||||
|
||||
return formatted
|
||||
}
|
||||
|
||||
func findKeyInMapCaseInsensitive(targetMap map[string]*string, key string) (bool, string) {
|
||||
for k := range targetMap {
|
||||
if strings.EqualFold(k, key) {
|
||||
return true, k
|
||||
}
|
||||
}
|
||||
|
||||
return false, ""
|
||||
}
|
||||
|
||||
func (az *Cloud) reconcileTags(currentTagsOnResource, newTags map[string]*string) (reconciledTags map[string]*string, changed bool) {
|
||||
var systemTags []string
|
||||
systemTagsMap := make(map[string]*string)
|
||||
|
||||
if az.SystemTags != "" {
|
||||
systemTags = strings.Split(az.SystemTags, consts.TagsDelimiter)
|
||||
for i := 0; i < len(systemTags); i++ {
|
||||
systemTags[i] = strings.TrimSpace(systemTags[i])
|
||||
}
|
||||
|
||||
for _, systemTag := range systemTags {
|
||||
systemTagsMap[systemTag] = to.StringPtr("")
|
||||
}
|
||||
}
|
||||
|
||||
// if the systemTags is not set, just add/update new currentTagsOnResource and not delete old currentTagsOnResource
|
||||
for k, v := range newTags {
|
||||
found, key := findKeyInMapCaseInsensitive(currentTagsOnResource, k)
|
||||
|
||||
if !found {
|
||||
currentTagsOnResource[k] = v
|
||||
changed = true
|
||||
} else if !strings.EqualFold(to.String(v), to.String(currentTagsOnResource[key])) {
|
||||
currentTagsOnResource[key] = v
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
|
||||
// if the systemTags is set, delete the old currentTagsOnResource
|
||||
if len(systemTagsMap) > 0 {
|
||||
for k := range currentTagsOnResource {
|
||||
if _, ok := newTags[k]; !ok {
|
||||
if found, _ := findKeyInMapCaseInsensitive(systemTagsMap, k); !found {
|
||||
delete(currentTagsOnResource, k)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return currentTagsOnResource, changed
|
||||
}
|
||||
|
||||
func (az *Cloud) getVMSetNamesSharingPrimarySLB() sets.String {
|
||||
vmSetNames := make([]string, 0)
|
||||
if az.NodePoolsWithoutDedicatedSLB != "" {
|
||||
vmSetNames = strings.Split(az.Config.NodePoolsWithoutDedicatedSLB, consts.VMSetNamesSharingPrimarySLBDelimiter)
|
||||
for i := 0; i < len(vmSetNames); i++ {
|
||||
vmSetNames[i] = strings.ToLower(strings.TrimSpace(vmSetNames[i]))
|
||||
}
|
||||
}
|
||||
|
||||
return sets.NewString(vmSetNames...)
|
||||
}
|
||||
|
||||
func getExtendedLocationTypeFromString(extendedLocationType string) network.ExtendedLocationTypes {
|
||||
extendedLocationType = strings.ToLower(extendedLocationType)
|
||||
if val, ok := strToExtendedLocationType[extendedLocationType]; ok {
|
||||
return val
|
||||
}
|
||||
return network.ExtendedLocationTypesEdgeZone
|
||||
}
|
||||
|
||||
func getServiceAdditionalPublicIPs(service *v1.Service) ([]string, error) {
|
||||
if service == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
result := []string{}
|
||||
if val, ok := service.Annotations[consts.ServiceAnnotationAdditionalPublicIPs]; ok {
|
||||
pips := strings.Split(strings.TrimSpace(val), ",")
|
||||
for _, pip := range pips {
|
||||
ip := strings.TrimSpace(pip)
|
||||
if ip == "" {
|
||||
continue // skip empty string
|
||||
}
|
||||
|
||||
if net.ParseIP(ip) == nil {
|
||||
return nil, fmt.Errorf("%s is not a valid IP address", ip)
|
||||
}
|
||||
|
||||
result = append(result, ip)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func getNodePrivateIPAddress(service *v1.Service, node *v1.Node) string {
|
||||
isIPV6SVC := utilnet.IsIPv6String(service.Spec.ClusterIP)
|
||||
for _, nodeAddress := range node.Status.Addresses {
|
||||
if strings.EqualFold(string(nodeAddress.Type), string(v1.NodeInternalIP)) &&
|
||||
utilnet.IsIPv6String(nodeAddress.Address) == isIPV6SVC {
|
||||
klog.V(4).Infof("getNodePrivateIPAddress: node %s, ip %s", node.Name, nodeAddress.Address)
|
||||
return nodeAddress.Address
|
||||
}
|
||||
}
|
||||
|
||||
klog.Warningf("getNodePrivateIPAddress: empty ip found for node %s", node.Name)
|
||||
return ""
|
||||
}
|
||||
|
||||
func getNodePrivateIPAddresses(node *v1.Node) []string {
|
||||
addresses := make([]string, 0)
|
||||
for _, nodeAddress := range node.Status.Addresses {
|
||||
if strings.EqualFold(string(nodeAddress.Type), string(v1.NodeInternalIP)) {
|
||||
addresses = append(addresses, nodeAddress.Address)
|
||||
}
|
||||
}
|
||||
|
||||
return addresses
|
||||
}
|
||||
108
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_vmsets.go
generated
vendored
Normal file
108
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_vmsets.go
generated
vendored
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-12-01/compute"
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
|
||||
azcache "sigs.k8s.io/cloud-provider-azure/pkg/cache"
|
||||
)
|
||||
|
||||
//go:generate sh -c "mockgen -destination=$GOPATH/src/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_mock_vmsets.go -source=$GOPATH/src/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_vmsets.go -package=provider VMSet"
|
||||
|
||||
// VMSet defines functions all vmsets (including scale set and availability
|
||||
// set) should be implemented.
|
||||
// Don't forget to run the following command to generate the mock client:
|
||||
// mockgen -destination=$GOPATH/src/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_mock_vmsets.go -source=$GOPATH/src/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_vmsets.go -package=provider VMSet
|
||||
type VMSet interface {
|
||||
// GetInstanceIDByNodeName gets the cloud provider ID by node name.
|
||||
// It must return ("", cloudprovider.InstanceNotFound) if the instance does
|
||||
// not exist or is no longer running.
|
||||
GetInstanceIDByNodeName(name string) (string, error)
|
||||
// GetInstanceTypeByNodeName gets the instance type by node name.
|
||||
GetInstanceTypeByNodeName(name string) (string, error)
|
||||
// GetIPByNodeName gets machine private IP and public IP by node name.
|
||||
GetIPByNodeName(name string) (string, string, error)
|
||||
// GetPrimaryInterface gets machine primary network interface by node name.
|
||||
GetPrimaryInterface(nodeName string) (network.Interface, error)
|
||||
// GetNodeNameByProviderID gets the node name by provider ID.
|
||||
GetNodeNameByProviderID(providerID string) (types.NodeName, error)
|
||||
|
||||
// GetZoneByNodeName gets cloudprovider.Zone by node name.
|
||||
GetZoneByNodeName(name string) (cloudprovider.Zone, error)
|
||||
|
||||
// GetPrimaryVMSetName returns the VM set name depending on the configured vmType.
|
||||
// It returns config.PrimaryScaleSetName for vmss and config.PrimaryAvailabilitySetName for standard vmType.
|
||||
GetPrimaryVMSetName() string
|
||||
// GetVMSetNames selects all possible availability sets or scale sets
|
||||
// (depending vmType configured) for service load balancer, if the service has
|
||||
// no loadbalancer mode annotation returns the primary VMSet. If service annotation
|
||||
// for loadbalancer exists then return the eligible VMSet.
|
||||
GetVMSetNames(service *v1.Service, nodes []*v1.Node) (availabilitySetNames *[]string, err error)
|
||||
// GetNodeVMSetName returns the availability set or vmss name by the node name.
|
||||
// It will return empty string when using standalone vms.
|
||||
GetNodeVMSetName(node *v1.Node) (string, error)
|
||||
// EnsureHostsInPool ensures the given Node's primary IP configurations are
|
||||
// participating in the specified LoadBalancer Backend Pool.
|
||||
EnsureHostsInPool(service *v1.Service, nodes []*v1.Node, backendPoolID string, vmSetName string) error
|
||||
// EnsureHostInPool ensures the given VM's Primary NIC's Primary IP Configuration is
|
||||
// participating in the specified LoadBalancer Backend Pool.
|
||||
EnsureHostInPool(service *v1.Service, nodeName types.NodeName, backendPoolID string, vmSetName string) (string, string, string, *compute.VirtualMachineScaleSetVM, error)
|
||||
// EnsureBackendPoolDeleted ensures the loadBalancer backendAddressPools deleted from the specified nodes.
|
||||
EnsureBackendPoolDeleted(service *v1.Service, backendPoolID, vmSetName string, backendAddressPools *[]network.BackendAddressPool, deleteFromVMSet bool) error
|
||||
//EnsureBackendPoolDeletedFromVMSets ensures the loadBalancer backendAddressPools deleted from the specified VMSS/VMAS
|
||||
EnsureBackendPoolDeletedFromVMSets(vmSetNamesMap map[string]bool, backendPoolID string) error
|
||||
|
||||
// AttachDisk attaches a disk to vm
|
||||
AttachDisk(nodeName types.NodeName, diskMap map[string]*AttachDiskOptions) (*azure.Future, error)
|
||||
// DetachDisk detaches a disk from vm
|
||||
DetachDisk(nodeName types.NodeName, diskMap map[string]string) error
|
||||
// WaitForUpdateResult waits for the response of the update request
|
||||
WaitForUpdateResult(ctx context.Context, future *azure.Future, resourceGroupName, source string) error
|
||||
|
||||
// GetDataDisks gets a list of data disks attached to the node.
|
||||
GetDataDisks(nodeName types.NodeName, crt azcache.AzureCacheReadType) ([]compute.DataDisk, *string, error)
|
||||
|
||||
// UpdateVM updates a vm
|
||||
UpdateVM(nodeName types.NodeName) error
|
||||
|
||||
// GetPowerStatusByNodeName returns the powerState for the specified node.
|
||||
GetPowerStatusByNodeName(name string) (string, error)
|
||||
|
||||
// GetProvisioningStateByNodeName returns the provisioningState for the specified node.
|
||||
GetProvisioningStateByNodeName(name string) (string, error)
|
||||
|
||||
// GetPrivateIPsByNodeName returns a slice of all private ips assigned to node (ipv6 and ipv4)
|
||||
GetPrivateIPsByNodeName(name string) ([]string, error)
|
||||
|
||||
// GetNodeNameByIPConfigurationID gets the nodeName and vmSetName by IP configuration ID.
|
||||
GetNodeNameByIPConfigurationID(ipConfigurationID string) (string, string, error)
|
||||
|
||||
// GetNodeCIDRMasksByProviderID returns the node CIDR subnet mask by provider ID.
|
||||
GetNodeCIDRMasksByProviderID(providerID string) (int, int, error)
|
||||
|
||||
// GetAgentPoolVMSetNames returns all vmSet names according to the nodes
|
||||
GetAgentPoolVMSetNames(nodes []*v1.Node) (*[]string, error)
|
||||
}
|
||||
1794
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_vmss.go
generated
vendored
Normal file
1794
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_vmss.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
341
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_vmss_cache.go
generated
vendored
Normal file
341
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_vmss_cache.go
generated
vendored
Normal file
|
|
@ -0,0 +1,341 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-12-01/compute"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
azcache "sigs.k8s.io/cloud-provider-azure/pkg/cache"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/consts"
|
||||
)
|
||||
|
||||
type vmssVirtualMachinesEntry struct {
|
||||
resourceGroup string
|
||||
vmssName string
|
||||
instanceID string
|
||||
virtualMachine *compute.VirtualMachineScaleSetVM
|
||||
lastUpdate time.Time
|
||||
}
|
||||
|
||||
type vmssEntry struct {
|
||||
vmss *compute.VirtualMachineScaleSet
|
||||
resourceGroup string
|
||||
lastUpdate time.Time
|
||||
}
|
||||
|
||||
type availabilitySetNodeEntry struct {
|
||||
vmNames sets.String
|
||||
nodeNames sets.String
|
||||
vms []compute.VirtualMachine
|
||||
}
|
||||
|
||||
func (ss *ScaleSet) newVMSSCache() (*azcache.TimedCache, error) {
|
||||
getter := func(key string) (interface{}, error) {
|
||||
localCache := &sync.Map{} // [vmasName]*vmssEntry
|
||||
|
||||
allResourceGroups, err := ss.GetResourceGroups()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, resourceGroup := range allResourceGroups.List() {
|
||||
allScaleSets, rerr := ss.VirtualMachineScaleSetsClient.List(context.Background(), resourceGroup)
|
||||
if rerr != nil {
|
||||
klog.Errorf("VirtualMachineScaleSetsClient.List failed: %v", rerr)
|
||||
return nil, rerr.Error()
|
||||
}
|
||||
|
||||
for i := range allScaleSets {
|
||||
scaleSet := allScaleSets[i]
|
||||
if scaleSet.Name == nil || *scaleSet.Name == "" {
|
||||
klog.Warning("failed to get the name of VMSS")
|
||||
continue
|
||||
}
|
||||
localCache.Store(*scaleSet.Name, &vmssEntry{
|
||||
vmss: &scaleSet,
|
||||
resourceGroup: resourceGroup,
|
||||
lastUpdate: time.Now().UTC(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return localCache, nil
|
||||
}
|
||||
|
||||
if ss.Config.VmssCacheTTLInSeconds == 0 {
|
||||
ss.Config.VmssCacheTTLInSeconds = consts.VMSSCacheTTLDefaultInSeconds
|
||||
}
|
||||
return azcache.NewTimedcache(time.Duration(ss.Config.VmssCacheTTLInSeconds)*time.Second, getter)
|
||||
}
|
||||
|
||||
func extractVmssVMName(name string) (string, string, error) {
|
||||
split := strings.SplitAfter(name, consts.VMSSNameSeparator)
|
||||
if len(split) < 2 {
|
||||
klog.V(3).Infof("Failed to extract vmssVMName %q", name)
|
||||
return "", "", ErrorNotVmssInstance
|
||||
}
|
||||
|
||||
ssName := strings.Join(split[0:len(split)-1], "")
|
||||
// removing the trailing `vmssNameSeparator` since we used SplitAfter
|
||||
ssName = ssName[:len(ssName)-1]
|
||||
instanceID := split[len(split)-1]
|
||||
return ssName, instanceID, nil
|
||||
}
|
||||
|
||||
// getVMSSVMCache returns an *azcache.TimedCache and cache key for a VMSS (creating that cache if new).
|
||||
func (ss *ScaleSet) getVMSSVMCache(resourceGroup, vmssName string) (string, *azcache.TimedCache, error) {
|
||||
cacheKey := strings.ToLower(fmt.Sprintf("%s/%s", resourceGroup, vmssName))
|
||||
if entry, ok := ss.vmssVMCache.Load(cacheKey); ok {
|
||||
cache := entry.(*azcache.TimedCache)
|
||||
return cacheKey, cache, nil
|
||||
}
|
||||
|
||||
cache, err := ss.newVMSSVirtualMachinesCache(resourceGroup, vmssName, cacheKey)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
ss.vmssVMCache.Store(cacheKey, cache)
|
||||
return cacheKey, cache, nil
|
||||
}
|
||||
|
||||
// gcVMSSVMCache delete stale VMSS VMs caches from deleted VMSSes.
|
||||
func (ss *ScaleSet) gcVMSSVMCache() error {
|
||||
cached, err := ss.vmssCache.Get(consts.VMSSKey, azcache.CacheReadTypeUnsafe)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
vmsses := cached.(*sync.Map)
|
||||
removed := map[string]bool{}
|
||||
ss.vmssVMCache.Range(func(key, value interface{}) bool {
|
||||
cacheKey := key.(string)
|
||||
vlistIdx := cacheKey[strings.LastIndex(cacheKey, "/")+1:]
|
||||
if _, ok := vmsses.Load(vlistIdx); !ok {
|
||||
removed[cacheKey] = true
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
for key := range removed {
|
||||
ss.vmssVMCache.Delete(key)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// newVMSSVirtualMachinesCache instantiates a new VMs cache for VMs belonging to the provided VMSS.
|
||||
func (ss *ScaleSet) newVMSSVirtualMachinesCache(resourceGroupName, vmssName, cacheKey string) (*azcache.TimedCache, error) {
|
||||
vmssVirtualMachinesCacheTTL := time.Duration(ss.Config.VmssVirtualMachinesCacheTTLInSeconds) * time.Second
|
||||
|
||||
getter := func(key string) (interface{}, error) {
|
||||
localCache := &sync.Map{} // [nodeName]*vmssVirtualMachinesEntry
|
||||
|
||||
oldCache := make(map[string]vmssVirtualMachinesEntry)
|
||||
|
||||
if vmssCache, ok := ss.vmssVMCache.Load(cacheKey); ok {
|
||||
// get old cache before refreshing the cache
|
||||
cache := vmssCache.(*azcache.TimedCache)
|
||||
entry, exists, err := cache.Store.GetByKey(cacheKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if exists {
|
||||
cached := entry.(*azcache.AzureCacheEntry).Data
|
||||
if cached != nil {
|
||||
virtualMachines := cached.(*sync.Map)
|
||||
virtualMachines.Range(func(key, value interface{}) bool {
|
||||
oldCache[key.(string)] = *value.(*vmssVirtualMachinesEntry)
|
||||
return true
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vms, err := ss.listScaleSetVMs(vmssName, resourceGroupName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := range vms {
|
||||
vm := vms[i]
|
||||
if vm.OsProfile == nil || vm.OsProfile.ComputerName == nil {
|
||||
klog.Warningf("failed to get computerName for vmssVM (%q)", vmssName)
|
||||
continue
|
||||
}
|
||||
|
||||
computerName := strings.ToLower(*vm.OsProfile.ComputerName)
|
||||
if vm.NetworkProfile == nil || vm.NetworkProfile.NetworkInterfaces == nil {
|
||||
klog.Warningf("skip caching vmssVM %s since its network profile hasn't initialized yet (probably still under creating)", computerName)
|
||||
continue
|
||||
}
|
||||
|
||||
vmssVMCacheEntry := &vmssVirtualMachinesEntry{
|
||||
resourceGroup: resourceGroupName,
|
||||
vmssName: vmssName,
|
||||
instanceID: to.String(vm.InstanceID),
|
||||
virtualMachine: &vm,
|
||||
lastUpdate: time.Now().UTC(),
|
||||
}
|
||||
// set cache entry to nil when the VM is under deleting.
|
||||
if vm.VirtualMachineScaleSetVMProperties != nil &&
|
||||
strings.EqualFold(to.String(vm.VirtualMachineScaleSetVMProperties.ProvisioningState), string(compute.ProvisioningStateDeleting)) {
|
||||
klog.V(4).Infof("VMSS virtualMachine %q is under deleting, setting its cache to nil", computerName)
|
||||
vmssVMCacheEntry.virtualMachine = nil
|
||||
}
|
||||
localCache.Store(computerName, vmssVMCacheEntry)
|
||||
|
||||
delete(oldCache, computerName)
|
||||
}
|
||||
|
||||
// add old missing cache data with nil entries to prevent aggressive
|
||||
// ARM calls during cache invalidation
|
||||
for name, vmEntry := range oldCache {
|
||||
// if the nil cache entry has existed for vmssVirtualMachinesCacheTTL in the cache
|
||||
// then it should not be added back to the cache
|
||||
if vmEntry.virtualMachine == nil && time.Since(vmEntry.lastUpdate) > vmssVirtualMachinesCacheTTL {
|
||||
klog.V(5).Infof("ignoring expired entries from old cache for %s", name)
|
||||
continue
|
||||
}
|
||||
lastUpdate := time.Now().UTC()
|
||||
if vmEntry.virtualMachine == nil {
|
||||
// if this is already a nil entry then keep the time the nil
|
||||
// entry was first created, so we can cleanup unwanted entries
|
||||
lastUpdate = vmEntry.lastUpdate
|
||||
}
|
||||
|
||||
klog.V(5).Infof("adding old entries to new cache for %s", name)
|
||||
localCache.Store(name, &vmssVirtualMachinesEntry{
|
||||
resourceGroup: vmEntry.resourceGroup,
|
||||
vmssName: vmEntry.vmssName,
|
||||
instanceID: vmEntry.instanceID,
|
||||
virtualMachine: nil,
|
||||
lastUpdate: lastUpdate,
|
||||
})
|
||||
}
|
||||
|
||||
return localCache, nil
|
||||
}
|
||||
|
||||
return azcache.NewTimedcache(vmssVirtualMachinesCacheTTL, getter)
|
||||
}
|
||||
|
||||
func (ss *ScaleSet) deleteCacheForNode(nodeName string) error {
|
||||
node, err := ss.getNodeIdentityByNodeName(nodeName, azcache.CacheReadTypeUnsafe)
|
||||
if err != nil {
|
||||
klog.Errorf("deleteCacheForNode(%s) failed with error: %v", nodeName, err)
|
||||
return err
|
||||
}
|
||||
|
||||
cacheKey, timedcache, err := ss.getVMSSVMCache(node.resourceGroup, node.vmssName)
|
||||
if err != nil {
|
||||
klog.Errorf("deleteCacheForNode(%s) failed with error: %v", nodeName, err)
|
||||
return err
|
||||
}
|
||||
|
||||
vmcache, err := timedcache.Get(cacheKey, azcache.CacheReadTypeUnsafe)
|
||||
if err != nil {
|
||||
klog.Errorf("deleteCacheForNode(%s) failed with error: %v", nodeName, err)
|
||||
return err
|
||||
}
|
||||
virtualMachines := vmcache.(*sync.Map)
|
||||
virtualMachines.Delete(nodeName)
|
||||
|
||||
if err := ss.gcVMSSVMCache(); err != nil {
|
||||
klog.Errorf("deleteCacheForNode(%s) failed to gc stale vmss caches: %v", nodeName, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ss *ScaleSet) newAvailabilitySetNodesCache() (*azcache.TimedCache, error) {
|
||||
getter := func(key string) (interface{}, error) {
|
||||
vmNames := sets.NewString()
|
||||
resourceGroups, err := ss.GetResourceGroups()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vmList := make([]compute.VirtualMachine, 0)
|
||||
for _, resourceGroup := range resourceGroups.List() {
|
||||
vms, err := ss.Cloud.ListVirtualMachines(resourceGroup)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("newAvailabilitySetNodesCache: failed to list vms in the resource group %s: %w", resourceGroup, err)
|
||||
}
|
||||
for _, vm := range vms {
|
||||
if vm.Name != nil {
|
||||
vmNames.Insert(to.String(vm.Name))
|
||||
vmList = append(vmList, vm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// store all the node names in the cluster when the cache data was created.
|
||||
nodeNames, err := ss.GetNodeNames()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
localCache := availabilitySetNodeEntry{
|
||||
vmNames: vmNames,
|
||||
nodeNames: nodeNames,
|
||||
vms: vmList,
|
||||
}
|
||||
|
||||
return localCache, nil
|
||||
}
|
||||
|
||||
if ss.Config.AvailabilitySetNodesCacheTTLInSeconds == 0 {
|
||||
ss.Config.AvailabilitySetNodesCacheTTLInSeconds = consts.AvailabilitySetNodesCacheTTLDefaultInSeconds
|
||||
}
|
||||
return azcache.NewTimedcache(time.Duration(ss.Config.AvailabilitySetNodesCacheTTLInSeconds)*time.Second, getter)
|
||||
}
|
||||
|
||||
func (ss *ScaleSet) isNodeManagedByAvailabilitySet(nodeName string, crt azcache.AzureCacheReadType) (bool, error) {
|
||||
// Assume all nodes are managed by VMSS when DisableAvailabilitySetNodes is enabled.
|
||||
if ss.DisableAvailabilitySetNodes {
|
||||
klog.V(2).Infof("Assuming node %q is managed by VMSS since DisableAvailabilitySetNodes is set to true", nodeName)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
cached, err := ss.availabilitySetNodesCache.Get(consts.AvailabilitySetNodesKey, crt)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
cachedNodes := cached.(availabilitySetNodeEntry).nodeNames
|
||||
// if the node is not in the cache, assume the node has joined after the last cache refresh and attempt to refresh the cache.
|
||||
if !cachedNodes.Has(nodeName) {
|
||||
klog.V(2).Infof("Node %s has joined the cluster since the last VM cache refresh, refreshing the cache", nodeName)
|
||||
cached, err = ss.availabilitySetNodesCache.Get(consts.AvailabilitySetNodesKey, azcache.CacheReadTypeForceRefresh)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
cachedVMs := cached.(availabilitySetNodeEntry).vmNames
|
||||
return cachedVMs.Has(nodeName), nil
|
||||
}
|
||||
360
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_wrap.go
generated
vendored
Normal file
360
cluster-autoscaler/vendor/sigs.k8s.io/cloud-provider-azure/pkg/provider/azure_wrap.go
generated
vendored
Normal file
|
|
@ -0,0 +1,360 @@
|
|||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-12-01/compute"
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-02-01/network"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
azcache "sigs.k8s.io/cloud-provider-azure/pkg/cache"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/consts"
|
||||
"sigs.k8s.io/cloud-provider-azure/pkg/retry"
|
||||
)
|
||||
|
||||
var (
|
||||
vmCacheTTLDefaultInSeconds = 60
|
||||
loadBalancerCacheTTLDefaultInSeconds = 120
|
||||
nsgCacheTTLDefaultInSeconds = 120
|
||||
routeTableCacheTTLDefaultInSeconds = 120
|
||||
|
||||
azureNodeProviderIDRE = regexp.MustCompile(`^azure:///subscriptions/(?:.*)/resourceGroups/(?:.*)/providers/Microsoft.Compute/(?:.*)`)
|
||||
azureResourceGroupNameRE = regexp.MustCompile(`.*/subscriptions/(?:.*)/resourceGroups/(.+)/providers/(?:.*)`)
|
||||
)
|
||||
|
||||
// checkExistsFromError inspects an error and returns a true if err is nil,
|
||||
// false if error is an autorest.Error with StatusCode=404 and will return the
|
||||
// error back if error is another status code or another type of error.
|
||||
func checkResourceExistsFromError(err *retry.Error) (bool, *retry.Error) {
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if err.HTTPStatusCode == http.StatusNotFound {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
/// getVirtualMachine calls 'VirtualMachinesClient.Get' with a timed cache
|
||||
/// The service side has throttling control that delays responses if there are multiple requests onto certain vm
|
||||
/// resource request in short period.
|
||||
func (az *Cloud) getVirtualMachine(nodeName types.NodeName, crt azcache.AzureCacheReadType) (vm compute.VirtualMachine, err error) {
|
||||
vmName := string(nodeName)
|
||||
cachedVM, err := az.vmCache.Get(vmName, crt)
|
||||
if err != nil {
|
||||
return vm, err
|
||||
}
|
||||
|
||||
if cachedVM == nil {
|
||||
klog.Warningf("Unable to find node %s: %v", nodeName, cloudprovider.InstanceNotFound)
|
||||
return vm, cloudprovider.InstanceNotFound
|
||||
}
|
||||
|
||||
return *(cachedVM.(*compute.VirtualMachine)), nil
|
||||
}
|
||||
|
||||
func (az *Cloud) getRouteTable(crt azcache.AzureCacheReadType) (routeTable network.RouteTable, exists bool, err error) {
|
||||
if len(az.RouteTableName) == 0 {
|
||||
return routeTable, false, fmt.Errorf("Route table name is not configured")
|
||||
}
|
||||
|
||||
cachedRt, err := az.rtCache.Get(az.RouteTableName, crt)
|
||||
if err != nil {
|
||||
return routeTable, false, err
|
||||
}
|
||||
|
||||
if cachedRt == nil {
|
||||
return routeTable, false, nil
|
||||
}
|
||||
|
||||
return *(cachedRt.(*network.RouteTable)), true, nil
|
||||
}
|
||||
|
||||
func (az *Cloud) getPublicIPAddress(pipResourceGroup string, pipName string) (network.PublicIPAddress, bool, error) {
|
||||
resourceGroup := az.ResourceGroup
|
||||
if pipResourceGroup != "" {
|
||||
resourceGroup = pipResourceGroup
|
||||
}
|
||||
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
pip, err := az.PublicIPAddressesClient.Get(ctx, resourceGroup, pipName, "")
|
||||
exists, rerr := checkResourceExistsFromError(err)
|
||||
if rerr != nil {
|
||||
return pip, false, rerr.Error()
|
||||
}
|
||||
|
||||
if !exists {
|
||||
klog.V(2).Infof("Public IP %q not found", pipName)
|
||||
return pip, false, nil
|
||||
}
|
||||
|
||||
return pip, exists, nil
|
||||
}
|
||||
|
||||
func (az *Cloud) getSubnet(virtualNetworkName string, subnetName string) (network.Subnet, bool, error) {
|
||||
var rg string
|
||||
if len(az.VnetResourceGroup) > 0 {
|
||||
rg = az.VnetResourceGroup
|
||||
} else {
|
||||
rg = az.ResourceGroup
|
||||
}
|
||||
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
subnet, err := az.SubnetsClient.Get(ctx, rg, virtualNetworkName, subnetName, "")
|
||||
exists, rerr := checkResourceExistsFromError(err)
|
||||
if rerr != nil {
|
||||
return subnet, false, rerr.Error()
|
||||
}
|
||||
|
||||
if !exists {
|
||||
klog.V(2).Infof("Subnet %q not found", subnetName)
|
||||
return subnet, false, nil
|
||||
}
|
||||
|
||||
return subnet, exists, nil
|
||||
}
|
||||
|
||||
func (az *Cloud) getAzureLoadBalancer(name string, crt azcache.AzureCacheReadType) (lb network.LoadBalancer, exists bool, err error) {
|
||||
cachedLB, err := az.lbCache.Get(name, crt)
|
||||
if err != nil {
|
||||
return lb, false, err
|
||||
}
|
||||
|
||||
if cachedLB == nil {
|
||||
return lb, false, nil
|
||||
}
|
||||
|
||||
return *(cachedLB.(*network.LoadBalancer)), true, nil
|
||||
}
|
||||
|
||||
func (az *Cloud) getSecurityGroup(crt azcache.AzureCacheReadType) (network.SecurityGroup, error) {
|
||||
nsg := network.SecurityGroup{}
|
||||
if az.SecurityGroupName == "" {
|
||||
return nsg, fmt.Errorf("securityGroupName is not configured")
|
||||
}
|
||||
|
||||
securityGroup, err := az.nsgCache.Get(az.SecurityGroupName, crt)
|
||||
if err != nil {
|
||||
return nsg, err
|
||||
}
|
||||
|
||||
if securityGroup == nil {
|
||||
return nsg, fmt.Errorf("nsg %q not found", az.SecurityGroupName)
|
||||
}
|
||||
|
||||
return *(securityGroup.(*network.SecurityGroup)), nil
|
||||
}
|
||||
|
||||
func (az *Cloud) newVMCache() (*azcache.TimedCache, error) {
|
||||
getter := func(key string) (interface{}, error) {
|
||||
// Currently InstanceView request are used by azure_zones, while the calls come after non-InstanceView
|
||||
// request. If we first send an InstanceView request and then a non InstanceView request, the second
|
||||
// request will still hit throttling. This is what happens now for cloud controller manager: In this
|
||||
// case we do get instance view every time to fulfill the azure_zones requirement without hitting
|
||||
// throttling.
|
||||
// Consider adding separate parameter for controlling 'InstanceView' once node update issue #56276 is fixed
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
resourceGroup, err := az.GetNodeResourceGroup(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vm, verr := az.VirtualMachinesClient.Get(ctx, resourceGroup, key, compute.InstanceView)
|
||||
exists, rerr := checkResourceExistsFromError(verr)
|
||||
if rerr != nil {
|
||||
return nil, rerr.Error()
|
||||
}
|
||||
|
||||
if !exists {
|
||||
klog.V(2).Infof("Virtual machine %q not found", key)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if vm.VirtualMachineProperties != nil &&
|
||||
strings.EqualFold(to.String(vm.VirtualMachineProperties.ProvisioningState), string(compute.ProvisioningStateDeleting)) {
|
||||
klog.V(2).Infof("Virtual machine %q is under deleting", key)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return &vm, nil
|
||||
}
|
||||
|
||||
if az.VMCacheTTLInSeconds == 0 {
|
||||
az.VMCacheTTLInSeconds = vmCacheTTLDefaultInSeconds
|
||||
}
|
||||
return azcache.NewTimedcache(time.Duration(az.VMCacheTTLInSeconds)*time.Second, getter)
|
||||
}
|
||||
|
||||
func (az *Cloud) newLBCache() (*azcache.TimedCache, error) {
|
||||
getter := func(key string) (interface{}, error) {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
lb, err := az.LoadBalancerClient.Get(ctx, az.getLoadBalancerResourceGroup(), key, "")
|
||||
exists, rerr := checkResourceExistsFromError(err)
|
||||
if rerr != nil {
|
||||
return nil, rerr.Error()
|
||||
}
|
||||
|
||||
if !exists {
|
||||
klog.V(2).Infof("Load balancer %q not found", key)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return &lb, nil
|
||||
}
|
||||
|
||||
if az.LoadBalancerCacheTTLInSeconds == 0 {
|
||||
az.LoadBalancerCacheTTLInSeconds = loadBalancerCacheTTLDefaultInSeconds
|
||||
}
|
||||
return azcache.NewTimedcache(time.Duration(az.LoadBalancerCacheTTLInSeconds)*time.Second, getter)
|
||||
}
|
||||
|
||||
func (az *Cloud) newNSGCache() (*azcache.TimedCache, error) {
|
||||
getter := func(key string) (interface{}, error) {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
nsg, err := az.SecurityGroupsClient.Get(ctx, az.SecurityGroupResourceGroup, key, "")
|
||||
exists, rerr := checkResourceExistsFromError(err)
|
||||
if rerr != nil {
|
||||
return nil, rerr.Error()
|
||||
}
|
||||
|
||||
if !exists {
|
||||
klog.V(2).Infof("Security group %q not found", key)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return &nsg, nil
|
||||
}
|
||||
|
||||
if az.NsgCacheTTLInSeconds == 0 {
|
||||
az.NsgCacheTTLInSeconds = nsgCacheTTLDefaultInSeconds
|
||||
}
|
||||
return azcache.NewTimedcache(time.Duration(az.NsgCacheTTLInSeconds)*time.Second, getter)
|
||||
}
|
||||
|
||||
func (az *Cloud) newRouteTableCache() (*azcache.TimedCache, error) {
|
||||
getter := func(key string) (interface{}, error) {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
rt, err := az.RouteTablesClient.Get(ctx, az.RouteTableResourceGroup, key, "")
|
||||
exists, rerr := checkResourceExistsFromError(err)
|
||||
if rerr != nil {
|
||||
return nil, rerr.Error()
|
||||
}
|
||||
|
||||
if !exists {
|
||||
klog.V(2).Infof("Route table %q not found", key)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return &rt, nil
|
||||
}
|
||||
|
||||
if az.RouteTableCacheTTLInSeconds == 0 {
|
||||
az.RouteTableCacheTTLInSeconds = routeTableCacheTTLDefaultInSeconds
|
||||
}
|
||||
return azcache.NewTimedcache(time.Duration(az.RouteTableCacheTTLInSeconds)*time.Second, getter)
|
||||
}
|
||||
|
||||
func (az *Cloud) useStandardLoadBalancer() bool {
|
||||
return strings.EqualFold(az.LoadBalancerSku, consts.LoadBalancerSkuStandard)
|
||||
}
|
||||
|
||||
func (az *Cloud) excludeMasterNodesFromStandardLB() bool {
|
||||
return az.ExcludeMasterFromStandardLB != nil && *az.ExcludeMasterFromStandardLB
|
||||
}
|
||||
|
||||
func (az *Cloud) disableLoadBalancerOutboundSNAT() bool {
|
||||
if !az.useStandardLoadBalancer() || az.DisableOutboundSNAT == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return *az.DisableOutboundSNAT
|
||||
}
|
||||
|
||||
// IsNodeUnmanaged returns true if the node is not managed by Azure cloud provider.
|
||||
// Those nodes includes on-prem or VMs from other clouds. They will not be added to load balancer
|
||||
// backends. Azure routes and managed disks are also not supported for them.
|
||||
func (az *Cloud) IsNodeUnmanaged(nodeName string) (bool, error) {
|
||||
unmanagedNodes, err := az.GetUnmanagedNodes()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return unmanagedNodes.Has(nodeName), nil
|
||||
}
|
||||
|
||||
// IsNodeUnmanagedByProviderID returns true if the node is not managed by Azure cloud provider.
|
||||
// All managed node's providerIDs are in format 'azure:///subscriptions/<id>/resourceGroups/<rg>/providers/Microsoft.Compute/.*'
|
||||
func (az *Cloud) IsNodeUnmanagedByProviderID(providerID string) bool {
|
||||
return !azureNodeProviderIDRE.Match([]byte(providerID))
|
||||
}
|
||||
|
||||
// convertResourceGroupNameToLower converts the resource group name in the resource ID to be lowered.
|
||||
func convertResourceGroupNameToLower(resourceID string) (string, error) {
|
||||
matches := azureResourceGroupNameRE.FindStringSubmatch(resourceID)
|
||||
if len(matches) != 2 {
|
||||
return "", fmt.Errorf("%q isn't in Azure resource ID format %q", resourceID, azureResourceGroupNameRE.String())
|
||||
}
|
||||
|
||||
resourceGroup := matches[1]
|
||||
return strings.Replace(resourceID, resourceGroup, strings.ToLower(resourceGroup), 1), nil
|
||||
}
|
||||
|
||||
// isBackendPoolOnSameLB checks whether newBackendPoolID is on the same load balancer as existingBackendPools.
|
||||
// Since both public and internal LBs are supported, lbName and lbName-internal are treated as same.
|
||||
// If not same, the lbName for existingBackendPools would also be returned.
|
||||
func isBackendPoolOnSameLB(newBackendPoolID string, existingBackendPools []string) (bool, string, error) {
|
||||
matches := backendPoolIDRE.FindStringSubmatch(newBackendPoolID)
|
||||
if len(matches) != 2 {
|
||||
return false, "", fmt.Errorf("new backendPoolID %q is in wrong format", newBackendPoolID)
|
||||
}
|
||||
|
||||
newLBName := matches[1]
|
||||
newLBNameTrimmed := strings.TrimSuffix(newLBName, consts.InternalLoadBalancerNameSuffix)
|
||||
for _, backendPool := range existingBackendPools {
|
||||
matches := backendPoolIDRE.FindStringSubmatch(backendPool)
|
||||
if len(matches) != 2 {
|
||||
return false, "", fmt.Errorf("existing backendPoolID %q is in wrong format", backendPool)
|
||||
}
|
||||
|
||||
lbName := matches[1]
|
||||
if !strings.EqualFold(strings.TrimSuffix(lbName, consts.InternalLoadBalancerNameSuffix), newLBNameTrimmed) {
|
||||
return false, lbName, nil
|
||||
}
|
||||
}
|
||||
|
||||
return true, "", nil
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue