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

kubernetes-sigs / blob-csi-driver / 4961304539

12 May 2023 05:20PM UTC coverage: 80.672%. First build
4961304539

push

github

GitHub
chore(deps): bump golang.org/x/net from 0.9.0 to 0.10.0

1824 of 2261 relevant lines covered (80.67%)

5.29 hits per line

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

87.03
/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
        "errors"
21
        "fmt"
22
        "os"
23
        "strings"
24

25
        "golang.org/x/net/context"
26

27
        kv "github.com/Azure/azure-sdk-for-go/services/keyvault/2016-10-01/keyvault"
28
        "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2022-07-01/network"
29
        "github.com/Azure/azure-sdk-for-go/storage"
30

31
        "github.com/Azure/go-autorest/autorest"
32

33
        clientset "k8s.io/client-go/kubernetes"
34
        "k8s.io/client-go/rest"
35
        "k8s.io/client-go/tools/clientcmd"
36
        "k8s.io/klog/v2"
37

38
        azure "sigs.k8s.io/cloud-provider-azure/pkg/provider"
39
        providerconfig "sigs.k8s.io/cloud-provider-azure/pkg/provider/config"
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 *azure.Cloud) bool {
7✔
50
        return !cloud.Config.DisableAzureStackCloud && strings.EqualFold(cloud.Config.Cloud, "AZURESTACKCLOUD")
7✔
51
}
7✔
52

53
// getCloudProvider get Azure Cloud Provider
54
func getCloudProvider(kubeconfig, nodeID, secretName, secretNamespace, userAgent string, allowEmptyCloudConfig bool, kubeAPIQPS float64, kubeAPIBurst int) (*azure.Cloud, error) {
8✔
55
        var (
8✔
56
                config     *azure.Config
8✔
57
                kubeClient *clientset.Clientset
8✔
58
                fromSecret bool
8✔
59
        )
8✔
60

8✔
61
        az := &azure.Cloud{
8✔
62
                InitSecretConfig: azure.InitSecretConfig{
8✔
63
                        SecretName:      secretName,
8✔
64
                        SecretNamespace: secretNamespace,
8✔
65
                        CloudConfigKey:  "cloud-config",
8✔
66
                },
8✔
67
        }
8✔
68
        az.Environment.StorageEndpointSuffix = storage.DefaultBaseURL
8✔
69

8✔
70
        kubeCfg, err := getKubeConfig(kubeconfig)
8✔
71
        if err == nil && kubeCfg != nil {
9✔
72
                // set QPS and QPS Burst as higher values
1✔
73
                klog.V(2).Infof("set QPS(%f) and QPS Burst(%d) for driver kubeClient", float32(kubeAPIQPS), kubeAPIBurst)
1✔
74
                kubeCfg.QPS = float32(kubeAPIQPS)
1✔
75
                kubeCfg.Burst = kubeAPIBurst
1✔
76
                if kubeClient, err = clientset.NewForConfig(kubeCfg); err != nil {
2✔
77
                        klog.Warningf("NewForConfig failed with error: %v", err)
1✔
78
                }
1✔
79
        } else {
7✔
80
                klog.Warningf("get kubeconfig(%s) failed with error: %v", kubeconfig, err)
7✔
81
                if !os.IsNotExist(err) && !errors.Is(err, rest.ErrNotInCluster) {
8✔
82
                        return az, fmt.Errorf("failed to get KubeClient: %w", err)
1✔
83
                }
1✔
84
        }
85

86
        if kubeClient != nil {
7✔
87
                klog.V(2).Infof("reading cloud config from secret %s/%s", az.SecretNamespace, az.SecretName)
×
88
                az.KubeClient = kubeClient
×
89
                config, err = az.GetConfigFromSecret()
×
90
                if err == nil && config != nil {
×
91
                        fromSecret = true
×
92
                }
×
93
                if err != nil {
×
94
                        klog.V(2).Infof("InitializeCloudFromSecret: failed to get cloud config from secret %s/%s: %v", az.SecretNamespace, az.SecretName, err)
×
95
                }
×
96
        }
97

98
        if config == nil {
14✔
99
                klog.V(2).Infof("could not read cloud config from secret %s/%s", az.SecretNamespace, az.SecretName)
7✔
100
                credFile, ok := os.LookupEnv(DefaultAzureCredentialFileEnv)
7✔
101
                if ok && strings.TrimSpace(credFile) != "" {
10✔
102
                        klog.V(2).Infof("%s env var set as %v", DefaultAzureCredentialFileEnv, credFile)
3✔
103
                } else {
7✔
104
                        credFile = DefaultCredFilePath
4✔
105
                        klog.V(2).Infof("use default %s env var: %v", DefaultAzureCredentialFileEnv, credFile)
4✔
106
                }
4✔
107

108
                credFileConfig, err := os.Open(credFile)
7✔
109
                if err != nil {
11✔
110
                        klog.Warningf("load azure config from file(%s) failed with %v", credFile, err)
4✔
111
                } else {
7✔
112
                        defer credFileConfig.Close()
3✔
113
                        klog.V(2).Infof("read cloud config from file: %s successfully", credFile)
3✔
114
                        if config, err = azure.ParseConfig(credFileConfig); err != nil {
3✔
115
                                klog.Warningf("parse config file(%s) failed with error: %v", credFile, err)
×
116
                        }
×
117
                }
118
        }
119

120
        if config == nil {
11✔
121
                if allowEmptyCloudConfig {
7✔
122
                        klog.V(2).Infof("no cloud config provided, error: %v, driver will run without cloud config", err)
3✔
123
                } else {
4✔
124
                        return az, fmt.Errorf("no cloud config provided, error: %w", err)
1✔
125
                }
1✔
126
        } else {
3✔
127
                config.UserAgent = userAgent
3✔
128
                config.CloudProviderBackoff = true
3✔
129
                if err = az.InitializeCloudFromConfig(context.TODO(), config, fromSecret, false); err != nil {
3✔
130
                        klog.Warningf("InitializeCloudFromConfig failed with error: %v", err)
×
131
                }
×
132
        }
133

134
        // reassign kubeClient
135
        if kubeClient != nil && az.KubeClient == nil {
6✔
136
                az.KubeClient = kubeClient
×
137
        }
×
138

139
        isController := (nodeID == "")
6✔
140
        if isController {
11✔
141
                if err == nil {
7✔
142
                        // Disable UseInstanceMetadata for controller to mitigate a timeout issue using IMDS
2✔
143
                        // https://github.com/kubernetes-sigs/azuredisk-csi-driver/issues/168
2✔
144
                        klog.V(2).Infof("disable UseInstanceMetadata for controller server")
2✔
145
                        az.Config.UseInstanceMetadata = false
2✔
146
                }
2✔
147
                klog.V(2).Infof("starting controller server...")
5✔
148
        } else {
1✔
149
                klog.V(2).Infof("starting node server on node(%s)", nodeID)
1✔
150
        }
1✔
151

152
        if az.Environment.StorageEndpointSuffix == "" {
6✔
153
                az.Environment.StorageEndpointSuffix = storage.DefaultBaseURL
×
154
        }
×
155
        return az, nil
6✔
156
}
157

