Skip to content

Commit 52ae11f

Browse files
committed
Merge branch 'master' into feature/plan-action-timeout
2 parents 43ffc34 + 265397d commit 52ae11f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1403
-205
lines changed

deps/github.com/arangodb/arangosync/client/client_cache.go

+7-2
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,10 @@ func (cc *ClientCache) createClient(source Endpoint, auth Authentication, insecu
8585
return nil, maskAny(err)
8686
}
8787
ac := AuthenticationConfig{}
88-
if auth.JWTSecret != "" {
88+
if auth.Username != "" {
89+
ac.UserName = auth.Username
90+
ac.Password = auth.Password
91+
} else if auth.JWTSecret != "" {
8992
ac.JWTSecret = auth.JWTSecret
9093
} else if auth.ClientToken != "" {
9194
ac.BearerToken = auth.ClientToken
@@ -113,11 +116,13 @@ func NewAuthentication(tlsAuth TLSAuthentication, jwtSecret string) Authenticati
113116
type Authentication struct {
114117
TLSAuthentication
115118
JWTSecret string
119+
Username string
120+
Password string
116121
}
117122

118123
// String returns a string used to unique identify the authentication settings.
119124
func (a Authentication) String() string {
120-
return a.TLSAuthentication.String() + ":" + a.JWTSecret
125+
return a.TLSAuthentication.String() + ":" + a.JWTSecret + ":" + a.Username + ":" + a.Password
121126
}
122127

123128
// AuthProxy is a helper that implements github.com/arangodb-helper/go-certificates#TLSAuthentication.

docs/Manual/Deployment/Kubernetes/DeploymentReplicationResource.md

+126-29
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ The ArangoDB Replication Operator creates and maintains ArangoDB
55
This replication specification is a `CustomResource` following
66
a `CustomResourceDefinition` created by the operator.
77

8-
Example minimal replication definition:
8+
Example minimal replication definition for 2 ArangoDB cluster with sync in the same Kubernetes cluster:
99

1010
```yaml
1111
apiVersion: "replication.database.arangodb.com/v1alpha"
@@ -15,17 +15,46 @@ metadata:
1515
spec:
1616
source:
1717
deploymentName: cluster-a
18+
auth:
19+
keyfileSecretName: cluster-a-sync-auth
1820
destination:
1921
deploymentName: cluster-b
20-
auth:
21-
clientAuthSecretName: client-auth-cert
2222
```
2323
2424
This definition results in:
2525
2626
- the arangosync `SyncMaster` in deployment `cluster-b` is called to configure a synchronization
27-
from `cluster-a` to `cluster-b`, using the client authentication certificate stored in
28-
`Secret` `client-auth-cert`.
27+
from the syncmasters in `cluster-a` to the syncmasters in `cluster-b`,
28+
using the client authentication certificate stored in `Secret` `cluster-a-sync-auth`.
29+
To access `cluster-a`, the JWT secret found in the deployment of `cluster-a` is used.
30+
To access `cluster-b`, the JWT secret found in the deployment of `cluster-b` is used.
31+
32+
Example replication definition for replicating from a source that is outside the current Kubernetes cluster
33+
to a destination that is in the same Kubernetes cluster:
34+
35+
```yaml
36+
apiVersion: "replication.database.arangodb.com/v1alpha"
37+
kind: "ArangoDeploymentReplication"
38+
metadata:
39+
name: "replication-from-a-to-b"
40+
spec:
41+
source:
42+
endpoint: ["https://163.172.149.229:31888", "https://51.15.225.110:31888", "https://51.15.229.133:31888"]
43+
auth:
44+
keyfileSecretName: cluster-a-sync-auth
45+
tls:
46+
caSecretName: cluster-a-sync-ca
47+
destination:
48+
deploymentName: cluster-b
49+
```
50+
51+
This definition results in:
52+
53+
- the arangosync `SyncMaster` in deployment `cluster-b` is called to configure a synchronization
54+
from the syncmasters located at the given list of endpoint URL's to the syncmasters `cluster-b`,
55+
using the client authentication certificate stored in `Secret` `cluster-a-sync-auth`.
56+
To access `cluster-a`, the keyfile (containing a client authentication certificate) is used.
57+
To access `cluster-b`, the JWT secret found in the deployment of `cluster-b` is used.
2958

3059
## Specification reference
3160

@@ -38,13 +67,7 @@ with sync enabled.
3867

3968
This cluster configured as the replication source.
4069

41-
### `spec.source.deploymentNamespace: string`
42-
43-
This setting specifies the Kubernetes namespace of an `ArangoDeployment` resource specified in `spec.source.deploymentName`.
44-
45-
If this setting is empty, the namespace of the `ArangoDeploymentReplication` is used.
46-
47-
### `spec.source.masterEndpoints: []string`
70+
### `spec.source.endpoint: []string`
4871

4972
This setting specifies zero or more master endpoint URL's of the source cluster.
5073

@@ -53,12 +76,23 @@ that is reachable from the Kubernetes cluster the `ArangoDeploymentReplication`
5376

5477
Specifying this setting and `spec.source.deploymentName` at the same time is not allowed.
5578

56-
### `spec.source.auth.jwtSecretName: string`
79+
### `spec.source.auth.keyfileSecretName: string`
5780

58-
This setting specifies the name of a `Secret` containing a JWT `token` used to authenticate
81+
This setting specifies the name of a `Secret` containing a client authentication certificate called `tls.keyfile` used to authenticate
5982
with the SyncMaster at the specified source.
6083

61-
This setting is required, unless `spec.source.deploymentName` has been set.
84+
If `spec.source.auth.userSecretName` has not been set,
85+
the client authentication certificate found in the secret with this name is also used to configure
86+
the synchronization and fetch the synchronization status.
87+
88+
This setting is required.
89+
90+
### `spec.source.auth.userSecretName: string`
91+
92+
This setting specifies the name of a `Secret` containing a `username` & `password` used to authenticate
93+
with the SyncMaster at the specified source in order to configure synchronization and fetch synchronization status.
94+
95+
The user identified by the username must have write access in the `_system` database of the source ArangoDB cluster.
6296

6397
### `spec.source.tls.caSecretName: string`
6498

@@ -74,13 +108,7 @@ with sync enabled.
74108

75109
This cluster configured as the replication destination.
76110

77-
### `spec.destination.deploymentNamespace: string`
78-
79-
This setting specifies the Kubernetes namespace of an `ArangoDeployment` resource specified in `spec.destination.deploymentName`.
80-
81-
If this setting is empty, the namespace of the `ArangoDeploymentReplication` is used.
82-
83-
### `spec.destination.masterEndpoints: []string`
111+
### `spec.destination.endpoint: []string`
84112

85113
This setting specifies zero or more master endpoint URL's of the destination cluster.
86114

@@ -89,12 +117,27 @@ that is reachable from the Kubernetes cluster the `ArangoDeploymentReplication`
89117

90118
Specifying this setting and `spec.destination.deploymentName` at the same time is not allowed.
91119

92-
### `spec.destination.auth.jwtSecretName: string`
120+
### `spec.destination.auth.keyfileSecretName: string`
93121

94-
This setting specifies the name of a `Secret` containing a JWT `token` used to authenticate
122+
This setting specifies the name of a `Secret` containing a client authentication certificate called `tls.keyfile` used to authenticate
95123
with the SyncMaster at the specified destination.
96124

97-
This setting is required, unless `spec.destination.deploymentName` has been set.
125+
If `spec.destination.auth.userSecretName` has not been set,
126+
the client authentication certificate found in the secret with this name is also used to configure
127+
the synchronization and fetch the synchronization status.
128+
129+
This setting is required, unless `spec.destination.deploymentName` or `spec.destination.auth.userSecretName` has been set.
130+
131+
Specifying this setting and `spec.destination.userSecretName` at the same time is not allowed.
132+
133+
### `spec.destination.auth.userSecretName: string`
134+
135+
This setting specifies the name of a `Secret` containing a `username` & `password` used to authenticate
136+
with the SyncMaster at the specified destination in order to configure synchronization and fetch synchronization status.
137+
138+
The user identified by the username must have write access in the `_system` database of the destination ArangoDB cluster.
139+
140+
Specifying this setting and `spec.destination.keyfileSecretName` at the same time is not allowed.
98141

99142
### `spec.destination.tls.caSecretName: string`
100143

@@ -103,8 +146,62 @@ the TLS connection created by the SyncMaster at the specified destination.
103146

104147
This setting is required, unless `spec.destination.deploymentName` has been set.
105148

106-
### `spec.auth.clientAuthSecretName: string`
149+
## Authentication details
150+
151+
The authentication settings in a `ArangoDeploymentReplication` resource are used for two distinct purposes.
152+
153+
The first use is the authentication of the syncmasters at the destination with the syncmasters at the source.
154+
This is always done using a client authentication certificate which is found in a `tls.keyfile` field
155+
in a secret identified by `spec.source.auth.keyfileSecretName`.
156+
157+
The second use is the authentication of the ArangoDB Replication operator with the syncmasters at the source
158+
or destination. These connections are made to configure synchronization, stop configuration and fetch the status
159+
of the configuration.
160+
The method used for this authentication is derived as follows (where `X` is either `source` or `destination`):
161+
162+
- If `spec.X.userSecretName` is set, the username + password found in the `Secret` identified by this name is used.
163+
- If `spec.X.keyfileSecretName` is set, the client authentication certificate (keyfile) found in the `Secret` identifier by this name is used.
164+
- If `spec.X.deploymentName` is set, the JWT secret found in the deployment is used.
165+
166+
## Creating client authentication certificate keyfiles
167+
168+
The client authentication certificates needed for the `Secrets` identified by `spec.source.auth.keyfileSecretName` & `spec.destination.auth.keyfileSecretName`
169+
are normal ArangoDB keyfiles that can be created by the `arangosync create client-auth keyfile` command.
170+
In order to do so, you must have access to the client authentication CA of the source/destination.
171+
172+
If the client authentication CA at the source/destination also contains a private key (`ca.key`), the ArangoDeployment operator
173+
can be used to create such a keyfile for you, without the need to have `arangosync` installed locally.
174+
Read the following paragraphs for instructions on how to do that.
175+
176+
## Creating and using access packages
177+
178+
An access package is a YAML file that contains:
179+
180+
- A client authentication certificate, wrapped in a `Secret` in a `tls.keyfile` data field.
181+
- A TLS certificate authority public key, wrapped in a `Secret` in a `ca.crt` data field.
182+
183+
The format of the access package is such that it can be inserted into a Kubernetes cluster using the standard `kubectl` tool.
184+
185+
To create an access package that can be used to authenticate with the ArangoDB SyncMasters of an `ArangoDeployment`,
186+
add a name of a non-existing `Secret` to the `spec.sync.externalAccess.accessPackageSecretNames` field of the `ArangoDeployment`.
187+
In response, a `Secret` is created in that Kubernetes cluster, with the given name, that contains a `accessPackage.yaml` data field
188+
that contains a Kubernetes resource specification that can be inserted into the other Kubernetes cluster.
189+
190+
The process for creating and using an access package for authentication at the source cluster is as follows:
191+
192+
- Edit the `ArangoDeployment` resource of the source cluster, set `spec.sync.externalAccess.accessPackageSecretNames` to `["my-access-package"]`
193+
- Wait for the `ArangoDeployment` operator to create a `Secret` named `my-access-package`.
194+
- Extract the access package from the Kubernetes source cluster using:
195+
196+
```bash
197+
kubectl get secret my-access-package --template='{{index .data "accessPackage.yaml"}}' | base64 -D > accessPackage.yaml
198+
```
199+
200+
- Insert the secrets found in the access package in the Kubernetes destination cluster using:
201+
202+
```bash
203+
kubectl apply -f accessPackage.yaml
204+
```
107205

108-
This setting specifies the name of a `Secret` containing a client authentication certificate,
109-
used to authenticate the SyncMaster in the destination cluster with the SyncMaster in the
110-
source cluster.
206+
As a result, the destination Kubernetes cluster will have 2 additional `Secrets`. One contains a client authentication certificate
207+
formatted as a keyfile. Another contains the public key of the TLS CA certificate of the source cluster.

docs/Manual/Deployment/Kubernetes/DeploymentResource.md

+21
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,19 @@ If not set, this setting defaults to:
241241
- If `spec.sync.externalAccess.loadBalancerIP` is set, it defaults to `https://<load-balancer-ip>:<8629>`.
242242
- Otherwise it defaults to `https://<sync-service-dns-name>:<8629>`.
243243

244+
### `spec.sync.externalAccess.accessPackageSecretNames: []string`
245+
246+
This setting specifies the names of zero of more `Secrets` that will be created by the deployment
247+
operator containing "access packages". An access package contains those `Secrets` that are needed
248+
to access the SyncMasters of this `ArangoDeployment`.
249+
250+
By removing a name from this setting, the corresponding `Secret` is also deleted.
251+
Note that to remove all access packages, leave an empty array in place (`[]`).
252+
Completely removing the setting results in not modifying the list.
253+
254+
See [the `ArangoDeploymentReplication` specification](./DeploymentReplicationResource.md) for more information
255+
on access packages.
256+
244257
### `spec.sync.auth.jwtSecretName: string`
245258

246259
This setting specifies the name of a kubernetes `Secret` that contains
@@ -335,6 +348,14 @@ The default value is `8Gi`.
335348
This setting is not available for group `coordinators`, `syncmasters` & `syncworkers`
336349
because servers in these groups do not need persistent storage.
337350

351+
### `spec.<group>.serviceAccountName: string`
352+
353+
This setting specifies the `serviceAccountName` for the `Pods` created
354+
for each server of this group.
355+
356+
Using an alternative `ServiceAccount` is typically used to separate access rights.
357+
The ArangoDB deployments do not require any special rights.
358+
338359
### `spec.<group>.storageClassName: string`
339360

340361
This setting specifies the `storageClass` for the `PersistentVolume`s created

main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ func cmdMainRun(cmd *cobra.Command, args []string) {
160160
mux := http.NewServeMux()
161161
mux.HandleFunc("/health", livenessProbe.LivenessHandler)
162162
mux.HandleFunc("/ready/deployment", deploymentProbe.ReadyHandler)
163-
mux.HandleFunc("/ready/deployment-replications", deploymentReplicationProbe.ReadyHandler)
163+
mux.HandleFunc("/ready/deployment-replication", deploymentReplicationProbe.ReadyHandler)
164164
mux.HandleFunc("/ready/storage", storageProbe.ReadyHandler)
165165
mux.Handle("/metrics", prometheus.Handler())
166166
listenAddr := net.JoinHostPort(serverOptions.host, strconv.Itoa(serverOptions.port))

manifests/templates/deployment-replication/deployment-replication.yaml

+10-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ metadata:
55
name: {{ .DeploymentReplication.OperatorDeploymentName }}
66
namespace: {{ .DeploymentReplication.Operator.Namespace }}
77
spec:
8-
replicas: 1
8+
replicas: 2
99
strategy:
1010
type: Recreate
1111
template:
@@ -50,3 +50,12 @@ spec:
5050
scheme: HTTPS
5151
initialDelaySeconds: 5
5252
periodSeconds: 10
53+
tolerations:
54+
- key: "node.kubernetes.io/unreachable"
55+
operator: "Exists"
56+
effect: "NoExecute"
57+
tolerationSeconds: 5
58+
- key: "node.kubernetes.io/not-ready"
59+
operator: "Exists"
60+
effect: "NoExecute"
61+
tolerationSeconds: 5

manifests/templates/deployment/deployment.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ metadata:
55
name: {{ .Deployment.OperatorDeploymentName }}
66
namespace: {{ .Deployment.Operator.Namespace }}
77
spec:
8-
replicas: 1
8+
replicas: 2
99
strategy:
1010
type: Recreate
1111
template:

manifests/templates/storage/deployment.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ metadata:
1313
name: {{ .Storage.OperatorDeploymentName }}
1414
namespace: {{ .Storage.Operator.Namespace }}
1515
spec:
16-
replicas: 1
16+
replicas: 2
1717
strategy:
1818
type: Recreate
1919
template:

manifests/templates/test/rbac.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ rules:
1010
resources: ["nodes"]
1111
verbs: ["list"]
1212
- apiGroups: [""]
13-
resources: ["pods", "services", "persistentvolumes", "persistentvolumeclaims", "secrets"]
13+
resources: ["pods", "services", "persistentvolumes", "persistentvolumeclaims", "secrets", "serviceaccounts"]
1414
verbs: ["*"]
1515
- apiGroups: ["apps"]
1616
resources: ["daemonsets"]

pkg/apis/deployment/v1alpha/conditions.go

+2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ const (
4646
// the deployment have changed. Once that is the case, the operator will no longer
4747
// touch the deployment, until the original secrets have been restored.
4848
ConditionTypeSecretsChanged ConditionType = "SecretsChanged"
49+
// ConditionTypeMemberOfCluster indicates that the member is a known member of the ArangoDB cluster.
50+
ConditionTypeMemberOfCluster ConditionType = "MemberOfCluster"
4951
)
5052

5153
// Condition represents one current condition of a deployment or deployment member.

pkg/apis/deployment/v1alpha/member_status.go

+5
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ type MemberStatus struct {
5252
IsInitialized bool `json:"initialized"`
5353
}
5454

55+
// Age returns the duration since the creation timestamp of this member.
56+
func (s MemberStatus) Age() time.Duration {
57+
return time.Since(s.CreatedAt.Time)
58+
}
59+
5560
// RemoveTerminationsBefore removes all recent terminations before the given timestamp.
5661
// It returns the number of terminations that have been removed.
5762
func (s *MemberStatus) RemoveTerminationsBefore(timestamp time.Time) int {

pkg/apis/deployment/v1alpha/server_group.go

+10
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,16 @@ func (g ServerGroup) DefaultTerminationGracePeriod() time.Duration {
101101
}
102102
}
103103

104+
// IsStateless returns true when the groups runs servers without a persistent volume.
105+
func (g ServerGroup) IsStateless() bool {
106+
switch g {
107+
case ServerGroupCoordinators, ServerGroupSyncMasters, ServerGroupSyncWorkers:
108+
return true
109+
default:
110+
return false
111+
}
112+
}
113+
104114
// IsArangod returns true when the groups runs servers of type `arangod`.
105115
func (g ServerGroup) IsArangod() bool {
106116
switch g {

0 commit comments

Comments
 (0)