Skip to content

Commit

Permalink
break up database client file
Browse files Browse the repository at this point in the history
  • Loading branch information
frodopwns committed Apr 3, 2020
1 parent 8a5138e commit a8fd1b2
Show file tree
Hide file tree
Showing 2 changed files with 178 additions and 168 deletions.
168 changes: 0 additions & 168 deletions pkg/resourcemanager/mysql/database/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,10 @@ package database

import (
"context"
"fmt"

mysql "github.com/Azure/azure-sdk-for-go/services/mysql/mgmt/2017-12-01/mysql"
"github.com/Azure/azure-service-operator/api/v1alpha1"
azurev1alpha1 "github.com/Azure/azure-service-operator/api/v1alpha1"
"github.com/Azure/azure-service-operator/pkg/errhelp"
"github.com/Azure/azure-service-operator/pkg/helpers"
"github.com/Azure/azure-service-operator/pkg/resourcemanager"
"github.com/Azure/azure-service-operator/pkg/resourcemanager/config"
"github.com/Azure/azure-service-operator/pkg/resourcemanager/iam"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
)

type MySQLDatabaseClient struct {
Expand Down Expand Up @@ -59,166 +51,6 @@ func (m *MySQLDatabaseClient) CheckDatabaseNameAvailability(ctx context.Context,
return false, err

}
func (m *MySQLDatabaseClient) Ensure(ctx context.Context, obj runtime.Object, opts ...resourcemanager.ConfigOption) (bool, error) {

instance, err := m.convert(obj)
if err != nil {
return true, err
}

client := getMySQLDatabasesClient()

instance.Status.Provisioning = true
// Check if this database already exists. This is required
// to overcome the issue with the lack of idempotence of the Create call

_, err = m.GetDatabase(ctx, instance.Spec.ResourceGroup, instance.Spec.Server, instance.Name)
if err == nil {
instance.Status.Provisioned = true
instance.Status.Provisioning = false
instance.Status.Message = resourcemanager.SuccessMsg
return true, nil
}
future, err := m.CreateDatabaseIfValid(
ctx,
instance.Name,
instance.Spec.Server,
instance.Spec.ResourceGroup,
)

if err != nil {
// let the user know what happened
instance.Status.Message = err.Error()
instance.Status.Provisioning = false
// errors we expect might happen that we are ok with waiting for
catch := []string{
errhelp.ResourceGroupNotFoundErrorCode,
errhelp.ParentNotFoundErrorCode,
errhelp.NotFoundErrorCode,
errhelp.AsyncOpIncompleteError,
errhelp.ResourceNotFound,
}

azerr := errhelp.NewAzureErrorAzureError(err)
if helpers.ContainsString(catch, azerr.Type) {
// most of these error technically mean the resource is actually not provisioning
switch azerr.Type {
case errhelp.AsyncOpIncompleteError:
instance.Status.Provisioning = true
}
// reconciliation is not done but error is acceptable
return false, nil
}
// reconciliation not done and we don't know what happened
return false, err
}

_, err = future.Result(client)
if err != nil {
// let the user know what happened
instance.Status.Message = err.Error()
instance.Status.Provisioning = false
// errors we expect might happen that we are ok with waiting for
catch := []string{
errhelp.ResourceGroupNotFoundErrorCode,
errhelp.ParentNotFoundErrorCode,
errhelp.NotFoundErrorCode,
errhelp.AsyncOpIncompleteError,
errhelp.SubscriptionDoesNotHaveServer,
}

azerr := errhelp.NewAzureErrorAzureError(err)
if helpers.ContainsString(catch, azerr.Type) {
// most of these error technically mean the resource is actually not provisioning
switch azerr.Type {
case errhelp.AsyncOpIncompleteError:
instance.Status.Provisioning = true
case errhelp.SubscriptionDoesNotHaveServer:
instance.Status.Message = fmt.Sprintf("The PostgreSQL Server %s has not been provisioned yet. ", instance.Spec.Server)
}
// reconciliation is not done but error is acceptable
return false, nil
}
// reconciliation not done and we don't know what happened
return false, err
}

if instance.Status.Provisioning {
instance.Status.Provisioned = true
instance.Status.Provisioning = false
instance.Status.Message = resourcemanager.SuccessMsg
} else {
instance.Status.Provisioned = false
instance.Status.Provisioning = true
}

return true, nil
}

func (m *MySQLDatabaseClient) Delete(ctx context.Context, obj runtime.Object, opts ...resourcemanager.ConfigOption) (bool, error) {

instance, err := m.convert(obj)
if err != nil {
return true, err
}

status, err := m.DeleteDatabase(ctx, instance.Name, instance.Spec.Server, instance.Spec.ResourceGroup)
if err != nil {
if !errhelp.IsAsynchronousOperationNotComplete(err) {
return true, err
}
}

if err == nil {
if status != "InProgress" {
return false, nil
}
}

return true, nil
}

func (m *MySQLDatabaseClient) GetParents(obj runtime.Object) ([]resourcemanager.KubeParent, error) {

instance, err := m.convert(obj)
if err != nil {
return nil, err
}

return []resourcemanager.KubeParent{
{
Key: types.NamespacedName{
Namespace: instance.Namespace,
Name: instance.Spec.Server,
},
Target: &azurev1alpha1.PostgreSQLServer{},
},
{
Key: types.NamespacedName{
Namespace: instance.Namespace,
Name: instance.Spec.ResourceGroup,
},
Target: &azurev1alpha1.ResourceGroup{},
},
}, nil
}

func (m *MySQLDatabaseClient) GetStatus(obj runtime.Object) (*v1alpha1.ASOStatus, error) {

instance, err := m.convert(obj)
if err != nil {
return nil, err
}
return &instance.Status, nil
}

func (m *MySQLDatabaseClient) convert(obj runtime.Object) (*v1alpha1.MySQLDatabase, error) {
local, ok := obj.(*v1alpha1.MySQLDatabase)
if !ok {
return nil, fmt.Errorf("failed type assertion on kind: %s", obj.GetObjectKind().GroupVersionKind().String())
}
return local, nil
}

func (m *MySQLDatabaseClient) CreateDatabaseIfValid(ctx context.Context, databasename string, servername string, resourcegroup string) (future mysql.DatabasesCreateOrUpdateFuture, err error) {

Expand Down
178 changes: 178 additions & 0 deletions pkg/resourcemanager/mysql/database/reconcile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

package database

import (
"context"
"fmt"

"github.com/Azure/azure-service-operator/api/v1alpha1"
azurev1alpha1 "github.com/Azure/azure-service-operator/api/v1alpha1"
"github.com/Azure/azure-service-operator/pkg/errhelp"
"github.com/Azure/azure-service-operator/pkg/helpers"
"github.com/Azure/azure-service-operator/pkg/resourcemanager"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
)

func (m *MySQLDatabaseClient) Ensure(ctx context.Context, obj runtime.Object, opts ...resourcemanager.ConfigOption) (bool, error) {

instance, err := m.convert(obj)
if err != nil {
return true, err
}

client := getMySQLDatabasesClient()

instance.Status.Provisioning = true
// Check if this database already exists. This is required
// to overcome the issue with the lack of idempotence of the Create call

_, err = m.GetDatabase(ctx, instance.Spec.ResourceGroup, instance.Spec.Server, instance.Name)
if err == nil {
instance.Status.Provisioned = true
instance.Status.Provisioning = false
instance.Status.Message = resourcemanager.SuccessMsg
return true, nil
}
future, err := m.CreateDatabaseIfValid(
ctx,
instance.Name,
instance.Spec.Server,
instance.Spec.ResourceGroup,
)

if err != nil {
// let the user know what happened
instance.Status.Message = err.Error()
instance.Status.Provisioning = false
// errors we expect might happen that we are ok with waiting for
catch := []string{
errhelp.ResourceGroupNotFoundErrorCode,
errhelp.ParentNotFoundErrorCode,
errhelp.NotFoundErrorCode,
errhelp.AsyncOpIncompleteError,
errhelp.ResourceNotFound,
}

azerr := errhelp.NewAzureErrorAzureError(err)
if helpers.ContainsString(catch, azerr.Type) {
// most of these error technically mean the resource is actually not provisioning
switch azerr.Type {
case errhelp.AsyncOpIncompleteError:
instance.Status.Provisioning = true
}
// reconciliation is not done but error is acceptable
return false, nil
}
// reconciliation not done and we don't know what happened
return false, err
}

_, err = future.Result(client)
if err != nil {
// let the user know what happened
instance.Status.Message = err.Error()
instance.Status.Provisioning = false
// errors we expect might happen that we are ok with waiting for
catch := []string{
errhelp.ResourceGroupNotFoundErrorCode,
errhelp.ParentNotFoundErrorCode,
errhelp.NotFoundErrorCode,
errhelp.AsyncOpIncompleteError,
errhelp.SubscriptionDoesNotHaveServer,
}

azerr := errhelp.NewAzureErrorAzureError(err)
if helpers.ContainsString(catch, azerr.Type) {
// most of these error technically mean the resource is actually not provisioning
switch azerr.Type {
case errhelp.AsyncOpIncompleteError:
instance.Status.Provisioning = true
case errhelp.SubscriptionDoesNotHaveServer:
instance.Status.Message = fmt.Sprintf("The PostgreSQL Server %s has not been provisioned yet. ", instance.Spec.Server)
}
// reconciliation is not done but error is acceptable
return false, nil
}
// reconciliation not done and we don't know what happened
return false, err
}

if instance.Status.Provisioning {
instance.Status.Provisioned = true
instance.Status.Provisioning = false
instance.Status.Message = resourcemanager.SuccessMsg
} else {
instance.Status.Provisioned = false
instance.Status.Provisioning = true
}

return true, nil
}

func (m *MySQLDatabaseClient) Delete(ctx context.Context, obj runtime.Object, opts ...resourcemanager.ConfigOption) (bool, error) {

instance, err := m.convert(obj)
if err != nil {
return true, err
}

status, err := m.DeleteDatabase(ctx, instance.Name, instance.Spec.Server, instance.Spec.ResourceGroup)
if err != nil {
if !errhelp.IsAsynchronousOperationNotComplete(err) {
return true, err
}
}

if err == nil {
if status != "InProgress" {
return false, nil
}
}

return true, nil
}

func (m *MySQLDatabaseClient) GetParents(obj runtime.Object) ([]resourcemanager.KubeParent, error) {

instance, err := m.convert(obj)
if err != nil {
return nil, err
}

return []resourcemanager.KubeParent{
{
Key: types.NamespacedName{
Namespace: instance.Namespace,
Name: instance.Spec.Server,
},
Target: &azurev1alpha1.PostgreSQLServer{},
},
{
Key: types.NamespacedName{
Namespace: instance.Namespace,
Name: instance.Spec.ResourceGroup,
},
Target: &azurev1alpha1.ResourceGroup{},
},
}, nil
}

func (m *MySQLDatabaseClient) GetStatus(obj runtime.Object) (*v1alpha1.ASOStatus, error) {

instance, err := m.convert(obj)
if err != nil {
return nil, err
}
return &instance.Status, nil
}

func (m *MySQLDatabaseClient) convert(obj runtime.Object) (*v1alpha1.MySQLDatabase, error) {
local, ok := obj.(*v1alpha1.MySQLDatabase)
if !ok {
return nil, fmt.Errorf("failed type assertion on kind: %s", obj.GetObjectKind().GroupVersionKind().String())
}
return local, nil
}

0 comments on commit a8fd1b2

Please sign in to comment.