158
// getKeyVaultSecretContent get content of the keyvault secret
159
func (d *Driver) getKeyVaultSecretContent(ctx context.Context, vaultURL string, secretName string, secretVersion string) (content string, err error) {
3✔
160
        kvClient, err := d.initializeKvClient()
3✔
161
        if err != nil {
5✔
162
                return "", fmt.Errorf("failed to get keyvaultClient: %w", err)
2✔
163
        }
2✔
164

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

173
func (d *Driver) initializeKvClient() (*kv.BaseClient, error) {
5✔
174
        kvClient := kv.New()
5✔
175
        token, err := d.getKeyvaultToken()
5✔
176
        if err != nil {
8✔
177
                return nil, err
3✔
178
        }
3✔
179

180
        kvClient.Authorizer = token
2✔
181
        return &kvClient, nil
2✔
182
}
183

184
// getKeyvaultToken retrieves a new service principal token to access keyvault
185
func (d *Driver) getKeyvaultToken() (authorizer autorest.Authorizer, err error) {
7✔
186
        env := d.cloud.Environment
7✔
187
        kvEndPoint := strings.TrimSuffix(env.KeyVaultEndpoint, "/")
7✔
188
        servicePrincipalToken, err := providerconfig.GetServicePrincipalToken(&d.cloud.Config.AzureAuthConfig, &env, kvEndPoint)
7✔
189
        if err != nil {
11✔
190
                return nil, err
4✔
191
        }
4✔
192
        authorizer = autorest.NewBearerAuthorizer(servicePrincipalToken)
3✔
193
        return authorizer, nil
3✔
194
}
195

196
func (d *Driver) updateSubnetServiceEndpoints(ctx context.Context, vnetResourceGroup, vnetName, subnetName string) error {
7✔
197
        if d.cloud.SubnetsClient == nil {
9✔
198
                return fmt.Errorf("SubnetsClient is nil")
2✔
199
        }
2✔
200

201
        if vnetResourceGroup == "" {
10✔
202
                vnetResourceGroup = d.cloud.ResourceGroup
5✔
203
                if len(d.cloud.VnetResourceGroup) > 0 {
5✔
204
                        vnetResourceGroup = d.cloud.VnetResourceGroup
×
205
                }
×
206
        }
207

208
        location := d.cloud.Location
5✔
209
        if vnetName == "" {
10✔
210
                vnetName = d.cloud.VnetName
5✔
211
        }
5✔
212
        if subnetName == "" {
10✔
213
                subnetName = d.cloud.SubnetName
5✔
214
        }
5✔
215

216
        klog.V(2).Infof("updateSubnetServiceEndpoints on vnetName: %s, subnetName: %s, location: %s", vnetName, subnetName, location)
5✔
217
        if subnetName == "" || vnetName == "" || location == "" {
5✔
218
                return fmt.Errorf("value of subnetName, vnetName or location is empty")
×
219
        }
×
220

221
        lockKey := vnetResourceGroup + vnetName + subnetName
5✔
222
        d.subnetLockMap.LockEntry(lockKey)
5✔
223
        defer d.subnetLockMap.UnlockEntry(lockKey)
5✔
224

5✔
225
        subnet, err := d.cloud.SubnetsClient.Get(ctx, vnetResourceGroup, vnetName, subnetName, "")
5✔
226
        if err != nil {
6✔
227
                return fmt.Errorf("failed to get the subnet %s under vnet %s: %v", subnetName, vnetName, err)
1✔
228
        }
1✔
229
        endpointLocaions := []string{location}
4✔
230
        storageServiceEndpoint := network.ServiceEndpointPropertiesFormat{
4✔
231
                Service:   &storageService,
4✔
232
                Locations: &endpointLocaions,
4✔
233
        }
4✔
234
        storageServiceExists := false
4✔
235
        if subnet.SubnetPropertiesFormat == nil {
5✔
236
                subnet.SubnetPropertiesFormat = &network.SubnetPropertiesFormat{}
1✔
237
        }
1✔
238
        if subnet.SubnetPropertiesFormat.ServiceEndpoints == nil {
6✔
239
                subnet.SubnetPropertiesFormat.ServiceEndpoints = &[]network.ServiceEndpointPropertiesFormat{}
2✔
240
        }
2✔
241
        serviceEndpoints := *subnet.SubnetPropertiesFormat.ServiceEndpoints
4✔
242
        for _, v := range serviceEndpoints {
5✔
243
                if v.Service != nil && *v.Service == storageService {
2✔
244
                        storageServiceExists = true
1✔
245
                        klog.V(4).Infof("serviceEndpoint(%s) is already in subnet(%s)", storageService, subnetName)
1✔
246
                        break
1✔
247
                }
248
        }
249

250
        if !storageServiceExists {
7✔
251
                serviceEndpoints = append(serviceEndpoints, storageServiceEndpoint)
3✔
252
                subnet.SubnetPropertiesFormat.ServiceEndpoints = &serviceEndpoints
3✔
253

3✔
254
                if err := d.cloud.SubnetsClient.CreateOrUpdate(ctx, vnetResourceGroup, vnetName, subnetName, subnet); err != nil {
3✔
255
                        return fmt.Errorf("failed to update the subnet %s under vnet %s: %v", subnetName, vnetName, err)
×
256
                }
×
257
                klog.V(2).Infof("serviceEndpoint(%s) is appended in subnet(%s)", storageService, subnetName)
3✔
258
        }
259

260
        return nil
4✔
261
}
262

263
func getKubeConfig(kubeconfig string) (config *rest.Config, err error) {
10✔
264
        if kubeconfig != "" {
15✔
265
                if config, err = clientcmd.BuildConfigFromFlags("", kubeconfig); err != nil {
8✔
266
                        return nil, err
3✔
267
                }
3✔
268
        } else {
5✔
269
                if config, err = rest.InClusterConfig(); err != nil {
10✔
270
                        return nil, err
5✔
271
                }
5✔
272
        }
273
        return config, err
2✔
274
}
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