Skip to content

Commit 2a08c35

Browse files
authored
Merge pull request #3 from DoodleScheduling/improvements
Refactoring & improvements DK-1724
2 parents f12549f + 7bdd176 commit 2a08c35

Some content is hidden

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

57 files changed

+2875
-2279
lines changed

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Build the manager binary
2-
FROM golang:1.13 as builder
2+
FROM golang:1.15 as builder
33

44
WORKDIR /workspace
55
# Copy the Go Modules manifests

Jenkinsfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ podTemplate(label: 'kubedb',
55
containers: [
66
containerTemplate(
77
name: 'golang',
8-
image: 'bitnami/golang:1.13',
8+
image: 'bitnami/golang:1.15',
99
ttyEnabled: true
1010
),
1111
containerTemplate(
@@ -28,7 +28,7 @@ podTemplate(label: 'kubedb',
2828
ansiColor("xterm") {
2929
stage('checkout') {
3030
checkout(scm)
31-
31+
3232
container('docker') {
3333
dockerAuth()
3434
}
@@ -66,8 +66,8 @@ podTemplate(label: 'kubedb',
6666
bumpImageVersion(env.TAG_NAME)
6767

6868
tgz="kubedb-${version}.tgz"
69+
sh "cp config/crd/bases/* chart/kubedb/crds"
6970
sh "helm package chart/kubedb"
70-
7171
}
7272

7373
container('golang') {

Makefile

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11

22
# Image URL to use all building/pushing image targets
33
IMG ?= controller:latest
4-
# Produce CRDs that work back to Kubernetes 1.11 (no version conversion)
5-
CRD_OPTIONS ?= "crd:trivialVersions=true"
4+
5+
# Produce CRDs that work back to Kubernetes 1.16
6+
CRD_OPTIONS ?= crd:crdVersions=v1
67

78
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
89
ifeq (,$(shell go env GOBIN))
@@ -71,7 +72,7 @@ ifeq (, $(shell which controller-gen))
7172
CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\
7273
cd $$CONTROLLER_GEN_TMP_DIR ;\
7374
go mod init tmp ;\
74-
go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.2.5 ;\
75+
go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.3.0 ;\
7576
rm -rf $$CONTROLLER_GEN_TMP_DIR ;\
7677
}
7778
CONTROLLER_GEN=$(GOBIN)/controller-gen

PROJECT

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
domain: doodle.com
22
repo: github.com/doodlescheduling/kubedb
33
resources:
4-
- group: infra
5-
kind: MongoDB
4+
- group: dbprovisioning.infra.doodle.com
5+
kind: MongoDBDatabase
66
version: v1beta1
7-
- group: infra
8-
kind: PostgreSQL
7+
- group: dbprovisioning.infra.doodle.com
8+
kind: PostgreSQLDatabase
9+
version: v1beta1
10+
- group: dbprovisioning.infra.doodle.com
11+
kind: MongoDBUser
12+
version: v1beta1
13+
- group: dbprovisioning.infra.doodle.com
14+
kind: PostgreSQLUser
915
version: v1beta1
1016
version: "2"

README.md

Lines changed: 98 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,111 @@
1-
# KUBEDB
1+
# Database controller
22

3-
Kubernetes Controller that sets up databases, credentials and permissions in Doodle databases.
3+
Kubernetes Controller that deals with database and user provisioning.
4+
**Note**: This controller does not deploy database servers but rather manage on top of existing ones, use existing operators for this.
45

5-
Build with [kubebuilder](https://github.com/kubernetes-sigs/kubebuilder).
6+
## Example for PostgreSQL
67

7-
Work in progress.
8+
A `VaultBinding` binds a kubernetes vanialla secret to a vault path.
9+
Following a secret which fields shall be placed into vault:
810

9-
Name "kubedb" clashes with an open-source project: https://github.com/kubedb
10-
We're going to have naming "clashes" (not technical, but on human level) if we ever decide to use that one.
11+
```yaml
12+
apiVersion: v1
13+
kind: Secret
14+
metadata:
15+
name: postgresql-admin-credentials
16+
namespace: default
17+
data:
18+
password: MTIzNA==
19+
username: MTIzNA==
20+
---
21+
apiVersion: dbprovisioning.infra.doodle.com/v1beta1
22+
kind: PostgreSQLDatabase
23+
metadata:
24+
name: my-app
25+
namespace: default
26+
spec:
27+
address: "postgres://localhost:5432"
28+
rootSecret:
29+
name: postgresql-admin-credentials
30+
---
31+
apiVersion: dbprovisioning.infra.doodle.com/v1beta1
32+
kind: PostgreSQLUser
33+
metadata:
34+
name: my-app
35+
namespace: default
36+
spec:
37+
database:
38+
name: my-app
39+
credentials:
40+
name: my-app-postgresql-credentials
41+
---
42+
apiVersion: v1
43+
kind: Secret
44+
metadata:
45+
name: my-app-postgresql-credentials
46+
namespace: default
47+
data:
48+
password: MTIzNA==
49+
username: MTIzNA==
50+
```
1151
12-
TODO: Write proper README file.
52+
## Example for MongoDB
53+
```yaml
54+
apiVersion: v1
55+
kind: Secret
56+
metadata:
57+
name: mongodb-admin-credentials
58+
namespace: default
59+
data:
60+
password: MTIzNA==
61+
username: MTIzNA==
62+
---
63+
apiVersion: dbprovisioning.infra.doodle.com/v1beta1
64+
kind: MongoDBDatabase
65+
metadata:
66+
name: my-app
67+
namespace: default
68+
spec:
69+
address: "mongodb://localhost:27017"
70+
rootSecret:
71+
name: mongodb-admin-credentials
72+
---
73+
apiVersion: dbprovisioning.infra.doodle.com/v1beta1
74+
kind: MongoDBUser
75+
metadata:
76+
name: my-app
77+
namespace: default
78+
spec:
79+
database:
80+
name: my-app-mongodb-credentials
81+
credentials:
82+
name: my-app-mongodb
83+
---
84+
apiVersion: v1
85+
kind: Secret
86+
metadata:
87+
name: my-app-mongodb-credentials
88+
namespace: default
89+
data:
90+
password: MTIzNA==
91+
username: MTIzNA==
92+
```
1393
14-
Config options:
94+
## Helm chart
95+
96+
Please see [chart/kubedb](https://github.com/DoodleScheduling/kubedb) for the helm chart docs.
97+
98+
## Limitations
99+
100+
Currently there is no garbage collection implemented, meaning all the things created are not removed.
101+
This will be at least implemented for user provisioning. Discussion will stay open for databases.
102+
103+
## Configure the controller
15104
16105
ENV Variable | Argument | Default value | Example | Purpose |
17106
-------------|----------|---------------|---------|---------|
18107
METRICS_ADDR | --metrics-addr | :8080 | :8080 | Metrics port |
19108
ENABLE_LEADER_ELECTION | --enable-leader-election | false | true | Enable leader election |
20109
LEADER_ELECTION_NAMESPACE | --leader-election-namespace | "" | devops | Leader election namespace. Default is the same as controller.
21110
NAMESPACES | --namespaces | "" | devops,default | Namespaces to watch. Default: watch all namespaces |
22-
MAX_CONCURRENT_RECONCILES | --max-concurrent-reconciles | 1 | 5 | Maximum concurrent reconciles per controller. This config covers all controllers. TODO maybe have a separate flag for each controller? |
23-
24-
25-
26-
111+
MAX_CONCURRENT_RECONCILES | --max-concurrent-reconciles | 1 | 5 | Maximum concurrent reconciles per controller. This config covers all controllers. |

api/v1beta1/database_types.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package v1beta1
2+
3+
import (
4+
apimeta "k8s.io/apimachinery/pkg/api/meta"
5+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
6+
)
7+
8+
// Finalizer
9+
const (
10+
Finalizer = "infra.finalizers.doodle.com"
11+
)
12+
13+
// Status conditions
14+
const (
15+
DatabaseReadyConditionType = "DatabaseReady"
16+
UserReadyConditionType = "UserReady"
17+
)
18+
19+
// Status reasons
20+
const (
21+
SecretNotFoundReason = "SecretNotFoundFailed"
22+
ConnectionFailedReason = "ConnectionFailed"
23+
DatabaseProvisioningFailedReason = "DatabaseProvisioningFailed"
24+
DatabaseProvisiningSuccessfulReason = "DatabaseProvisiningSuccessful"
25+
DatabaseNotFoundReason = "DatabaseNotFoundReason"
26+
UserNotProvisionedReason = "UserNotProvisioned"
27+
UserProvisioningSuccessfulReason = "UserProvisioningSuccessful"
28+
CredentialsNotFoundReason = "CredentialsNotFound"
29+
CreateDatabaseFailedReason = "CreateDatabaseFailed"
30+
)
31+
32+
// DatabaseSpec defines the desired state of MongoDBDatabase
33+
type DatabaseSpec struct {
34+
// DatabaseName is by default the same as metata.name
35+
// +optional
36+
DatabaseName string `json:"databaseName"`
37+
38+
// The connect URI
39+
// +required
40+
Address string `json:"address"`
41+
42+
// Contains a credentials set of a user with enough permission to manage databases and user accounts
43+
// +required
44+
RootSecret *SecretReference `json:"rootSecret"`
45+
}
46+
47+
// DatabaseReference is a named reference to a database kind
48+
type DatabaseReference struct {
49+
// Name referrs to the name of the database kind, mist be located within the same namespace
50+
// +required
51+
Name string `json:"name"`
52+
}
53+
54+
// SecretReference is a named reference to a secret which contains user credentials
55+
type SecretReference struct {
56+
// Name referrs to the name of the secret, must be located whithin the same namespace
57+
// +required
58+
Name string `json:"name"`
59+
60+
// +optional
61+
// +kubebuilder:default:=username
62+
UserField string `json:"userField"`
63+
64+
// +optional
65+
// +kubebuilder:default:=password
66+
PasswordField string `json:"passwordField"`
67+
}
68+
69+
// conditionalResource is a resource with conditions
70+
type conditionalResource interface {
71+
GetStatusConditions() *[]metav1.Condition
72+
}
73+
74+
func DatabaseNotReadyCondition(in conditionalResource, reason, message string) {
75+
setResourceCondition(in, DatabaseReadyConditionType, metav1.ConditionFalse, reason, message)
76+
}
77+
78+
func DatabaseReadyCondition(in conditionalResource, reason, message string) {
79+
setResourceCondition(in, DatabaseReadyConditionType, metav1.ConditionTrue, reason, message)
80+
}
81+
82+
func UserNotReadyCondition(in conditionalResource, reason, message string) {
83+
setResourceCondition(in, UserReadyConditionType, metav1.ConditionFalse, reason, message)
84+
}
85+
86+
func UserReadyCondition(in conditionalResource, reason, message string) {
87+
setResourceCondition(in, UserReadyConditionType, metav1.ConditionTrue, reason, message)
88+
}
89+
90+
// setResourceCondition sets the given condition with the given status,
91+
// reason and message on a resource.
92+
func setResourceCondition(resource conditionalResource, condition string, status metav1.ConditionStatus, reason, message string) {
93+
conditions := resource.GetStatusConditions()
94+
95+
newCondition := metav1.Condition{
96+
Type: condition,
97+
Status: status,
98+
Reason: reason,
99+
Message: message,
100+
}
101+
102+
apimeta.SetStatusCondition(conditions, newCondition)
103+
}

api/v1beta1/groupversion_info.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ limitations under the License.
1616

1717
// Package v1beta1 contains API Schema definitions for the infra v1beta1 API group
1818
// +kubebuilder:object:generate=true
19-
// +groupName=infra.doodle.com
19+
// +groupName=dbprovisioning.infra.doodle.com
2020
package v1beta1
2121

2222
import (
@@ -26,7 +26,7 @@ import (
2626

2727
var (
2828
// GroupVersion is group version used to register these objects
29-
GroupVersion = schema.GroupVersion{Group: "infra.doodle.com", Version: "v1beta1"}
29+
GroupVersion = schema.GroupVersion{Group: "dbprovisioning.infra.doodle.com", Version: "v1beta1"}
3030

3131
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
3232
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}

0 commit comments

Comments
 (0)