From 60b177e28e26dfbdf2e9208b8238d06c24d0dabc Mon Sep 17 00:00:00 2001 From: Erin Corson Date: Thu, 22 Aug 2019 14:36:07 -0600 Subject: [PATCH] wip - working on sqlserver (#122) * working on sqlserver * Update config/samples/azure_v1_sqlserver.yaml --- api/v1/sqlserver_types.go | 2 +- .../bases/azure.microsoft.com_sqlservers.yaml | 3 +- config/samples/azure_v1_sqlserver.yaml | 4 +- controllers/sqlserver_controller.go | 95 ++++++++++++------- controllers/sqlserver_controller_finalizer.go | 37 ++++++++ main.go | 5 +- .../sqlclient/sqlclient_godsk.go | 14 +-- 7 files changed, 113 insertions(+), 47 deletions(-) create mode 100644 controllers/sqlserver_controller_finalizer.go diff --git a/api/v1/sqlserver_types.go b/api/v1/sqlserver_types.go index 88e8fba0c38..5085c9f6230 100644 --- a/api/v1/sqlserver_types.go +++ b/api/v1/sqlserver_types.go @@ -28,7 +28,7 @@ type SqlServerSpec struct { // Important: Run "make" to regenerate code after modifying this file Location string `json:"location"` ResourceGroup string `json:"resourcegroup,omitempty"` - AdminUser string `json:"adminuser"` + AdminUser string `json:"adminuser,omitempty"` } // SqlServerStatus defines the observed state of SqlServer diff --git a/config/crd/bases/azure.microsoft.com_sqlservers.yaml b/config/crd/bases/azure.microsoft.com_sqlservers.yaml index 9d62b7634c0..4f050c9c3fc 100644 --- a/config/crd/bases/azure.microsoft.com_sqlservers.yaml +++ b/config/crd/bases/azure.microsoft.com_sqlservers.yaml @@ -401,7 +401,7 @@ spec: spec: description: SqlServerSpec defines the desired state of SqlServer properties: - admin: + adminuser: type: string location: description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster @@ -410,7 +410,6 @@ spec: resourcegroup: type: string required: - - admin - location type: object status: diff --git a/config/samples/azure_v1_sqlserver.yaml b/config/samples/azure_v1_sqlserver.yaml index 0626eba1f4a..c05db4567ae 100644 --- a/config/samples/azure_v1_sqlserver.yaml +++ b/config/samples/azure_v1_sqlserver.yaml @@ -3,5 +3,5 @@ kind: SqlServer metadata: name: sqlserver-sample spec: - # Add fields here - foo: bar + location: "westus" + resourcegroup: "resourcegroup-sample-1907" diff --git a/controllers/sqlserver_controller.go b/controllers/sqlserver_controller.go index 44b8d49eb29..22d3ab83fd5 100644 --- a/controllers/sqlserver_controller.go +++ b/controllers/sqlserver_controller.go @@ -18,8 +18,13 @@ package controllers import ( "context" "fmt" + "strings" + "time" + "github.com/Azure/azure-service-operator/pkg/errhelp" helpers "github.com/Azure/azure-service-operator/pkg/helpers" + sql "github.com/Azure/azure-service-operator/pkg/resourcemanager/sqlclient" + "github.com/Azure/go-autorest/autorest/to" "github.com/go-logr/logr" "k8s.io/client-go/tools/record" ctrl "sigs.k8s.io/controller-runtime" @@ -28,8 +33,6 @@ import ( azurev1 "github.com/Azure/azure-service-operator/api/v1" ) -const SQLServerFinalizerName = "sqlserver.finalizers.azure.com" - // SqlServerReconciler reconciles a SqlServer object type SqlServerReconciler struct { client.Client @@ -58,7 +61,7 @@ func (r *SqlServerReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) { if helpers.IsBeingDeleted(&instance) { if helpers.HasFinalizer(&instance, SQLServerFinalizerName) { if err := r.deleteExternal(&instance); err != nil { - log.Info("Delete SQL Server failed with ", err.Error()) + log.Info("Delete SqlServer failed with ", err.Error()) return ctrl.Result{}, err } @@ -72,13 +75,18 @@ func (r *SqlServerReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) { if !helpers.HasFinalizer(&instance, SQLServerFinalizerName) { if err := r.addFinalizer(&instance); err != nil { - log.Info("Adding sql-server finalizer failed with ", err.Error()) + log.Info("Adding SqlServer finalizer failed with ", err.Error()) return ctrl.Result{}, err } } if !instance.IsSubmitted() { + r.Recorder.Event(&instance, "Normal", "Submitting", "starting resource reconciliation") if err := r.reconcileExternal(&instance); err != nil { + if strings.Contains(err.Error(), "asynchronous operation has not completed") { + r.Recorder.Event(&instance, "Normal", "Provisioning", "async op still running") + return ctrl.Result{Requeue: true, RequeueAfter: 10 * time.Second}, nil + } return ctrl.Result{}, fmt.Errorf("error reconciling sql server in azure: %v", err) } return ctrl.Result{}, nil @@ -96,49 +104,70 @@ func (r *SqlServerReconciler) SetupWithManager(mgr ctrl.Manager) error { } func (r *SqlServerReconciler) reconcileExternal(instance *azurev1.SqlServer) error { - // ctx := context.Background() - // location := instance.Spec.Location - // name := instance.ObjectMeta.Name - // groupName := instance.Spec.ResourceGroupName + ctx := context.Background() + location := instance.Spec.Location + name := instance.ObjectMeta.Name + groupName := instance.Spec.ResourceGroup + + sdkClient := sql.GoSDKClient{ + Ctx: ctx, + ResourceGroupName: groupName, + ServerName: name, + Location: location, + } - // // write information back to instance - // instance.Status.Provisioning = true + sqlServerProperties := sql.SQLServerProperties{ + AdministratorLogin: to.StringPtr("iamadmin"), + AdministratorLoginPassword: to.StringPtr("generate_me_1234"), + AllowAzureServicesAccess: true, + } - // if err := r.Status().Update(ctx, instance); err != nil { - // r.Recorder.Event(instance, "Warning", "Failed", "Unable to update instance") - // } + r.Log.Info("calling createorupdattte") + instance.Status.Provisioning = true + instance.Status.Provisioned = true + result, err := sdkClient.CreateOrUpdateSQLServer(sqlServerProperties) + if err != nil { + instance.Status.Provisioning = false + instance.Status.Provisioned = false + } - //err = CreateResource() - // if err != nil { + r.Log.Info("result from createorupdate", "resultt", result) - // } + // write information back to instance + if updateerr := r.Status().Update(ctx, instance); updateerr != nil { + r.Recorder.Event(instance, "Warning", "Failed", "Unable to update instance") + } - // instance.Status.Provisioning = false - // instance.Status.Provisioned = true + // now that the status is updatetd we can exit if there was an error + if err != nil { + r.Recorder.Event(instance, "Warning", "Failed", "Unable to provision or update instance") + return errhelp.NewAzureError(err) + } - // if err = r.Status().Update(ctx, instance); err != nil { - // r.Recorder.Event(instance, "Warning", "Failed", "Unable to update instance") - // } + r.Recorder.Event(instance, "Normal", "Provisioned", "created or updated entity") return nil } func (r *SqlServerReconciler) deleteExternal(instance *azurev1.SqlServer) error { - // ctx := context.Background() + ctx := context.Background() name := instance.ObjectMeta.Name - // groupName := instance.Spec.ResourceGroupName - // delette resource - - r.Recorder.Event(instance, "Normal", "Deleted", name+" deleted") - return nil -} + groupName := instance.Spec.ResourceGroup + location := instance.Spec.Location + + sdkClient := sql.GoSDKClient{ + Ctx: ctx, + ResourceGroupName: groupName, + ServerName: name, + Location: location, + } -func (r *SqlServerReconciler) addFinalizer(instance *azurev1.SqlServer) error { - helpers.AddFinalizer(instance, SQLServerFinalizerName) - err := r.Update(context.Background(), instance) + _, err := sdkClient.DeleteSQLServer() if err != nil { - return fmt.Errorf("failed to update finalizer: %v", err) + r.Recorder.Event(instance, "Warning", "Failed", "Couldn't delete resouce in azure") + return err } - r.Recorder.Event(instance, "Normal", "Updated", fmt.Sprintf("finalizer %s added", SQLServerFinalizerName)) + + r.Recorder.Event(instance, "Normal", "Deleted", name+" deleted") return nil } diff --git a/controllers/sqlserver_controller_finalizer.go b/controllers/sqlserver_controller_finalizer.go new file mode 100644 index 00000000000..595cc8a9565 --- /dev/null +++ b/controllers/sqlserver_controller_finalizer.go @@ -0,0 +1,37 @@ +/* +Copyright 2019 microsoft. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllers + +import ( + "context" + "fmt" + + azurev1 "github.com/Azure/azure-service-operator/api/v1" + helpers "github.com/Azure/azure-service-operator/pkg/helpers" +) + +const SQLServerFinalizerName = "sqlserver.finalizers.azure.com" + +func (r *SqlServerReconciler) addFinalizer(instance *azurev1.SqlServer) error { + helpers.AddFinalizer(instance, SQLServerFinalizerName) + err := r.Update(context.Background(), instance) + if err != nil { + return fmt.Errorf("failed to update finalizer: %v", err) + } + r.Recorder.Event(instance, "Normal", "Updated", fmt.Sprintf("finalizer %s added", SQLServerFinalizerName)) + return nil +} diff --git a/main.go b/main.go index 251679af17f..8daad01c60b 100644 --- a/main.go +++ b/main.go @@ -172,8 +172,9 @@ func main() { } if err = (&controllers.SqlServerReconciler{ - Client: mgr.GetClient(), - Log: ctrl.Log.WithName("controllers").WithName("SqlServer"), + Client: mgr.GetClient(), + Log: ctrl.Log.WithName("controllers").WithName("SqlServer"), + Recorder: mgr.GetEventRecorderFor("SqlServer-controller"), }).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "SqlServer") os.Exit(1) diff --git a/pkg/resourcemanager/sqlclient/sqlclient_godsk.go b/pkg/resourcemanager/sqlclient/sqlclient_godsk.go index 99312c6af46..22952c5e3e2 100644 --- a/pkg/resourcemanager/sqlclient/sqlclient_godsk.go +++ b/pkg/resourcemanager/sqlclient/sqlclient_godsk.go @@ -7,6 +7,7 @@ package sqlclient import ( "fmt" + "log" "strings" "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/2015-05-01-preview/sql" @@ -34,23 +35,22 @@ func getGoCBClient() sql.DatabasesClient { } // CreateOrUpdateSQLServer creates a SQL server in Azure -func (sdk GoSDKClient) CreateOrUpdateSQLServer(properties SQLServerProperties) (result bool, err error) { +func (sdk GoSDKClient) CreateOrUpdateSQLServer(properties SQLServerProperties) (s sql.Server, err error) { serversClient := getGoServersClient() serverProp := SQLServerPropertiesToServer(properties) - _, err = serversClient.CreateOrUpdate( + future, err := serversClient.CreateOrUpdate( sdk.Ctx, sdk.ResourceGroupName, sdk.ServerName, sql.Server{ - Location: to.StringPtr(config.Location()), + Location: to.StringPtr(sdk.Location), ServerProperties: &serverProp, }) - if err != nil { - return false, fmt.Errorf("cannot create sql server: %v", err) - } - return true, nil + log.Println(future) + + return future.Result(serversClient) } // SQLServerReady returns true if the SQL server is active