forked from kyma-project/control-plane
-
Notifications
You must be signed in to change notification settings - Fork 0
/
account_pool.go
88 lines (72 loc) · 2.64 KB
/
account_pool.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
package hyperscaler
import (
"fmt"
"sync"
"github.com/gardener/gardener/pkg/apis/core/v1beta1"
gardener_apis "github.com/gardener/gardener/pkg/client/core/clientset/versioned/typed/core/v1beta1"
"github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type Type string
const (
Azure Type = "azure"
)
type Credentials struct {
Name string
TenantName string
HyperscalerType Type
CredentialData map[string][]byte
}
type AccountPool interface {
CredentialsSecretBinding(hyperscalerType Type, tenantName string) (*v1beta1.SecretBinding, error)
}
type secretBindingsAccountPool struct {
secretBindingsClient gardener_apis.SecretBindingInterface
mux sync.Mutex
}
// NewAccountPool returns a new AccountPool
func NewAccountPool(secretBindingsClient gardener_apis.SecretBindingInterface) AccountPool {
return &secretBindingsAccountPool{
secretBindingsClient: secretBindingsClient,
}
}
// Credentials returns the hyperscaler secret from k8s secret
func (p *secretBindingsAccountPool) CredentialsSecretBinding(hyperscalerType Type, tenantName string) (*v1beta1.SecretBinding, error) {
labelSelector := fmt.Sprintf("tenantName=%s,hyperscalerType=%s", tenantName, hyperscalerType)
secretBinding, err := getSecretBinding(p.secretBindingsClient, labelSelector)
if err != nil {
return nil, err
}
if secretBinding != nil {
return secretBinding, nil
}
// lock so that only one thread can fetch an unassigned secret binding and assign it (update secret binding with tenantName)
p.mux.Lock()
defer p.mux.Unlock()
labelSelector = fmt.Sprintf("shared!=true, !tenantName, !dirty, hyperscalerType=%s", hyperscalerType)
secretBinding, err = getSecretBinding(p.secretBindingsClient, labelSelector)
if err != nil {
return nil, err
}
if secretBinding == nil {
return nil, errors.Errorf("failed to find unassigned secret binding for hyperscalerType: %s", hyperscalerType)
}
secretBinding.Labels["tenantName"] = tenantName
updatedSecretBinding, err := p.secretBindingsClient.Update(secretBinding)
if err != nil {
return nil, errors.Wrapf(err, "updating secret binding with tenantName: %s", tenantName)
}
return updatedSecretBinding, nil
}
func getSecretBinding(secretBindingsClient gardener_apis.SecretBindingInterface, labelSelector string) (*v1beta1.SecretBinding, error) {
secretBindings, err := secretBindingsClient.List(metav1.ListOptions{
LabelSelector: labelSelector,
})
if err != nil {
return nil, errors.Wrapf(err, "listing secret bindings for LabelSelector: %s", labelSelector)
}
if secretBindings != nil && len(secretBindings.Items) > 0 {
return &secretBindings.Items[0], nil
}
return nil, nil
}