-
Notifications
You must be signed in to change notification settings - Fork 2.7k
/
azure.go
102 lines (82 loc) · 3.36 KB
/
azure.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/*
Copyright 2024 The Rook Authors. All rights reserved.
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 kms
import (
"context"
"fmt"
"os"
"github.com/libopenstorage/secrets"
"github.com/libopenstorage/secrets/azure"
"github.com/pkg/errors"
"github.com/rook/rook/pkg/clusterd"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
const (
//#nosec G101 -- This is only the k8s secret name
azureClientCertSecretName = "AZURE_CERT_SECRET_NAME"
)
var kmsAzureManadatoryConnectionDetails = []string{azure.AzureVaultURL, azure.AzureTenantID, azure.AzureClientID, azureClientCertSecretName}
// IsAzure determines whether the configured KMS is Azure Key Vault
func (c *Config) IsAzure() bool {
return c.Provider == secrets.TypeAzure
}
// InitAzure initializes azure key vault client
func InitAzure(ctx context.Context, context *clusterd.Context, namespace string, config map[string]string) (secrets.Secrets, error) {
azureKVConfig, removecertFiles, err := azureKVCert(ctx, context, namespace, config)
if err != nil {
return nil, errors.Wrapf(err, "failed to setup azure client cert authentication")
}
defer removecertFiles()
// Convert map string to map interface
secretConfig := make(map[string]interface{})
for key, value := range azureKVConfig {
secretConfig[key] = string(value)
}
secrets, err := azure.New(secretConfig)
if err != nil {
return nil, errors.Wrapf(err, "failed to initialize azure client")
}
return secrets, nil
}
// azureKVCert retrivies azure client cert from the secret and stores that in a file
func azureKVCert(ctx context.Context, context *clusterd.Context, namespace string, config map[string]string) (newConfig map[string]string, removeCertFiles removeCertFilesFunction, retErr error) {
var filesToRemove []*os.File
defer func() {
removeCertFiles = getRemoveCertFiles(filesToRemove)
if retErr != nil {
removeCertFiles()
removeCertFiles = nil
}
}()
clientCertSecretName := config[azureClientCertSecretName]
if clientCertSecretName == "" {
return nil, removeCertFiles, fmt.Errorf("azure cert secret name is not provided in the connection details")
}
secret, err := context.Clientset.CoreV1().Secrets(namespace).Get(ctx, clientCertSecretName, v1.GetOptions{})
if err != nil {
return nil, removeCertFiles, errors.Wrapf(err, "failed to fetch tls k8s secret %q", clientCertSecretName)
}
// Generate a temp file
file, err := createTmpFile("", "cert.pem")
if err != nil {
return nil, removeCertFiles, errors.Wrapf(err, "failed to generate temp file for k8s secret %q content", clientCertSecretName)
}
err = os.WriteFile(file.Name(), secret.Data["CLIENT_CERT"], 0400)
if err != nil {
return nil, removeCertFiles, errors.Wrapf(err, "failed to write k8s secret %q content to a file", clientCertSecretName)
}
// Update the env var with the path
config[azure.AzureClientCertPath] = file.Name()
filesToRemove = append(filesToRemove, file)
return config, removeCertFiles, nil
}