-
Notifications
You must be signed in to change notification settings - Fork 95
/
azure.go
95 lines (77 loc) · 3.24 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
/*
Copyright 2023 The Radius 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 credentials
import (
"context"
"errors"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/radius-project/radius/pkg/sdk"
"github.com/radius-project/radius/pkg/to"
ucpapi "github.com/radius-project/radius/pkg/ucp/api/v20231001preview"
"github.com/radius-project/radius/pkg/ucp/secret"
"github.com/radius-project/radius/pkg/ucp/secret/provider"
)
var _ CredentialProvider[AzureCredential] = (*AzureCredentialProvider)(nil)
// AzureCredentialProvider is UCP credential provider for Azure.
type AzureCredentialProvider struct {
secretProvider *provider.SecretProvider
client *ucpapi.AzureCredentialsClient
}
// NewAzureCredentialProvider creates a new AzureCredentialProvider by creating a new AzureCredentialClient with the given
// credential and connection, and returns an error if one occurs.
func NewAzureCredentialProvider(provider *provider.SecretProvider, ucpConn sdk.Connection, credential azcore.TokenCredential) (*AzureCredentialProvider, error) {
cli, err := ucpapi.NewAzureCredentialsClient(credential, sdk.NewClientOptions(ucpConn))
if err != nil {
return nil, err
}
return &AzureCredentialProvider{
secretProvider: provider,
client: cli,
}, nil
}
// Fetch fetches the Azure service principal credentials from UCP and the internal storage (e.g.
// Kubernetes secret store) and returns an AzureCredential struct. If an error occurs, an error is returned.
func (p *AzureCredentialProvider) Fetch(ctx context.Context, planeName, name string) (*AzureCredential, error) {
// 1. Fetch the secret name of Azure service principal credentials from UCP.
cred, err := p.client.Get(ctx, planeName, name, &ucpapi.AzureCredentialsClientGetOptions{})
if err != nil {
return nil, err
}
// We support only kubernetes secret, but we may support multiple secret stores.
var storage *ucpapi.InternalCredentialStorageProperties
switch p := cred.Properties.(type) {
case *ucpapi.AzureServicePrincipalProperties:
switch c := p.Storage.(type) {
case *ucpapi.InternalCredentialStorageProperties:
storage = c
default:
return nil, errors.New("invalid AzureServicePrincipalProperties")
}
default:
return nil, errors.New("invalid InternalCredentialStorageProperties")
}
secretName := to.String(storage.SecretName)
if secretName == "" {
return nil, errors.New("unspecified SecretName for internal storage")
}
// 2. Fetch the credential from internal storage (e.g. Kubernetes secret store)
secretClient, err := p.secretProvider.GetClient(ctx)
if err != nil {
return nil, err
}
s, err := secret.GetSecret[AzureCredential](ctx, secretClient, secretName)
if err != nil {
return nil, errors.New("failed to get credential info: " + err.Error())
}
return &s, nil
}