Skip to content

Commit

Permalink
chore: use v2 client with context support (#497)
Browse files Browse the repository at this point in the history
  • Loading branch information
byashimov authored Sep 14, 2023
1 parent eaa4892 commit 21a10e6
Show file tree
Hide file tree
Showing 49 changed files with 347 additions and 297 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Make `projectVpcId` and `projectVPCRef` mutable
- Fix panic on `nil` user config conversion
- Use aiven-go-client with context support

## v0.13.0 - 2023-08-18

Expand Down
22 changes: 11 additions & 11 deletions controllers/basic_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"strings"
"time"

"github.com/aiven/aiven-go-client"
"github.com/aiven/aiven-go-client/v2"
"github.com/go-logr/logr"
"github.com/hashicorp/go-multierror"
"github.com/pkg/errors"
Expand Down Expand Up @@ -45,20 +45,20 @@ type (
// of the Aiven services lifecycle.
Handlers interface {
// create or updates an instance on the Aiven side.
createOrUpdate(*aiven.Client, client.Object, []client.Object) error
createOrUpdate(ctx context.Context, avn *aiven.Client, obj client.Object, refs []client.Object) error

// delete removes an instance on Aiven side.
// If an object is already deleted and cannot be found, it should not be an error. For other deletion
// errors, return an error.
delete(*aiven.Client, client.Object) (bool, error)
delete(ctx context.Context, avn *aiven.Client, obj client.Object) (bool, error)

// get retrieve an object and a secret (for example, connection credentials) that is generated on the
// fly based on data from Aiven API. When not applicable to service, it should return nil.
get(*aiven.Client, client.Object) (*corev1.Secret, error)
get(ctx context.Context, avn *aiven.Client, obj client.Object) (*corev1.Secret, error)

// checkPreconditions check whether all preconditions for creating (or updating) the resource are in place.
// For example, it is applicable when a service needs to be running before this resource can be created.
checkPreconditions(*aiven.Client, client.Object) (bool, error)
checkPreconditions(ctx context.Context, avn *aiven.Client, obj client.Object) (bool, error)
}

aivenManagedObject interface {
Expand Down Expand Up @@ -212,7 +212,7 @@ func (i instanceReconcilerHelper) reconcileInstance(ctx context.Context, o clien

if !isAlreadyProcessed(o) {
i.rec.Event(o, corev1.EventTypeNormal, eventCreateOrUpdatedAtAiven, "about to create instance at aiven")
if err := i.createOrUpdateInstance(o, refs); err != nil {
if err := i.createOrUpdateInstance(ctx, o, refs); err != nil {
i.rec.Event(o, corev1.EventTypeWarning, eventUnableToCreateOrUpdateAtAiven, err.Error())
return ctrl.Result{}, fmt.Errorf("unable to create or update instance at aiven: %w", err)
}
Expand Down Expand Up @@ -262,7 +262,7 @@ func (i instanceReconcilerHelper) checkPreconditions(ctx context.Context, o clie
i.log.Info("all references are good")
}

check, err := i.h.checkPreconditions(i.avn, o)
check, err := i.h.checkPreconditions(ctx, i.avn, o)
if err != nil {
i.rec.Event(o, corev1.EventTypeWarning, eventUnableToWaitForPreconditions, err.Error())
return false, fmt.Errorf("unable to wait for preconditions: %w", err)
Expand Down Expand Up @@ -317,7 +317,7 @@ func (i instanceReconcilerHelper) getObjectRefs(ctx context.Context, o client.Ob
func (i instanceReconcilerHelper) finalize(ctx context.Context, o client.Object) (ctrl.Result, error) {
i.rec.Event(o, corev1.EventTypeNormal, eventTryingToDeleteAtAiven, "trying to delete instance at aiven")

finalised, err := i.h.delete(i.avn, o)
finalised, err := i.h.delete(ctx, i.avn, o)

// There are dependencies on Aiven side, resets error, so it goes for requeue
// Handlers does not have logger, it goes here
Expand Down Expand Up @@ -376,13 +376,13 @@ func (i instanceReconcilerHelper) isInvalidTokenError(err error) bool {
return strings.Contains(msg, "Invalid token") || strings.Contains(msg, "Missing (expired) db token")
}

func (i instanceReconcilerHelper) createOrUpdateInstance(o client.Object, refs []client.Object) error {
func (i instanceReconcilerHelper) createOrUpdateInstance(ctx context.Context, o client.Object, refs []client.Object) error {
i.log.Info("generation wasn't processed, creation or updating instance on aiven side")
a := o.GetAnnotations()
delete(a, processedGenerationAnnotation)
delete(a, instanceIsRunningAnnotation)

if err := i.h.createOrUpdate(i.avn, o, refs); err != nil {
if err := i.h.createOrUpdate(ctx, i.avn, o, refs); err != nil {
return fmt.Errorf("unable to create or update aiven instance: %w", err)
}

Expand Down Expand Up @@ -415,7 +415,7 @@ func (i instanceReconcilerHelper) updateInstanceStateAndSecretUntilRunning(ctx c
err = err.(*multierror.Error).ErrorOrNil()
}()

serviceSecret, err := i.h.get(i.avn, o)
serviceSecret, err := i.h.get(ctx, i.avn, o)
if err != nil {
return false, err
} else if serviceSecret != nil {
Expand Down
4 changes: 2 additions & 2 deletions controllers/cassandra_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"fmt"
"strings"

"github.com/aiven/aiven-go-client"
"github.com/aiven/aiven-go-client/v2"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
ctrl "sigs.k8s.io/controller-runtime"
Expand Down Expand Up @@ -66,7 +66,7 @@ func (a *cassandraAdapter) getUserConfig() any {
return &a.Spec.UserConfig
}

func (a *cassandraAdapter) newSecret(s *aiven.Service) (*corev1.Secret, error) {
func (a *cassandraAdapter) newSecret(ctx context.Context, s *aiven.Service) (*corev1.Secret, error) {
stringData := map[string]string{
"HOST": s.URIParams["host"],
"PORT": s.URIParams["port"],
Expand Down
4 changes: 2 additions & 2 deletions controllers/clickhouse_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"context"
"fmt"

"github.com/aiven/aiven-go-client"
"github.com/aiven/aiven-go-client/v2"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
ctrl "sigs.k8s.io/controller-runtime"
Expand Down Expand Up @@ -65,7 +65,7 @@ func (a *clickhouseAdapter) getUserConfig() any {
return &a.Spec.UserConfig
}

func (a *clickhouseAdapter) newSecret(s *aiven.Service) (*corev1.Secret, error) {
func (a *clickhouseAdapter) newSecret(ctx context.Context, s *aiven.Service) (*corev1.Secret, error) {
prefix := getSecretPrefix(a)
stringData := map[string]string{
prefix + "HOST": s.URIParams["host"],
Expand Down
20 changes: 10 additions & 10 deletions controllers/clickhouseuser_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"fmt"
"strconv"

"github.com/aiven/aiven-go-client"
"github.com/aiven/aiven-go-client/v2"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -42,13 +42,13 @@ func (r *ClickhouseUserReconciler) SetupWithManager(mgr ctrl.Manager) error {

type clickhouseUserHandler struct{}

func (h *clickhouseUserHandler) createOrUpdate(avn *aiven.Client, obj client.Object, _ []client.Object) error {
func (h *clickhouseUserHandler) createOrUpdate(ctx context.Context, avn *aiven.Client, obj client.Object, refs []client.Object) error {
user, err := h.convert(obj)
if err != nil {
return err
}

r, err := avn.ClickhouseUser.Create(user.Spec.Project, user.Spec.ServiceName, user.Name)
r, err := avn.ClickhouseUser.Create(ctx, user.Spec.Project, user.Spec.ServiceName, user.Name)
if err != nil {
return err
}
Expand All @@ -73,7 +73,7 @@ func (h *clickhouseUserHandler) createOrUpdate(avn *aiven.Client, obj client.Obj
return nil
}

func (h *clickhouseUserHandler) delete(avn *aiven.Client, obj client.Object) (bool, error) {
func (h *clickhouseUserHandler) delete(ctx context.Context, avn *aiven.Client, obj client.Object) (bool, error) {
user, err := h.convert(obj)
if err != nil {
return false, err
Expand All @@ -84,21 +84,21 @@ func (h *clickhouseUserHandler) delete(avn *aiven.Client, obj client.Object) (bo
return true, nil
}

err = avn.ClickhouseUser.Delete(user.Spec.Project, user.Spec.ServiceName, user.Status.UUID)
err = avn.ClickhouseUser.Delete(ctx, user.Spec.Project, user.Spec.ServiceName, user.Status.UUID)
if !aiven.IsNotFound(err) {
return false, err
}

return true, nil
}

func (h *clickhouseUserHandler) get(avn *aiven.Client, obj client.Object) (*corev1.Secret, error) {
func (h *clickhouseUserHandler) get(ctx context.Context, avn *aiven.Client, obj client.Object) (*corev1.Secret, error) {
user, err := h.convert(obj)
if err != nil {
return nil, err
}

s, err := avn.Services.Get(user.Spec.Project, user.Spec.ServiceName)
s, err := avn.Services.Get(ctx, user.Spec.Project, user.Spec.ServiceName)
if err != nil {
return nil, err
}
Expand All @@ -108,7 +108,7 @@ func (h *clickhouseUserHandler) get(avn *aiven.Client, obj client.Object) (*core
// And all other GET methods return empty password, even this one.
// So the only way to have a secret here is to reset it manually
password := randPassword(maxUserPasswordLength)
_, err = avn.ClickhouseUser.ResetPassword(user.Spec.Project, user.Spec.ServiceName, user.Status.UUID, password)
_, err = avn.ClickhouseUser.ResetPassword(ctx, user.Spec.Project, user.Spec.ServiceName, user.Status.UUID, password)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -136,7 +136,7 @@ func (h *clickhouseUserHandler) get(avn *aiven.Client, obj client.Object) (*core
return secret, nil
}

func (h *clickhouseUserHandler) checkPreconditions(avn *aiven.Client, obj client.Object) (bool, error) {
func (h *clickhouseUserHandler) checkPreconditions(ctx context.Context, avn *aiven.Client, obj client.Object) (bool, error) {
user, err := h.convert(obj)
if err != nil {
return false, err
Expand All @@ -145,7 +145,7 @@ func (h *clickhouseUserHandler) checkPreconditions(avn *aiven.Client, obj client
meta.SetStatusCondition(&user.Status.Conditions,
getInitializedCondition("Preconditions", "Checking preconditions"))

return checkServiceIsRunning(avn, user.Spec.Project, user.Spec.ServiceName)
return checkServiceIsRunning(ctx, avn, user.Spec.Project, user.Spec.ServiceName)
}

func (h *clickhouseUserHandler) convert(i client.Object) (*v1alpha1.ClickhouseUser, error) {
Expand Down
6 changes: 3 additions & 3 deletions controllers/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"strconv"
"strings"

"github.com/aiven/aiven-go-client"
"github.com/aiven/aiven-go-client/v2"
"github.com/liip/sheriff"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -35,8 +35,8 @@ var (
errTerminationProtectionOn = errors.New("termination protection is on")
)

func checkServiceIsRunning(c *aiven.Client, project, serviceName string) (bool, error) {
s, err := c.Services.Get(project, serviceName)
func checkServiceIsRunning(ctx context.Context, c *aiven.Client, project, serviceName string) (bool, error) {
s, err := c.Services.Get(ctx, project, serviceName)
if err != nil {
// if service is not found, it is not running
if aiven.IsNotFound(err) {
Expand Down
41 changes: 20 additions & 21 deletions controllers/connectionpool_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"fmt"
"strconv"

"github.com/aiven/aiven-go-client"
"github.com/aiven/aiven-go-client/v2"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -40,19 +40,19 @@ func (r *ConnectionPoolReconciler) SetupWithManager(mgr ctrl.Manager) error {
Complete(r)
}

func (h ConnectionPoolHandler) createOrUpdate(avn *aiven.Client, i client.Object, refs []client.Object) error {
cp, err := h.convert(i)
func (h ConnectionPoolHandler) createOrUpdate(ctx context.Context, avn *aiven.Client, obj client.Object, _ []client.Object) error {
cp, err := h.convert(obj)
if err != nil {
return err
}

exists, err := h.exists(avn, cp)
exists, err := h.exists(ctx, avn, cp)
if err != nil {
return err
}
var reason string
if !exists {
_, err := avn.ConnectionPools.Create(cp.Spec.Project, cp.Spec.ServiceName,
_, err := avn.ConnectionPools.Create(ctx, cp.Spec.Project, cp.Spec.ServiceName,
aiven.CreateConnectionPoolRequest{
Database: cp.Spec.DatabaseName,
PoolMode: cp.Spec.PoolMode,
Expand All @@ -65,7 +65,7 @@ func (h ConnectionPoolHandler) createOrUpdate(avn *aiven.Client, i client.Object
}
reason = "Created"
} else {
_, err := avn.ConnectionPools.Update(cp.Spec.Project, cp.Spec.ServiceName, cp.Name,
_, err := avn.ConnectionPools.Update(ctx, cp.Spec.Project, cp.Spec.ServiceName, cp.Name,
aiven.UpdateConnectionPoolRequest{
Database: cp.Spec.DatabaseName,
PoolMode: cp.Spec.PoolMode,
Expand All @@ -92,23 +92,22 @@ func (h ConnectionPoolHandler) createOrUpdate(avn *aiven.Client, i client.Object
return nil
}

func (h ConnectionPoolHandler) delete(avn *aiven.Client, i client.Object) (bool, error) {
cp, err := h.convert(i)
func (h ConnectionPoolHandler) delete(ctx context.Context, avn *aiven.Client, obj client.Object) (bool, error) {
cp, err := h.convert(obj)
if err != nil {
return false, err
}

err = avn.ConnectionPools.Delete(
cp.Spec.Project, cp.Spec.ServiceName, cp.Name)
err = avn.ConnectionPools.Delete(ctx, cp.Spec.Project, cp.Spec.ServiceName, cp.Name)
if err != nil && !aiven.IsNotFound(err) {
return false, err
}

return true, nil
}

func (h ConnectionPoolHandler) exists(avn *aiven.Client, cp *v1alpha1.ConnectionPool) (bool, error) {
conPool, err := avn.ConnectionPools.Get(cp.Spec.Project, cp.Spec.ServiceName, cp.Name)
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 aiven.IsNotFound(err) {
return false, nil
Expand All @@ -119,18 +118,18 @@ func (h ConnectionPoolHandler) exists(avn *aiven.Client, cp *v1alpha1.Connection
return conPool != nil, nil
}

func (h ConnectionPoolHandler) get(avn *aiven.Client, i client.Object) (*corev1.Secret, error) {
connPool, err := h.convert(i)
func (h ConnectionPoolHandler) get(ctx context.Context, avn *aiven.Client, obj client.Object) (*corev1.Secret, error) {
connPool, err := h.convert(obj)
if err != nil {
return nil, err
}

cp, err := avn.ConnectionPools.Get(connPool.Spec.Project, connPool.Spec.ServiceName, connPool.Name)
cp, err := avn.ConnectionPools.Get(ctx, connPool.Spec.Project, connPool.Spec.ServiceName, connPool.Name)
if err != nil {
return nil, fmt.Errorf("cannot get ConnectionPool: %w", err)
}

s, err := avn.Services.Get(connPool.Spec.Project, connPool.Spec.ServiceName)
s, err := avn.Services.Get(ctx, connPool.Spec.Project, connPool.Spec.ServiceName)
if err != nil {
return nil, fmt.Errorf("cannot get service: %w", err)
}
Expand Down Expand Up @@ -164,7 +163,7 @@ func (h ConnectionPoolHandler) get(avn *aiven.Client, i client.Object) (*corev1.
return newSecret(connPool, stringData, false), nil
}

u, err := avn.ServiceUsers.Get(connPool.Spec.Project, connPool.Spec.ServiceName, connPool.Spec.Username)
u, err := avn.ServiceUsers.Get(ctx, connPool.Spec.Project, connPool.Spec.ServiceName, connPool.Spec.Username)
if err != nil {
return nil, fmt.Errorf("cannot get user: %w", err)
}
Expand All @@ -190,22 +189,22 @@ func (h ConnectionPoolHandler) get(avn *aiven.Client, i client.Object) (*corev1.
return newSecret(connPool, stringData, false), nil
}

func (h ConnectionPoolHandler) checkPreconditions(avn *aiven.Client, i client.Object) (bool, error) {
cp, err := h.convert(i)
func (h ConnectionPoolHandler) checkPreconditions(ctx context.Context, avn *aiven.Client, obj client.Object) (bool, error) {
cp, err := h.convert(obj)
if err != nil {
return false, err
}

meta.SetStatusCondition(&cp.Status.Conditions,
getInitializedCondition("Preconditions", "Checking preconditions"))

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

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

0 comments on commit 21a10e6

Please sign in to comment.