-
Notifications
You must be signed in to change notification settings - Fork 66
/
ensuresecret.go
135 lines (117 loc) · 4.15 KB
/
ensuresecret.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package connectionsecret
import (
"context"
"fmt"
"net/url"
corev1 "k8s.io/api/core/v1"
apiErrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/kube"
)
const (
ProjectLabelKey string = "atlas.mongodb.com/project-id"
ClusterLabelKey string = "atlas.mongodb.com/cluster-name"
TypeLabelKey = "atlas.mongodb.com/type"
CredLabelVal = "credentials"
standardKey string = "connectionStringStandard"
standardKeySrv string = "connectionStringStandardSrv"
privateKey string = "connectionStringPrivate"
privateKeySrv string = "connectionStringPrivateSrv"
privateShardKey string = "connectionStringPrivateShard"
userNameKey string = "username"
passwordKey string = "password"
)
type ConnectionData struct {
DBUserName string
Password string
ConnURL string
SrvConnURL string
PrivateConnURLs []PrivateLinkConnURLs
}
type PrivateLinkConnURLs struct {
PvtConnURL string
PvtSrvConnURL string
PvtShardConnURL string
}
// Ensure creates or updates the connection Secret for the specific cluster and db user. Returns the name of the Secret
// created.
func Ensure(ctx context.Context, client client.Client, namespace, projectName, projectID, clusterName string, data ConnectionData) (string, error) {
var getError error
s := &corev1.Secret{ObjectMeta: metav1.ObjectMeta{
Name: formatSecretName(projectName, clusterName, data.DBUserName),
Namespace: namespace,
}}
if getError = client.Get(ctx, kube.ObjectKeyFromObject(s), s); getError != nil && !apiErrors.IsNotFound(getError) {
return "", getError
}
if err := fillSecret(s, projectID, clusterName, data); err != nil {
return "", err
}
if getError != nil {
// Creating
return s.Name, client.Create(ctx, s)
}
return s.Name, client.Update(ctx, s)
}
func fillSecret(secret *corev1.Secret, projectID string, clusterName string, data ConnectionData) error {
var err error
if data.ConnURL, err = AddCredentialsToConnectionURL(data.ConnURL, data.DBUserName, data.Password); err != nil {
return err
}
if data.SrvConnURL, err = AddCredentialsToConnectionURL(data.SrvConnURL, data.DBUserName, data.Password); err != nil {
return err
}
for idx, privateConn := range data.PrivateConnURLs {
if data.PrivateConnURLs[idx].PvtConnURL, err = AddCredentialsToConnectionURL(privateConn.PvtConnURL, data.DBUserName, data.Password); err != nil {
return err
}
if data.PrivateConnURLs[idx].PvtSrvConnURL, err = AddCredentialsToConnectionURL(privateConn.PvtSrvConnURL, data.DBUserName, data.Password); err != nil {
return err
}
if data.PrivateConnURLs[idx].PvtShardConnURL, err = AddCredentialsToConnectionURL(privateConn.PvtShardConnURL, data.DBUserName, data.Password); err != nil {
return err
}
}
secret.Labels = map[string]string{
TypeLabelKey: CredLabelVal,
ProjectLabelKey: projectID,
ClusterLabelKey: kube.NormalizeLabelValue(clusterName),
}
secret.Data = map[string][]byte{
userNameKey: []byte(data.DBUserName),
passwordKey: []byte(data.Password),
standardKey: []byte(data.ConnURL),
standardKeySrv: []byte(data.SrvConnURL),
privateKey: []byte(""),
privateKeySrv: []byte(""),
}
for idx, privateConn := range data.PrivateConnURLs {
suffix := getSuffix(idx)
secret.Data[privateKey+suffix] = []byte(privateConn.PvtConnURL)
secret.Data[privateKeySrv+suffix] = []byte(privateConn.PvtSrvConnURL)
secret.Data[privateShardKey+suffix] = []byte(privateConn.PvtShardConnURL)
}
return nil
}
func getSuffix(idx int) string {
if idx == 0 {
return ""
}
return fmt.Sprint(idx)
}
func formatSecretName(projectName, clusterName, dbUserName string) string {
name := fmt.Sprintf("%s-%s-%s",
kube.NormalizeIdentifier(projectName),
kube.NormalizeIdentifier(clusterName),
kube.NormalizeIdentifier(dbUserName))
return kube.NormalizeIdentifier(name)
}
func AddCredentialsToConnectionURL(connURL, userName, password string) (string, error) {
cs, err := url.Parse(connURL)
if err != nil {
return "", err
}
cs.User = url.UserPassword(userName, password)
return cs.String(), nil
}