diff --git a/controllers/azuresqlaction_controller.go b/controllers/azuresqlaction_controller.go index 6e9be034faa..9eea20db2b3 100644 --- a/controllers/azuresqlaction_controller.go +++ b/controllers/azuresqlaction_controller.go @@ -126,10 +126,6 @@ func (r *AzureSqlActionReconciler) reconcileExternal(ctx context.Context, instan instance.Status.Provisioning = true instance.Status.Provisioned = false instance.Status.Message = "AzureSqlAction in progress" - // write information back to instance - if updateerr := r.Status().Update(ctx, instance); updateerr != nil { - r.Recorder.Event(instance, corev1.EventTypeWarning, "Failed", "Unable to update instance") - } //get owner instance of AzureSqlServer r.Recorder.Event(instance, corev1.EventTypeNormal, "UpdatingOwner", "Updating owner AzureSqlServer instance") @@ -182,7 +178,7 @@ func (r *AzureSqlActionReconciler) reconcileExternal(ctx context.Context, instan newPassword, _ := generateRandomPassword(passwordLength) azureSqlServerProperties.AdministratorLoginPassword = to.StringPtr(newPassword) - if _, err := r.AzureSqlServerManager.CreateOrUpdateSQLServer(ctx, groupName, *server.Location, serverName, azureSqlServerProperties); err != nil { + if _, err := r.AzureSqlServerManager.CreateOrUpdateSQLServer(ctx, groupName, *server.Location, serverName, azureSqlServerProperties, true); err != nil { if !strings.Contains(err.Error(), "not complete") { r.Recorder.Event(instance, corev1.EventTypeWarning, "Failed", "Unable to provision or update instance") return err diff --git a/controllers/azuresqlfailovergroup_controller.go b/controllers/azuresqlfailovergroup_controller.go index d91fb08261e..42a881f752e 100644 --- a/controllers/azuresqlfailovergroup_controller.go +++ b/controllers/azuresqlfailovergroup_controller.go @@ -115,6 +115,8 @@ func (r *AzureSqlFailoverGroupReconciler) Reconcile(req ctrl.Request) (ctrl.Resu errhelp.NotFoundErrorCode, errhelp.AsyncOpIncompleteError, errhelp.InvalidServerName, + errhelp.ResourceNotFound, + errhelp.FailoverGroupBusy, } if azerr, ok := err.(*errhelp.AzureError); ok { if helpers.ContainsString(catch, azerr.Type) { diff --git a/controllers/azuresqlserver_controller.go b/controllers/azuresqlserver_controller.go index cd84c5db0a7..556c1c393d2 100644 --- a/controllers/azuresqlserver_controller.go +++ b/controllers/azuresqlserver_controller.go @@ -217,7 +217,7 @@ func (r *AzureSqlServerReconciler) reconcileExternal(instance *azurev1alpha1.Azu } // write information back to instance - if err := r.Status().Update(ctx, instance); err != nil { + if err := r.Update(ctx, instance); err != nil { r.Recorder.Event(instance, corev1.EventTypeWarning, "Failed", "Unable to update instance") } @@ -230,7 +230,7 @@ func (r *AzureSqlServerReconciler) reconcileExternal(instance *azurev1alpha1.Azu // create the sql server instance.Status.Provisioning = true - if _, err := r.AzureSqlServerManager.CreateOrUpdateSQLServer(ctx, groupName, location, name, azureSqlServerProperties); err != nil { + if _, err := r.AzureSqlServerManager.CreateOrUpdateSQLServer(ctx, groupName, location, name, azureSqlServerProperties, false); err != nil { if !strings.Contains(err.Error(), "not complete") { msg := fmt.Sprintf("CreateOrUpdateSQLServer not complete: %v", err) instance.Status.Message = msg diff --git a/controllers/azuresqluser_controller.go b/controllers/azuresqluser_controller.go index e6ba7199b30..5105fa3dd7f 100644 --- a/controllers/azuresqluser_controller.go +++ b/controllers/azuresqluser_controller.go @@ -228,7 +228,7 @@ func (r *AzureSQLUserReconciler) reconcileExternal(instance azurev1alpha1.AzureS if len(roles) == 0 { log.Info("No roles specified for user") } else { - r.AzureSqlUserManager.GrantUserRoles(ctx, user, roles, db) + r.AzureSqlUserManager.GrantUserRoles(ctx, string(DBSecret[SecretUsernameKey]), roles, db) } // publish user secret diff --git a/pkg/errhelp/errors.go b/pkg/errhelp/errors.go index a5dfe854257..62decf30032 100644 --- a/pkg/errhelp/errors.go +++ b/pkg/errhelp/errors.go @@ -22,6 +22,7 @@ const ( BadRequest = "BadRequest" AccountNameInvalid = "AccountNameInvalid" RequestConflictError = "Conflict" + FailoverGroupBusy = "FailoverGroupBusy" ) func NewAzureError(err error) error { diff --git a/pkg/resourcemanager/azuresql/azuresqlserver/azuresqlserver.go b/pkg/resourcemanager/azuresql/azuresqlserver/azuresqlserver.go index af4067598ae..69f9398fe53 100644 --- a/pkg/resourcemanager/azuresql/azuresqlserver/azuresqlserver.go +++ b/pkg/resourcemanager/azuresql/azuresqlserver/azuresqlserver.go @@ -66,15 +66,17 @@ func (_ *AzureSqlServerManager) GetServer(ctx context.Context, resourceGroupName } // CreateOrUpdateSQLServer creates a SQL server in Azure -func (_ *AzureSqlServerManager) CreateOrUpdateSQLServer(ctx context.Context, resourceGroupName string, location string, serverName string, properties azuresqlshared.SQLServerProperties) (result sql.Server, err error) { +func (_ *AzureSqlServerManager) CreateOrUpdateSQLServer(ctx context.Context, resourceGroupName string, location string, serverName string, properties azuresqlshared.SQLServerProperties, forceUpdate bool) (result sql.Server, err error) { serversClient := azuresqlshared.GetGoServersClient() serverProp := azuresqlshared.SQLServerPropertiesToServer(properties) - checkNameResult, err := CheckNameAvailability(ctx, resourceGroupName, serverName) - if checkNameResult.Reason == sql.AlreadyExists { - return result, errors.New("AlreadyExists") - } else if checkNameResult.Reason == sql.Invalid { - return result, errors.New("InvalidServerName") + if forceUpdate == false { + checkNameResult, _ := CheckNameAvailability(ctx, resourceGroupName, serverName) + if checkNameResult.Reason == sql.AlreadyExists { + return result, errors.New("AlreadyExists") + } else if checkNameResult.Reason == sql.Invalid { + return result, errors.New("InvalidServerName") + } } // issue the creation diff --git a/pkg/resourcemanager/azuresql/azuresqlserver/azuresqlserver_manager.go b/pkg/resourcemanager/azuresql/azuresqlserver/azuresqlserver_manager.go index 53deea82f18..7f36ccc3f82 100644 --- a/pkg/resourcemanager/azuresql/azuresqlserver/azuresqlserver_manager.go +++ b/pkg/resourcemanager/azuresql/azuresqlserver/azuresqlserver_manager.go @@ -15,7 +15,7 @@ import ( ) type SqlServerManager interface { - CreateOrUpdateSQLServer(ctx context.Context, resourceGroupName string, location string, serverName string, properties azuresqlshared.SQLServerProperties) (result sql.Server, err error) + CreateOrUpdateSQLServer(ctx context.Context, resourceGroupName string, location string, serverName string, properties azuresqlshared.SQLServerProperties, forceUpdate bool) (result sql.Server, err error) DeleteSQLServer(ctx context.Context, resourceGroupName string, serverName string) (result autorest.Response, err error) GetServer(ctx context.Context, resourceGroupName string, serverName string) (result sql.Server, err error) } diff --git a/pkg/resourcemanager/azuresql/azuresqlshared/resourceclient.go b/pkg/resourcemanager/azuresql/azuresqlshared/resourceclient.go index 87f42b5e875..67eeb1cb44a 100644 --- a/pkg/resourcemanager/azuresql/azuresqlshared/resourceclient.go +++ b/pkg/resourcemanager/azuresql/azuresqlshared/resourceclient.go @@ -14,7 +14,7 @@ import ( // ResourceClient contains the helper functions for interacting with SQL servers / databases type ResourceClient interface { - CreateOrUpdateSQLServer(ctx context.Context, resourceGroupName string, location string, serverName string, properties SQLServerProperties) (result sql.Server, err error) + CreateOrUpdateSQLServer(ctx context.Context, resourceGroupName string, location string, serverName string, properties SQLServerProperties, forceUpdate bool) (result sql.Server, err error) DeleteSQLServer(ctx context.Context, resourceGroupName string, serverName string) (result autorest.Response, err error) GetServer(ctx context.Context, resourceGroupName string, serverName string) (result sql.Server, err error) DeleteSQLFirewallRule(ctx context.Context, resourceGroupName string, serverName string, ruleName string) (err error) diff --git a/pkg/resourcemanager/azuresql/azuresqluser/azuresqluser.go b/pkg/resourcemanager/azuresql/azuresqluser/azuresqluser.go index ef6b3b95ba9..9bdc71818e7 100644 --- a/pkg/resourcemanager/azuresql/azuresqluser/azuresqluser.go +++ b/pkg/resourcemanager/azuresql/azuresqluser/azuresqluser.go @@ -36,7 +36,6 @@ func (m *AzureSqlUserManager) ConnectToSqlDb(ctx context.Context, drivername str fullServerAddress := fmt.Sprintf("%s.database.windows.net", server) connString := fmt.Sprintf("server=%s;user id=%s;password=%s;port=%d;database=%s;Persist Security Info=False;Pooling=False;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30", fullServerAddress, user, password, port, database) - m.Log.Info("ConnectToSqlDb:", "conn string:", connString) db, err := sql.Open(drivername, connString) if err != nil { m.Log.Info("ConnectToSqlDb", "error from sql.Open is:", err.Error()) diff --git a/pkg/resourcemanager/azuresql/endtoend_test.go b/pkg/resourcemanager/azuresql/endtoend_test.go index 05a597a9c75..edbf376cea4 100644 --- a/pkg/resourcemanager/azuresql/endtoend_test.go +++ b/pkg/resourcemanager/azuresql/endtoend_test.go @@ -65,7 +65,7 @@ func TestCreateOrUpdateSQLServer(t *testing.T) { } // wait for server to be created, then only proceed once activated - server, err := tc.sqlServerManager.CreateOrUpdateSQLServer(ctx, groupName, location, serverName, sqlServerProperties) + server, err := tc.sqlServerManager.CreateOrUpdateSQLServer(ctx, groupName, location, serverName, sqlServerProperties, false) azerr := errhelp.NewAzureErrorAzureError(err) if err != nil && !helpers.ContainsString(ignorableErrors, azerr.Type) { util.PrintAndLog(fmt.Sprintf("cannot create sql server: %v", err)) @@ -163,7 +163,7 @@ func TestCreateOrUpdateSQLServer(t *testing.T) { } // wait for server to be created, then only proceed once activated - server, err = tc.sqlServerManager.CreateOrUpdateSQLServer(ctx, groupName, secLocation, secSrvName, sqlServerProperties) + server, err = tc.sqlServerManager.CreateOrUpdateSQLServer(ctx, groupName, secLocation, secSrvName, sqlServerProperties, false) azerr = errhelp.NewAzureErrorAzureError(err) if err != nil && !helpers.ContainsString(ignorableErrors, azerr.Type) { diff --git a/pkg/resourcemanager/mock/azuresql/azuresqlserver.go b/pkg/resourcemanager/mock/azuresql/azuresqlserver.go index 3951ae0a5a0..b4ab365e633 100644 --- a/pkg/resourcemanager/mock/azuresql/azuresqlserver.go +++ b/pkg/resourcemanager/mock/azuresql/azuresqlserver.go @@ -42,7 +42,7 @@ func findSqlServer(res []MockSqlServerResource, predicate func(MockSqlServerReso } // CreateOrUpdateSqlServer creates a new sql server -func (manager *MockSqlServerManager) CreateOrUpdateSQLServer(ctx context.Context, resourceGroupName string, location string, serverName string, properties azuresqlshared.SQLServerProperties) (result sql.Server, err error) { +func (manager *MockSqlServerManager) CreateOrUpdateSQLServer(ctx context.Context, resourceGroupName string, location string, serverName string, properties azuresqlshared.SQLServerProperties, forceUpdate bool) (result sql.Server, err error) { index, _ := findSqlServer(manager.sqlServers, func(s MockSqlServerResource) bool { return s.resourceGroupName == resourceGroupName && *s.sqlServer.Name == serverName }) diff --git a/pkg/resourcemanager/mock/sqlclient/sqlclient_gosdk.go b/pkg/resourcemanager/mock/sqlclient/sqlclient_gosdk.go index 8648a3b365a..072310c326f 100644 --- a/pkg/resourcemanager/mock/sqlclient/sqlclient_gosdk.go +++ b/pkg/resourcemanager/mock/sqlclient/sqlclient_gosdk.go @@ -37,7 +37,7 @@ type MockGoSDKClient struct { } // CreateOrUpdateSQLServer creates a new sql server -func (sdk *MockGoSDKClient) CreateOrUpdateSQLServer(ctx context.Context, resourceGroupName string, location string, serverName string, properties azuresqlshared.SQLServerProperties) (result sql.Server, err error) { +func (sdk *MockGoSDKClient) CreateOrUpdateSQLServer(ctx context.Context, resourceGroupName string, location string, serverName string, properties azuresqlshared.SQLServerProperties, forceUpdate bool) (result sql.Server, err error) { var sqlServer = sql.Server{ Response: helpers.GetRestResponse(http.StatusCreated), }