• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kubernetes-sigs / blob-csi-driver / 14841670227

05 May 2025 04:49PM UTC coverage: 79.72%. Remained the same
14841670227

Pull #1984

github

web-flow
chore(deps): bump golang.org/x/sync from 0.13.0 to 0.14.0

Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.13.0 to 0.14.0.
- [Commits](https://github.com/golang/sync/compare/v0.13.0...v0.14.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sync
  dependency-version: 0.14.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #1984: chore(deps): bump golang.org/x/sync from 0.13.0 to 0.14.0

2390 of 2998 relevant lines covered (79.72%)

7.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.09
/pkg/blob/azure.go
1
/*
2
Copyright 2017 The Kubernetes Authors.
3

4
Licensed under the Apache License, Version 2.0 (the "License");
5
you may not use this file except in compliance with the License.
6
You may obtain a copy of the License at
7

8
    http://www.apache.org/licenses/LICENSE-2.0
9

10
Unless required by applicable law or agreed to in writing, software
11
distributed under the License is distributed on an "AS IS" BASIS,
12
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
See the License for the specific language governing permissions and
14
limitations under the License.
15
*/
16

17
package blob
18

19
import (
20
        "fmt"
21
        "os"
22
        "strings"
23
        "time"
24

25
        "github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
26
        network "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v6"
27
        "github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets"
28
        azure2 "github.com/Azure/go-autorest/autorest/azure"
29
        "golang.org/x/net/context"
30
        "k8s.io/apimachinery/pkg/util/wait"
31
        "k8s.io/client-go/kubernetes"
32
        "k8s.io/klog/v2"
33
        "k8s.io/utils/ptr"
34
        "sigs.k8s.io/cloud-provider-azure/pkg/azclient"
35
        "sigs.k8s.io/cloud-provider-azure/pkg/azclient/configloader"
36
        azcache "sigs.k8s.io/cloud-provider-azure/pkg/cache"
37
        azure "sigs.k8s.io/cloud-provider-azure/pkg/provider"
38
        azureconfig "sigs.k8s.io/cloud-provider-azure/pkg/provider/config"
39
        "sigs.k8s.io/cloud-provider-azure/pkg/provider/storage"
40
)
41

42
var (
43
        DefaultAzureCredentialFileEnv = "AZURE_CREDENTIAL_FILE"
44
        DefaultCredFilePath           = "/etc/kubernetes/azure.json"
45
        storageService                = "Microsoft.Storage"
46
)
47

48
// IsAzureStackCloud decides whether the driver is running on Azure Stack Cloud.
49
func IsAzureStackCloud(cloud *storage.AccountRepo) bool {
10✔
50
        return cloud != nil && !cloud.DisableAzureStackCloud && strings.EqualFold(cloud.Cloud, "AZURESTACKCLOUD")
10✔
51
}
10✔
52

53
// getCloudProvider get Azure Cloud Provider
54
func GetCloudProvider(ctx context.Context, kubeClient kubernetes.Interface, nodeID, secretName, secretNamespace, userAgent string, allowEmptyCloudConfig bool) (*storage.AccountRepo, error) {
5✔
55
        var (
5✔
56
                config     *azureconfig.Config
5✔
57
                fromSecret bool
5✔
58
                err        error
5✔
59
        )
5✔
60

5✔
61
        repo := &storage.AccountRepo{}
5✔
62
        defer func() {
10✔
63
                if repo.Environment == nil || repo.Environment.StorageEndpointSuffix == "" {
8✔
64
                        repo.Environment = &azclient.Environment{
3✔
65
                                StorageEndpointSuffix: defaultStorageEndPointSuffix,
3✔
66
                        }
3✔
67
                }
3✔
68
        }()
69

70
        if kubeClient != nil {
7✔
71
                klog.V(2).Infof("reading cloud config from secret %s/%s", secretNamespace, secretName)
2✔
72
                config, err = configloader.Load[azureconfig.Config](ctx, &configloader.K8sSecretLoaderConfig{
2✔
73
                        K8sSecretConfig: configloader.K8sSecretConfig{
2✔
74
                                SecretName:      secretName,
2✔
75
                                SecretNamespace: secretNamespace,
2✔
76
                                CloudConfigKey:  "cloud-config",
2✔
77
                        },
2✔
78
                        KubeClient: kubeClient,
2✔
79
                }, nil)
2✔
80
                if err == nil && config != nil {
2✔
81
                        fromSecret = true
×
82
                }
×
83
                if err != nil {
4✔
84
                        klog.V(2).Infof("InitializeCloudFromSecret: failed to get cloud config from secret %s/%s: %v", secretNamespace, secretName, err)
2✔
85
                }
2✔
86
        }
87

88
        if config == nil {
10✔
89
                klog.V(2).Infof("could not read cloud config from secret %s/%s", secretNamespace, secretName)
5✔
90
                credFile, ok := os.LookupEnv(DefaultAzureCredentialFileEnv)
5✔
91
                if ok && strings.TrimSpace(credFile) != "" {
7✔
92
                        klog.V(2).Infof("%s env var set as %v", DefaultAzureCredentialFileEnv, credFile)
2✔
93
                } else {
5✔
94
                        credFile = DefaultCredFilePath
3✔
95
                        klog.V(2).Infof("use default %s env var: %v", DefaultAzureCredentialFileEnv, credFile)
3✔
96
                }
3✔
97

98
                config, err = configloader.Load[azureconfig.Config](ctx, nil, &configloader.FileLoaderConfig{
5✔
99
                        FilePath: credFile,
5✔
100
                })
5✔
101
                if err != nil {
8✔
102
                        klog.Warningf("load azure config from file(%s) failed with %v", credFile, err)
3✔
103
                }
3✔
104
        }
105

106
        if config == nil {
8✔
107
                if allowEmptyCloudConfig {
5✔
108
                        klog.V(2).Infof("no cloud config provided, error: %v, driver will run without cloud config", err)
2✔
109
                } else {
3✔
110
                        return repo, fmt.Errorf("no cloud config provided, error: %w", err)
1✔
111
                }
1✔
112
        } else {
2✔
113
                config.UserAgent = userAgent
2✔
114
                config.CloudProviderBackoff = true
2✔
115
                // these environment variables are injected by workload identity webhook
2✔
116
                if tenantID := os.Getenv("AZURE_TENANT_ID"); tenantID != "" {
3✔
117
                        config.TenantID = tenantID
1✔
118
                }
1✔
119
                if clientID := os.Getenv("AZURE_CLIENT_ID"); clientID != "" {
3✔
120
                        config.AADClientID = clientID
1✔
121
                }
1✔
122
                if federatedTokenFile := os.Getenv("AZURE_FEDERATED_TOKEN_FILE"); federatedTokenFile != "" {
3✔
123
                        config.AADFederatedTokenFile = federatedTokenFile
1✔
124
                        config.UseFederatedWorkloadIdentityExtension = true
1✔
125
                }
1✔
126
                az := &azure.Cloud{}
2✔
127
                if err = az.InitializeCloudFromConfig(ctx, config, fromSecret, false); err != nil {
2✔
128
                        klog.Warningf("InitializeCloudFromConfig failed with error: %v", err)
×
129
                }
×
130
                _, env, err := azclient.GetAzureCloudConfigAndEnvConfig(&config.ARMClientConfig)
2✔
131
                if err != nil {
2✔
132
                        return nil, fmt.Errorf("failed to get AzureCloudConfigAndEnvConfig: %v", err)
×
133
                }
×
134

135
                if nodeID == "" {
4✔
136
                        // Disable UseInstanceMetadata for controller to mitigate a timeout issue using IMDS
2✔
137
                        // https://github.com/kubernetes-sigs/azuredisk-csi-driver/issues/168
2✔
138
                        klog.V(2).Infof("disable UseInstanceMetadata for controller server")
2✔
139
                        config.UseInstanceMetadata = false
2✔
140
                        klog.V(2).Infof("starting controller server...")
2✔
141
                } else {
2✔
142
                        klog.V(2).Infof("starting node server on node(%s)", nodeID)
×
143
                }
×
144

145
                repo, err = storage.NewRepository(*config, env, az.ComputeClientFactory, az.NetworkClientFactory)
2✔
146
                if err != nil {
2✔
147
                        return nil, fmt.Errorf("failed to create storage repository: %v", err)
×
148
                }
×
149
        }
150

151
        return repo, nil
4✔
152
}
153

154
// getKeyVaultSecretContent get content of the keyvault secret
155
func (d *Driver) getKeyVaultSecretContent(ctx context.Context, vaultURL string, secretName string, secretVersion string) (content string, err error) {
3✔
156
        var authProvider *azclient.AuthProvider
3✔
157
        authProvider, err = azclient.NewAuthProvider(&d.cloud.ARMClientConfig, &d.cloud.AzureAuthConfig)
3✔
158
        if err != nil {
4✔
159
                return "", err
1✔
160
        }
1✔
161
        kvClient, err := azsecrets.NewClient(vaultURL, authProvider.GetAzIdentity(), nil)
2✔
162
        if err != nil {
2✔
163
                return "", fmt.Errorf("failed to get keyvaultClient: %w", err)
×
164
        }
×
165

166
        klog.V(2).Infof("get secret from vaultURL(%v), sercretName(%v), secretVersion(%v)", vaultURL, secretName, secretVersion)
2✔
167
        secret, err := kvClient.GetSecret(ctx, secretName, secretVersion, nil)
2✔
168
        if err != nil {
4✔
169
                return "", fmt.Errorf("get secret from vaultURL(%v), sercretName(%v), secretVersion(%v) failed with error: %w", vaultURL, secretName, secretVersion, err)
2✔
170
        }
2✔
171
        return *secret.Value, nil
×
172
}
173

174
func (d *Driver) updateSubnetServiceEndpoints(ctx context.Context, vnetResourceGroup, vnetName, subnetName string) ([]string, error) {
5✔
175
        var vnetResourceIDs []string
5✔
176
        if d.networkClientFactory == nil {
6✔
177
                return vnetResourceIDs, fmt.Errorf("networkClientFactory is nil")
1✔
178
        }
1✔
179

180
        if vnetResourceGroup == "" {
8✔
181
                vnetResourceGroup = d.cloud.ResourceGroup
4✔
182
                if len(d.cloud.VnetResourceGroup) > 0 {
4✔
183
                        vnetResourceGroup = d.cloud.VnetResourceGroup
×
184
                }
×
185
        }
186

187
        location := d.cloud.Location
4✔
188
        if vnetName == "" {
8✔
189
                vnetName = d.cloud.VnetName
4✔
190
        }
4✔
191

192
        klog.V(2).Infof("updateSubnetServiceEndpoints on vnetName: %s, subnetName: %s, location: %s", vnetName, subnetName, location)
4✔
193
        if vnetName == "" || location == "" {
4✔
194
                return vnetResourceIDs, fmt.Errorf("vnetName or location is empty")
×
195
        }
×
196

197
        lockKey := vnetResourceGroup + vnetName + subnetName
4✔
198
        cache, err := d.subnetCache.Get(ctx, lockKey, azcache.CacheReadTypeDefault)
4✔
199
        if err != nil {
4✔
200
                return nil, err
×
201
        }
×
202
        if cache != nil {
6✔
203
                vnetResourceIDs = cache.([]string)
2✔
204
                klog.V(2).Infof("subnet %s under vnet %s in rg %s is already updated, vnetResourceIDs: %v", subnetName, vnetName, vnetResourceGroup, vnetResourceIDs)
2✔
205
                return vnetResourceIDs, nil
2✔
206
        }
2✔
207

208
        d.subnetLockMap.LockEntry(lockKey)
2✔
209
        defer d.subnetLockMap.UnlockEntry(lockKey)
2✔
210

2✔
211
        var subnets []*network.Subnet
2✔
212
        if subnetName != "" {
4✔
213
                // list multiple subnets separated by comma
2✔
214
                subnetNames := strings.Split(subnetName, ",")
2✔
215
                for _, sn := range subnetNames {
4✔
216
                        sn = strings.TrimSpace(sn)
2✔
217
                        subnet, rerr := d.networkClientFactory.GetSubnetClient().Get(ctx, vnetResourceGroup, vnetName, sn, nil)
2✔
218
                        if rerr != nil {
2✔
219
                                return vnetResourceIDs, fmt.Errorf("failed to get the subnet %s under rg %s vnet %s: %v", subnetName, vnetResourceGroup, vnetName, rerr.Error())
×
220
                        }
×
221
                        subnets = append(subnets, subnet)
2✔
222
                }
223
        } else {
×
224
                var rerr error
×
225
                subnets, rerr = d.networkClientFactory.GetSubnetClient().List(ctx, vnetResourceGroup, vnetName)
×
226
                if rerr != nil {
×
227
                        return vnetResourceIDs, fmt.Errorf("failed to list the subnets under rg %s vnet %s: %v", vnetResourceGroup, vnetName, rerr.Error())
×
228
                }
×
229
        }
230

231
        for _, subnet := range subnets {
4✔
232
                if subnet.Name == nil {
3✔
233
                        return vnetResourceIDs, fmt.Errorf("subnet name is nil")
1✔
234
                }
1✔
235
                sn := *subnet.Name
1✔
236
                vnetResourceID := d.getSubnetResourceID(vnetResourceGroup, vnetName, sn)
1✔
237
                klog.V(2).Infof("set vnetResourceID %s", vnetResourceID)
1✔
238
                vnetResourceIDs = append(vnetResourceIDs, vnetResourceID)
1✔
239

1✔
240
                endpointLocaions := []*string{to.Ptr(location)}
1✔
241
                storageServiceEndpoint := &network.ServiceEndpointPropertiesFormat{
1✔
242
                        Service:   &storageService,
1✔
243
                        Locations: endpointLocaions,
1✔
244
                }
1✔
245
                storageServiceExists := false
1✔
246
                if subnet.Properties == nil {
1✔
247
                        subnet.Properties = &network.SubnetPropertiesFormat{}
×
248
                }
×
249
                if subnet.Properties.ServiceEndpoints == nil {
2✔
250
                        subnet.Properties.ServiceEndpoints = []*network.ServiceEndpointPropertiesFormat{}
1✔
251
                }
1✔
252
                serviceEndpoints := subnet.Properties.ServiceEndpoints
1✔
253
                for _, v := range serviceEndpoints {
1✔
254
                        if strings.HasPrefix(ptr.Deref(v.Service, ""), storageService) {
×
255
                                storageServiceExists = true
×
256
                                klog.V(4).Infof("serviceEndpoint(%s) is already in subnet(%s)", storageService, sn)
×
257
                                break
×
258
                        }
259
                }
260

261
                if !storageServiceExists {
2✔
262
                        serviceEndpoints = append(serviceEndpoints, storageServiceEndpoint)
1✔
263
                        subnet.Properties.ServiceEndpoints = serviceEndpoints
1✔
264

1✔
265
                        klog.V(2).Infof("begin to update the subnet %s under vnet %s in rg %s", sn, vnetName, vnetResourceGroup)
1✔
266
                        if _, err := d.networkClientFactory.GetSubnetClient().CreateOrUpdate(ctx, vnetResourceGroup, vnetName, sn, *subnet); err != nil {
1✔
267
                                return vnetResourceIDs, fmt.Errorf("failed to update the subnet %s under vnet %s: %v", sn, vnetName, err)
×
268
                        }
×
269
                }
270
        }
271
        // cache the subnet update
272
        d.subnetCache.Set(lockKey, vnetResourceIDs)
1✔
273
        return vnetResourceIDs, nil
1✔
274
}
275

276
func (d *Driver) getStorageEndPointSuffix() string {
21✔
277
        if d.cloud == nil || d.cloud.Environment == nil || d.cloud.Environment.StorageEndpointSuffix == "" {
39✔
278
                return defaultStorageEndPointSuffix
18✔
279
        }
18✔
280
        return d.cloud.Environment.StorageEndpointSuffix
3✔
281
}
282

283
func (d *Driver) getCloudEnvironment() azure2.Environment {
2✔
284
        if d.cloud == nil || d.cloud.Environment == nil {
3✔
285
                return azure2.PublicCloud
1✔
286
        }
1✔
287
        return azure2.Environment{
1✔
288
                Name:                       d.cloud.Environment.Name,
1✔
289
                ServiceManagementEndpoint:  d.cloud.Environment.ServiceManagementEndpoint,
1✔
290
                ResourceManagerEndpoint:    d.cloud.Environment.ResourceManagerEndpoint,
1✔
291
                ActiveDirectoryEndpoint:    d.cloud.Environment.ActiveDirectoryEndpoint,
1✔
292
                StorageEndpointSuffix:      d.cloud.Environment.StorageEndpointSuffix,
1✔
293
                ContainerRegistryDNSSuffix: d.cloud.Environment.ContainerRegistryDNSSuffix,
1✔
294
                TokenAudience:              d.cloud.Environment.TokenAudience,
1✔
295
        }
1✔
296
}
297

298
// getBackOff returns a backoff object based on the config
299
func getBackOff(config azureconfig.Config) wait.Backoff {
19✔
300
        steps := config.CloudProviderBackoffRetries
19✔
301
        if steps < 1 {
37✔
302
                steps = 1
18✔
303
        }
18✔
304
        return wait.Backoff{
19✔
305
                Steps:    steps,
19✔
306
                Factor:   config.CloudProviderBackoffExponent,
19✔
307
                Jitter:   config.CloudProviderBackoffJitter,
19✔
308
                Duration: time.Duration(config.CloudProviderBackoffDuration) * time.Second,
19✔
309
        }
19✔
310
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc