Skip to content

Commit

Permalink
fix(connectionpool): check user exists (#734)
Browse files Browse the repository at this point in the history
  • Loading branch information
byashimov authored May 16, 2024
1 parent 4b17d24 commit 216e226
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 108 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- Change `Kafka` field `userConfig.kafka_version`: enum ~~`[3.4, 3.5, 3.6]`~~`[3.4, 3.5, 3.6, 3.7]`
- Add `ServiceIntegration` `flink_external_postgresql` type
- Remove `CA_CERT` secret key for `Grafana`, `OpenSearch`, `Redis`, and `Clickhouse`. Can't be used with these service types
- Fix `ConnectionPool` doesn't check service user precondition

## v0.19.0 - 2024-04-18

Expand Down
33 changes: 15 additions & 18 deletions controllers/connectionpool_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,10 @@ func (h ConnectionPoolHandler) delete(ctx context.Context, avn *aiven.Client, av

func (h ConnectionPoolHandler) exists(ctx context.Context, avn *aiven.Client, cp *v1alpha1.ConnectionPool) (bool, error) {
conPool, err := avn.ConnectionPools.Get(ctx, cp.Spec.Project, cp.Spec.ServiceName, cp.Name)
if err != nil {
if isNotFound(err) {
return false, nil
}
return false, err
if isNotFound(err) {
return false, nil
}

return conPool != nil, nil
return conPool != nil, err
}

func (h ConnectionPoolHandler) get(ctx context.Context, avn *aiven.Client, avnGen avngen.Client, obj client.Object) (*corev1.Secret, error) {
Expand Down Expand Up @@ -219,24 +215,25 @@ func (h ConnectionPoolHandler) checkPreconditions(ctx context.Context, avn *aive
meta.SetStatusCondition(&cp.Status.Conditions,
getInitializedCondition("Preconditions", "Checking preconditions"))

check, err := checkServiceIsRunning(ctx, avn, avnGen, cp.Spec.Project, cp.Spec.ServiceName)
isRunning, err := checkServiceIsRunning(ctx, avn, avnGen, cp.Spec.Project, cp.Spec.ServiceName)
if err != nil {
return false, err
}

if check {
db, err := avn.Databases.Get(ctx, cp.Spec.Project, cp.Spec.ServiceName, cp.Spec.DatabaseName)
if err != nil {
if isNotFound(err) {
return false, nil
}
return false, err
}
if !isRunning {
return false, nil
}

_, err = avn.Databases.Get(ctx, cp.Spec.Project, cp.Spec.ServiceName, cp.Spec.DatabaseName)
if err == nil {
_, err = avnGen.ServiceUserGet(ctx, cp.Spec.Project, cp.Spec.ServiceName, cp.Spec.Username)
}

return db != nil, nil
if isNotFound(err) {
return false, nil
}

return false, nil
return err == nil, err
}

func (h ConnectionPoolHandler) convert(i client.Object) (*v1alpha1.ConnectionPool, error) {
Expand Down
57 changes: 46 additions & 11 deletions docs/docs/api-reference/connectionpool.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,55 @@ title: "ConnectionPool"
name: aiven-token
key: token

connInfoSecretTarget:
name: connection-pool-secret
prefix: MY_SECRET_PREFIX_
annotations:
foo: bar
labels:
baz: egg

project: aiven-project-name
serviceName: my-service
databaseName: my-db
username: my-user
serviceName: my-pg
databaseName: my-database
username: my-service-user
poolMode: transaction
poolSize: 25

---

apiVersion: aiven.io/v1alpha1
kind: PostgreSQL
metadata:
name: my-pg
spec:
authSecretRef:
name: aiven-token
key: token

project: aiven-project-name
cloudName: google-europe-west1
plan: startup-4

---

apiVersion: aiven.io/v1alpha1
kind: Database
metadata:
name: my-database
spec:
authSecretRef:
name: aiven-token
key: token

project: aiven-project-name
serviceName: my-pg

---

apiVersion: aiven.io/v1alpha1
kind: ServiceUser
metadata:
name: my-service-user
spec:
authSecretRef:
name: aiven-token
key: token

project: aiven-project-name
serviceName: my-pg
```

## ConnectionPool {: #ConnectionPool }
Expand Down
57 changes: 46 additions & 11 deletions docs/docs/api-reference/examples/connectionpool.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,52 @@ spec:
name: aiven-token
key: token

connInfoSecretTarget:
name: connection-pool-secret
prefix: MY_SECRET_PREFIX_
annotations:
foo: bar
labels:
baz: egg

project: aiven-project-name
serviceName: my-service
databaseName: my-db
username: my-user
serviceName: my-pg
databaseName: my-database
username: my-service-user
poolMode: transaction
poolSize: 25

---

apiVersion: aiven.io/v1alpha1
kind: PostgreSQL
metadata:
name: my-pg
spec:
authSecretRef:
name: aiven-token
key: token

project: aiven-project-name
cloudName: google-europe-west1
plan: startup-4

---

apiVersion: aiven.io/v1alpha1
kind: Database
metadata:
name: my-database
spec:
authSecretRef:
name: aiven-token
key: token

project: aiven-project-name
serviceName: my-pg

---

apiVersion: aiven.io/v1alpha1
kind: ServiceUser
metadata:
name: my-service-user
spec:
authSecretRef:
name: aiven-token
key: token

project: aiven-project-name
serviceName: my-pg
80 changes: 12 additions & 68 deletions tests/connectionpool_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package tests

import (
"fmt"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -10,69 +9,6 @@ import (
"github.com/aiven/aiven-operator/api/v1alpha1"
)

func getConnectionPoolYaml(project, pgName, dbName, userName, poolName, cloudName string) string {
return fmt.Sprintf(`
apiVersion: aiven.io/v1alpha1
kind: PostgreSQL
metadata:
name: %[2]s
spec:
authSecretRef:
name: aiven-token
key: token
project: %[1]s
cloudName: %[6]s
plan: startup-4
---
apiVersion: aiven.io/v1alpha1
kind: Database
metadata:
name: %[3]s
spec:
authSecretRef:
name: aiven-token
key: token
project: %[1]s
serviceName: %[2]s
---
apiVersion: aiven.io/v1alpha1
kind: ServiceUser
metadata:
name: %[4]s
spec:
authSecretRef:
name: aiven-token
key: token
project: %[1]s
serviceName: %[2]s
---
apiVersion: aiven.io/v1alpha1
kind: ConnectionPool
metadata:
name: %[5]s
spec:
authSecretRef:
name: aiven-token
key: token
project: %[1]s
serviceName: %[2]s
databaseName: %[3]s
username: %[4]s
poolMode: transaction
poolSize: 25
`, project, pgName, dbName, userName, poolName, cloudName)
}

func TestConnectionPool(t *testing.T) {
t.Parallel()
defer recoverPanic(t)
Expand All @@ -81,11 +17,19 @@ func TestConnectionPool(t *testing.T) {
ctx, cancel := testCtx()
defer cancel()

pgName := randName("connection-pool")
dbName := randName("connection-pool")
userName := randName("connection-pool")
pgName := randName("pg")
dbName := randName("database")
userName := randName("service-user")
poolName := randName("connection-pool")
yml := getConnectionPoolYaml(cfg.Project, pgName, dbName, userName, poolName, cfg.PrimaryCloudName)
yml, err := loadExampleYaml("connectionpool.yaml", map[string]string{
"aiven-project-name": cfg.Project,
"google-europe-west1": cfg.PrimaryCloudName,
"my-connection-pool": poolName,
"my-pg": pgName,
"my-database": dbName,
"my-service-user": userName,
})
require.NoError(t, err)
s := NewSession(ctx, k8sClient, cfg.Project)

// Cleans test afterward
Expand Down

0 comments on commit 216e226

Please sign in to comment.