private void OnEnableInstance(string msg, string reply, string subject) { Logger.Debug(Strings.OnEnableInstanceDebugMessage, ServiceDescription(), msg, reply); object[] credentials = new object[0]; credentials = JsonConvertibleObject.DeserializeFromJsonArray(msg); ServiceCredentials prov_cred = new ServiceCredentials(); Dictionary <string, object> binding_creds_hash = new Dictionary <string, object>(); prov_cred.FromJsonIntermediateObject(credentials[0]); binding_creds_hash = JsonConvertibleObject.ObjectToValue <Dictionary <string, object> >(credentials[1]); prov_cred.ServiceWorkFactory.StartNew( () => { try { this.EnableInstance(ref prov_cred, ref binding_creds_hash); // Update node_id in provision credentials.. prov_cred.NodeId = this.nodeId; credentials[0] = prov_cred; credentials[1] = binding_creds_hash; NodeNats.Publish(reply, null, JsonConvertibleObject.SerializeToJson(credentials)); } catch (Exception ex) { Logger.Warning(ex.ToString()); } }); }
private void OnCleanupNfs(string msg, string reply, string subject) { Logger.Debug(Strings.CleanupNfsLogMessage, ServiceDescription(), msg, reply); object[] request = new object[0]; request = JsonConvertibleObject.DeserializeFromJsonArray(msg); ServiceCredentials prov_cred = new ServiceCredentials(); ServiceCredentials binding_creds = new ServiceCredentials(); prov_cred.FromJsonIntermediateObject(request[0]); binding_creds.FromJsonIntermediateObject(request[1]); prov_cred.ServiceWorkFactory.StartNew( () => { try { string instance = prov_cred.Name; Directory.Delete(this.GetMigrationFolder(instance), true); NodeNats.Publish(reply, null, "true"); } catch (Exception ex) { Logger.Warning(ex.ToString()); } }); }
private void OnImportInstance(string msg, string reply, string subject) { Logger.Debug(Strings.OnImportInstanceDebugLogMessage, ServiceDescription(), msg, reply); object[] credentials = new object[0]; credentials = JsonConvertibleObject.DeserializeFromJsonArray(msg); ProvisionedServicePlanType plan = (ProvisionedServicePlanType)Enum.Parse(typeof(ProvisionedServicePlanType), JsonConvertibleObject.ObjectToValue <string>(credentials[0])); ServiceCredentials prov_cred = new ServiceCredentials(); ServiceCredentials binding_creds = new ServiceCredentials(); prov_cred.FromJsonIntermediateObject(credentials[1]); binding_creds.FromJsonIntermediateObject(credentials[2]); prov_cred.ServiceWorkFactory.StartNew( () => { try { string instance = prov_cred.Name; string file_path = this.GetMigrationFolder(instance); bool result = this.ImportInstance(prov_cred, binding_creds, file_path, plan); NodeNats.Publish(reply, null, result.ToString()); } catch (Exception ex) { Logger.Warning(ex.ToString()); } }); }
private void OnBind(string msg, string reply, string subject) { Logger.Debug(Strings.BindRequestLogMessage, ServiceDescription(), msg, reply); BindResponse response = new BindResponse(); BindRequest bind_message = new BindRequest(); bind_message.FromJsonIntermediateObject(JsonConvertibleObject.DeserializeFromJson(msg)); string name = bind_message.Name; // Create a service credentials object with a name set, so we can run this operation in parallel for different service instances. ServiceCredentials nameCredentials = new ServiceCredentials(); nameCredentials.Name = name; nameCredentials.ServiceWorkFactory.StartNew( () => { try { Dictionary <string, object> bind_opts = bind_message.BindOptions; ServiceCredentials credentials = bind_message.Credentials; response.Credentials = this.Bind(name, bind_opts, credentials); NodeNats.Publish(reply, null, EncodeSuccess(response)); } catch (Exception ex) { Logger.Warning(ex.ToString()); NodeNats.Publish(reply, null, EncodeFailure(response, ex)); } }); }
private void OnProvision(string msg, string reply, string subject) { Logger.Debug(Strings.OnProvisionRequestDebugLogMessage, ServiceDescription(), msg, reply); ProvisionResponse response = new ProvisionResponse(); ProvisionRequest provision_req = new ProvisionRequest(); provision_req.FromJsonIntermediateObject(JsonConvertibleObject.DeserializeFromJson(msg)); ProvisionedServicePlanType plan = provision_req.Plan; ServiceCredentials credentials = provision_req.Credentials; if (credentials == null) { credentials = GenerateCredentials(); } credentials.ServiceWorkFactory.StartNew( () => { try { ServiceCredentials credential = Provision(plan, credentials); credential.NodeId = this.nodeId; response.Credentials = credential; Logger.Debug( Strings.OnProvisionSuccessDebugLogMessage, ServiceDescription(), msg, response.SerializeToJson()); NodeNats.Publish(reply, null, EncodeSuccess(response)); } catch (Exception ex) { Logger.Warning(ex.ToString()); NodeNats.Publish(reply, null, EncodeFailure(response)); } }); }
private void OnUnprovision(string msg, string reply, string subject) { Logger.Debug(Strings.UnprovisionRequestDebugLogMessage, ServiceDescription(), msg); SimpleResponse response = new SimpleResponse(); UnprovisionRequest unprovision_req = new UnprovisionRequest(); unprovision_req.FromJsonIntermediateObject(JsonConvertibleObject.DeserializeFromJson(msg)); string name = unprovision_req.Name; // Create a service credentials object with a name set, so we can run this operation in parallel for different service instances. ServiceCredentials credentials = new ServiceCredentials(); credentials.Name = name; credentials.ServiceWorkFactory.StartNew( () => { try { ServiceCredentials[] bindings = unprovision_req.Bindings; bool result = this.Unprovision(name, bindings); if (result) { this.NodeNats.Publish(reply, null, EncodeSuccess(response)); } else { this.NodeNats.Publish(reply, null, EncodeFailure(response)); } } catch (Exception ex) { Logger.Warning(ex.ToString()); NodeNats.Publish(reply, null, EncodeFailure(response, ex)); } }); }
private void OnDisableInstance(string msg, string reply, string subject) { Logger.Debug(Strings.OnDisableInstanceDebugLogMessage, ServiceDescription(), msg, reply); object[] credentials = new object[0]; credentials = JsonConvertibleObject.DeserializeFromJsonArray(msg); ServiceCredentials prov_cred = new ServiceCredentials(); ServiceCredentials binding_creds = new ServiceCredentials(); prov_cred.FromJsonIntermediateObject(credentials[0]); binding_creds.FromJsonIntermediateObject(credentials[1]); prov_cred.ServiceWorkFactory.StartNew( () => { try { string instance = prov_cred.Name; string file_path = this.GetMigrationFolder(instance); Directory.CreateDirectory(file_path); bool result = this.DisableInstance(prov_cred, binding_creds); if (result) { result = this.DumpInstance(prov_cred, binding_creds, file_path); } NodeNats.Publish(reply, null, result.ToString()); } catch (Exception ex) { Logger.Warning(ex.ToString()); } }); }
/// <summary> /// Binds a SQL Server database to an app. /// </summary> /// <param name="name">The name of the service.</param> /// <param name="bindOptions">Binding options.</param> /// <param name="credentials">Already existing credentials.</param> /// <returns> /// A new set of credentials used for binding. /// </returns> protected override ServiceCredentials Bind(string name, Dictionary<string, object> bindOptions, ServiceCredentials credentials) { Logger.Debug(Strings.SqlNodeBindServiceDebugMessage, name, JsonConvertibleObject.SerializeToJson(bindOptions)); Dictionary<string, object> binding = null; try { ProvisionedService service = ProvisionedService.GetService(name); if (service == null) { throw new MSSqlErrorException(MSSqlErrorException.MSSqlConfigNotFound, name); } // create new credential for binding binding = new Dictionary<string, object>(); if (credentials != null) { binding["user"] = credentials.User; binding["password"] = credentials.Password; } else { binding["user"] = "******" + Credentials.GenerateCredential(); binding["password"] = "******" + Credentials.GenerateCredential(); } binding["bind_opts"] = bindOptions; this.CreateDatabaseUser(name, binding["user"] as string, binding["password"] as string); ServiceCredentials response = this.GenerateCredential(name, binding["user"] as string, binding["password"] as string); Logger.Debug(Strings.SqlNodeBindResponseDebugMessage, response.SerializeToJson()); this.bindingServed += 1; return response; } catch (Exception) { if (binding != null) { this.DeleteDatabaseUser(binding["user"] as string); } throw; } }
protected override bool Unprovision(string name, ServiceCredentials[] bindings) { if (string.IsNullOrEmpty(name)) { return false; } bool success = true; ProvisionedService provisioned_service = ProvisionedService.GetService(name); if (provisioned_service == null) { throw new FileServiceErrorException(FileServiceErrorException.FileServiceConfigNotFound, name); } // TODO: validate that database files are not lingering // Delete all bindings, ignore not_found error since we are unprovision try { if (bindings != null) { foreach (ServiceCredentials credential in bindings) { this.Unbind(credential); } } } catch (Exception) { // ignore } if (!this.InstanceCleanup(provisioned_service)) { success = false; } if (!provisioned_service.Destroy()) { Logger.Error(Strings.SqlNodeDeleteServiceErrorMessage, provisioned_service.Name); throw new FileServiceErrorException(FileServiceErrorException.FileServiceLocalDBError); } Logger.Debug(Strings.SqlNodeUnprovisionSuccessDebugMessage, name); return success; }
/// <summary> /// Provisions an directory. /// </summary> /// <param name="planRequest">The payment plan for the service.</param> /// <param name="credentials">Existing credentials for the service.</param> /// <param name="version">The service version.</param> /// <returns> /// Credentials for the provisioned service. /// </returns> protected override ServiceCredentials Provision(string planRequest, ServiceCredentials credentials, string version) { if (planRequest != this.plan) { throw new FileServiceErrorException(FileServiceErrorException.FileServiceInvalidPlan); } if (!this.supportedVersions.Contains(version)) { throw new FileServiceErrorException(ServiceException.UnsupportedVersion); } ProvisionedService provisioned_service = new ProvisionedService(); if (credentials == null) { credentials = this.GenerateCredentials(); } try { string name = credentials.Name; string user = credentials.User; string password = credentials.Password; int port = credentials.Port; provisioned_service.Name = name; provisioned_service.User = user; provisioned_service.Password = password; provisioned_service.Plan = planRequest; provisioned_service.Port = port; this.CreateInstanceStorage(provisioned_service); this.InstanceSystemSetup(provisioned_service); if (!ProvisionedService.Save()) { Logger.Error(Strings.SqlNodeCannotSaveProvisionedServicesErrorMessage, provisioned_service.SerializeToJson()); throw new FileServiceErrorException(FileServiceErrorException.FileServiceLocalDBError); } ServiceCredentials response = this.GenerateCredential(provisioned_service.Name, provisioned_service.User, provisioned_service.Password, provisioned_service.Port.Value); this.provisionServed += 1; return response; } catch (Exception) { this.InstanceCleanup(provisioned_service); throw; } }
protected override bool EnableInstance(ref ServiceCredentials provisionedCredential, ref Dictionary<string, object> bindingCredentialsHash) { if (provisionedCredential == null) { throw new ArgumentNullException("provisionedCredential"); } if (bindingCredentialsHash == null) { throw new ArgumentNullException("bindingCredentialsHash"); } Logger.Debug("Enabling instance {0}", provisionedCredential.Name); try { provisionedCredential = Bind(provisionedCredential.Name, null, provisionedCredential); foreach (KeyValuePair<string, object> pair in bindingCredentialsHash) { Handle handle = (Handle)pair.Value; ServiceCredentials cred = new ServiceCredentials(); cred.FromJsonIntermediateObject(handle.Credentials); Dictionary<string, object> bindingOptions = handle.Credentials.BindOptions; Bind(cred.Name, bindingOptions, cred); } } catch (Exception ex) { Logger.Warning("Could not enable instance {0}: [{1}]", provisionedCredential.Name, ex.ToString()); return false; } return true; }
protected override bool DisableInstance(ServiceCredentials provisionedCredential, Collection<ServiceCredentials> bindingCredentials) { if (provisionedCredential == null) { throw new ArgumentNullException("provisionedCredential"); } if (bindingCredentials == null) { throw new ArgumentNullException("bindingCredentials"); } Logger.Info("Disable instance {0} request", provisionedCredential.Name); bindingCredentials.Add(provisionedCredential); try { foreach (ServiceCredentials credential in bindingCredentials) { this.Unbind(credential); } } catch (Exception ex) { Logger.Warning("Error disabling instance {0}: [{1}]", provisionedCredential.Name, ex.ToString()); return false; } return true; }
/// <summary> /// Subclasses have to implement this in order to disable an instance. /// </summary> /// <param name="provisionedCredential">The provisioned credentials.</param> /// <param name="bindingCredentials">The binding credentials.</param> /// <returns>A bool indicating whether the request was successful.</returns> protected abstract bool DisableInstance(ServiceCredentials provisionedCredential, Collection<ServiceCredentials> bindingCredentials);
/// <summary> /// Subclasses have to implement this in order to unbind a service from an app. /// </summary> /// <param name="credentials">The credentials that have to be unprovisioned.</param> /// <returns>A bool indicating whether the unbind request was successful.</returns> protected abstract bool Unbind(ServiceCredentials credentials);
/// <summary> /// Subclasses have to implement this in order to bind a provisioned service to an app. /// </summary> /// <param name="name">The name of the service.</param> /// <param name="bindOptions">Binding options.</param> /// <param name="credentials">Already existing credentials.</param> /// <returns>A new set of credentials used for binding.</returns> protected abstract ServiceCredentials Bind(string name, Dictionary <string, object> bindOptions, ServiceCredentials credentials);
/// <summary> /// Subclasses have to implement this in order to provision services. /// </summary> /// <param name="planRequest">The payment plan for the service.</param> /// <param name="credentials">Existing credentials for the service.</param> /// <returns>Credentials for the provisioned service.</returns> protected abstract ServiceCredentials Provision(ProvisionedServicePlanType planRequest, ServiceCredentials credentials);
private bool PurgeOrphan(string[] orphanInstancesList, ServiceCredentials[] orphanBindingsList) { bool ret = true; ServiceCredentials[] allBindingsList = this.AllBindingsList(); foreach (string ins in orphanInstancesList) { try { ServiceCredentials[] bindings = allBindingsList.Where(b => b.Name == ins).ToArray(); Logger.Debug(Strings.PurgeOrphanDebugLogMessage, ins, string.Join(", ", JsonConvertibleObject.SerializeToJson(bindings))); ret = ret && this.Unprovision(ins, bindings); // Remove the OBs that are unbinded by unprovision orphanBindingsList = (from ob in orphanBindingsList where !bindings.Any(binding => binding.Name == ob.Name) select ob).ToArray(); } catch (Exception ex) { Logger.Debug(Strings.PurgeOrphanErrorLogMessage, ins, ex.ToString()); } } foreach (ServiceCredentials credential in orphanBindingsList) { // We're running the unbind on the same thread that other stuff is running for this service instance, so we don't get race conditions; need to wait though, so we have a result status credential.ServiceWorkFactory.StartNew( () => { try { Logger.Debug(Strings.PurgeOrphanUnbindBindingDebugLogMessage, credential.SerializeToJson()); ret = ret && this.Unbind(credential); } catch (Exception ex) { Logger.Debug(Strings.PurgeOrphanUnbindBindingErrorLogMessage, credential.SerializeToJson(), ex.ToString()); } }).Wait(); } return ret; }
private void OnUnprovision(string msg, string reply, string subject) { Logger.Debug(Strings.UnprovisionRequestDebugLogMessage, ServiceDescription(), msg); SimpleResponse response = new SimpleResponse(); UnprovisionRequest unprovision_req = new UnprovisionRequest(); unprovision_req.FromJsonIntermediateObject(JsonConvertibleObject.DeserializeFromJson(msg)); string name = unprovision_req.Name; // Create a service credentials object with a name set, so we can run this operation in parallel for different service instances. ServiceCredentials credentials = new ServiceCredentials(); credentials.Name = name; credentials.ServiceWorkFactory.StartNew( () => { try { ServiceCredentials[] bindings = unprovision_req.Bindings; bool result = this.Unprovision(name, bindings); if (result) { this.nodeNats.Publish(reply, null, EncodeSuccess(response)); this.capacity += CapacityUnit(); } else { this.nodeNats.Publish(reply, null, EncodeFailure(response)); } } catch (Exception ex) { Logger.Warning(ex.ToString()); nodeNats.Publish(reply, null, EncodeFailure(response, ex)); } }); }
private void OnBind(string msg, string reply, string subject) { Logger.Debug(Strings.BindRequestLogMessage, ServiceDescription(), msg, reply); BindResponse response = new BindResponse(); BindRequest bind_message = new BindRequest(); bind_message.FromJsonIntermediateObject(JsonConvertibleObject.DeserializeFromJson(msg)); string name = bind_message.Name; // Create a service credentials object with a name set, so we can run this operation in parallel for different service instances. ServiceCredentials nameCredentials = new ServiceCredentials(); nameCredentials.Name = name; nameCredentials.ServiceWorkFactory.StartNew( () => { try { Dictionary<string, object> bind_opts = bind_message.BindOptions; ServiceCredentials credentials = bind_message.Credentials; response.Credentials = this.Bind(name, bind_opts, credentials); nodeNats.Publish(reply, null, EncodeSuccess(response)); } catch (Exception ex) { Logger.Warning(ex.ToString()); nodeNats.Publish(reply, null, EncodeFailure(response, ex)); } }); }
/// <summary> /// Subclasses have to implement this in order to update services. /// </summary> /// <param name="provisionedCredential">The provisioned credentials.</param> /// <param name="bindingCredentials">The binding credentials.</param> /// <returns>Updated service credentials</returns> protected abstract object[] UpdateInstance(ServiceCredentials provisionedCredential, Dictionary<string, object> bindingCredentials);
protected abstract bool Unprovision(string name, ServiceCredentials[] bindings);
/// <summary> /// Re-enables the instance, re-binds credentials. /// </summary> /// <param name="provisionedCredential">The provisioned credential.</param> /// <param name="bindingCredentialsHash">The binding credentials hash.</param> /// <returns> /// A bool indicating whether the request was successful. /// </returns> protected override bool EnableInstance(ref ServiceCredentials provisionedCredential, ref Dictionary<string, object> bindingCredentialsHash) { // todo: vladi: Replace with code for odbc object for SQL Server return false; }
/// <summary> /// Provisions an MS Sql Server database. /// </summary> /// <param name="planRequest">The payment plan for the service.</param> /// <param name="credentials">Existing credentials for the service.</param> /// <returns> /// Credentials for the provisioned service. /// </returns> protected override ServiceCredentials Provision(ProvisionedServicePlanType planRequest, ServiceCredentials credentials) { //// todo: chek for plan ProvisionedService provisioned_service = new ProvisionedService(); if (credentials == null) { throw new ArgumentNullException("credentials"); } try { string name = credentials.Name; string user = credentials.User; string password = credentials.Password; provisioned_service.Name = name; provisioned_service.User = user; provisioned_service.Password = password; provisioned_service.Plan = planRequest; this.CreateDatabase(provisioned_service); if (!ProvisionedService.Save()) { Logger.Error(Strings.SqlNodeCannotSaveProvisionedServicesErrorMessage, provisioned_service.SerializeToJson()); throw new MSSqlErrorException(MSSqlErrorException.MSSqlLocalDBError); } ServiceCredentials response = this.GenerateCredential(provisioned_service.Name, provisioned_service.User, provisioned_service.Password); this.provisionServed += 1; return response; } catch (Exception) { this.DeleteDatabase(provisioned_service); throw; } }
/// <summary> /// Subclasses have to implement this in order to dump an instance. /// </summary> /// <param name="provisionedCredential">The provisioned credential.</param> /// <param name="bindingCredentials">The binding credentials.</param> /// <param name="filePath">The file path where to dump the service.</param> /// <returns>A bool indicating whether the request was successful.</returns> protected abstract bool DumpInstance(ServiceCredentials provisionedCredential, Collection<ServiceCredentials> bindingCredentials, string filePath);
/// <summary> /// Subclasses have to implement this in order to disable an instance. /// </summary> /// <param name="provisionedCredential">The provisioned credentials.</param> /// <param name="bindingCredentials">The binding credentials.</param> /// <returns>A bool indicating whether the request was successful.</returns> protected abstract bool DisableInstance(ServiceCredentials provisionedCredential, ServiceCredentials bindingCredentials);
/// <summary> /// Binds a shared directory to an app. /// </summary> /// <param name="name">The name of the service.</param> /// <param name="bindOptions">Binding options.</param> /// <param name="credentials">Already existing credentials.</param> /// <returns> /// A new set of credentials used for binding. /// </returns> protected override ServiceCredentials Bind(string name, Dictionary<string, object> bindOptions, ServiceCredentials credentials) { Logger.Debug(Strings.SqlNodeBindServiceDebugMessage, name, JsonConvertibleObject.SerializeToJson(bindOptions)); ProvisionedService service = ProvisionedService.GetService(name); if (service == null) { throw new FileServiceErrorException(FileServiceErrorException.FileServiceConfigNotFound, name); } string user = null; string password = null; if (credentials != null) { user = credentials.User; password = credentials.Password; } else { user = "******" + Credentials.GenerateCredential(); password = "******" + Credentials.GenerateCredential(); } var binding = new ServiceBinding { User = user, Password = password }; Bind(service, binding); service.Bindings.Add(binding); if (!ProvisionedService.Save()) { Logger.Error(Strings.SqlNodeCannotSaveProvisionedServicesErrorMessage, credentials == null ? string.Empty : credentials.SerializeToJson()); throw new FileServiceErrorException(FileServiceErrorException.FileServiceLocalDBError); } ServiceCredentials response = this.GenerateCredential(name, user, password, service.Port.Value); Logger.Debug(Strings.SqlNodeBindResponseDebugMessage, response.SerializeToJson()); this.bindingServed += 1; return response; }
/// <summary> /// Subclasses have to implement this in order to dump an instance. /// </summary> /// <param name="provisionedCredential">The provisioned credential.</param> /// <param name="bindingCredentials">The binding credentials.</param> /// <param name="filePath">The file path where to dump the service.</param> /// <returns>A bool indicating whether the request was successful.</returns> protected abstract bool DumpInstance(ServiceCredentials provisionedCredential, ServiceCredentials bindingCredentials, string filePath);
protected override bool DumpInstance(ServiceCredentials provisionedCredential, Collection<ServiceCredentials> bindingCredentials, string filePath) { if (provisionedCredential == null) { throw new ArgumentNullException("provisionedCredential"); } if (bindingCredentials == null) { throw new ArgumentNullException("bindingCredentials"); } string dumpFile = Path.Combine(filePath, provisionedCredential.Name); Logger.Info("Dump instance {0} content to {1}", provisionedCredential.Name, dumpFile); try { string instanceDir = this.GetInstanceDirectory(provisionedCredential.Name); if (!Directory.EnumerateFileSystemEntries(instanceDir).Any()) { File.Create(Path.Combine(instanceDir, Strings.MigrationEmptyFolderDummyFileName)).Dispose(); } ZipUtilities.ZipFile(instanceDir, dumpFile); } catch (Exception ex) { Logger.Warning("Error dumping instance {0}: [{1}]", provisionedCredential.Name, ex.ToString()); return false; } return true; }
/// <summary> /// Subclasses have to implement this in order to import an instance. /// </summary> /// <param name="provisionedCredential">The provisioned credential.</param> /// <param name="bindingCredentials">The binding credentials.</param> /// <param name="filePath">The file path from which to import the service.</param> /// <param name="planRequest">The payment plan.</param> /// <returns>A bool indicating whether the request was successful.</returns> protected abstract bool ImportInstance(ServiceCredentials provisionedCredential, ServiceCredentials bindingCredentials, string filePath, ProvisionedServicePlanType planRequest);
protected override bool ImportInstance(ServiceCredentials provisionedCredential, Dictionary<string, object> bindingCredentialsHash, string filePath, string planRequest) { if (provisionedCredential == null) { throw new ArgumentNullException("provisionedCredential"); } if (bindingCredentialsHash == null) { throw new ArgumentNullException("bindingCredentialsHash"); } string dumpFile = Path.Combine(filePath, provisionedCredential.Name); Logger.Debug("Import instance {0} from {1}", provisionedCredential.Name, dumpFile); try { this.Provision(planRequest, provisionedCredential, this.defaultVersion); string instanceDir = this.GetInstanceDirectory(provisionedCredential.Name); ZipUtilities.UnzipFile(this.GetInstanceDirectory(provisionedCredential.Name), dumpFile); if (File.Exists(Path.Combine(instanceDir, Strings.MigrationEmptyFolderDummyFileName))) { File.Delete(Path.Combine(instanceDir, Strings.MigrationEmptyFolderDummyFileName)); } } catch (Exception ex) { Logger.Warning("Error importing instance {0} from {1}: [{2}]", provisionedCredential.Name, dumpFile, ex.ToString()); return false; } return true; }
protected abstract bool EnableInstance(ref ServiceCredentials provisionedCredential, ref Dictionary <string, object> bindingCredentialsHash);
protected override bool Unbind(ServiceCredentials credentials) { if (credentials == null) { return false; } bool success = true; Logger.Debug(Strings.SqlNodeUnbindServiceDebugMessage, credentials.SerializeToJson()); string name = credentials.Name; string user = credentials.User; ProvisionedService serviceInstance = ProvisionedService.GetService(name); // Remove the binding form the local db var binding = serviceInstance.Bindings.FirstOrDefault(p => p.User == user); serviceInstance.Bindings.Remove(binding); if (!ProvisionedService.Save()) { Logger.Error(Strings.SqlNodeCannotSaveProvisionedServicesErrorMessage, credentials.SerializeToJson()); throw new FileServiceErrorException(FileServiceErrorException.FileServiceLocalDBError); } try { DeleteInstanceUser(user); } catch (Exception ex) { Logger.Error("Unable to delete bound user {1} for instance {0}. Exception: {2}", name, user, ex.ToString()); success = false; } return success; }
/// <summary> /// Subclasses have to implement this in order to import an instance. /// </summary> /// <param name="provisionedCredential">The provisioned credential.</param> /// <param name="bindingCredentialsHash">The binding credentials.</param> /// <param name="filePath">The file path from which to import the service.</param> /// <param name="planRequest">The payment plan.</param> /// <returns>A bool indicating whether the request was successful.</returns> protected abstract bool ImportInstance(ServiceCredentials provisionedCredential, Dictionary<string, object> bindingCredentialsHash, string filePath, string planRequest);
protected override object[] UpdateInstance(ServiceCredentials provisionedCredential, Dictionary<string, object> bindingCredentials) { if (provisionedCredential == null) { throw new ArgumentNullException("provisionedCredential"); } if (bindingCredentials == null) { throw new ArgumentNullException("bindingCredentials"); } object[] response = new object[2]; string name = provisionedCredential.Name; try { provisionedCredential = Bind(name, null, provisionedCredential); Dictionary<string, object> bindingCredentialsResponse = new Dictionary<string, object>(); foreach (KeyValuePair<string, object> pair in bindingCredentials) { ServiceCredentials cred = (ServiceCredentials)pair.Value; ServiceCredentials bindingCred = Bind(cred.Name, cred.BindOptions, cred); bindingCredentialsResponse[pair.Key] = bindingCred; } response[0] = provisionedCredential; response[1] = bindingCredentialsResponse; return response; } catch (Exception ex) { Logger.Warning(ex.ToString()); return new object[0]; } }
protected override bool Unprovision(string name, ServiceCredentials[] bindings) { if (string.IsNullOrEmpty(name)) { return false; } Logger.Debug(Strings.SqlNodeUnprovisionDatabaseDebugMessage, name, JsonConvertibleObject.SerializeToJson(bindings.Select(binding => binding.ToJsonIntermediateObject()).ToArray())); ProvisionedService provisioned_service = ProvisionedService.GetService(name); if (provisioned_service == null) { throw new MSSqlErrorException(MSSqlErrorException.MSSqlConfigNotFound, name); } // TODO: validate that database files are not lingering // Delete all bindings, ignore not_found error since we are unprovision try { if (bindings != null) { foreach (ServiceCredentials credential in bindings) { this.Unbind(credential); } } } catch (Exception) { // ignore } this.DeleteDatabase(provisioned_service); long storage = this.StorageForService(provisioned_service); this.availableStorageBytes += storage; this.availableCapacity += this.CapacityUnit(); if (!provisioned_service.Destroy()) { Logger.Error(Strings.SqlNodeDeleteServiceErrorMessage, provisioned_service.Name); throw new MSSqlErrorException(MSSqlErrorException.MSSqlLocalDBError); } Logger.Debug(Strings.SqlNodeUnprovisionSuccessDebugMessage, name); return true; }
/// <summary> /// Dumps database content into a given path. /// </summary> /// <param name="provisionedCredential">The provisioned credential.</param> /// <param name="bindingCredentials">The binding credentials.</param> /// <param name="filePath">The file path where to dump the service.</param> /// <returns> /// A bool indicating whether the request was successful. /// </returns> protected override bool DumpInstance(ServiceCredentials provisionedCredential, ServiceCredentials bindingCredentials, string filePath) { // todo: vladi: Replace with code for odbc object for SQL Server return false; }
/// <summary> /// Subclasses have to implement this in order to bind a provisioned service to an app. /// </summary> /// <param name="name">The name of the service.</param> /// <param name="bindOptions">Binding options.</param> /// <param name="credentials">Already existing credentials.</param> /// <returns>A new set of credentials used for binding.</returns> protected abstract ServiceCredentials Bind(string name, Dictionary<string, object> bindOptions, ServiceCredentials credentials);
/// <summary> /// Imports an instance from a path. /// </summary> /// <param name="provisionedCredential">The provisioned credential.</param> /// <param name="bindingCredentials">The binding credentials.</param> /// <param name="filePath">The file path from which to import the service.</param> /// <param name="planRequest">The payment plan.</param> /// <returns> /// A bool indicating whether the request was successful. /// </returns> protected override bool ImportInstance(ServiceCredentials provisionedCredential, ServiceCredentials bindingCredentials, string filePath, ProvisionedServicePlanType planRequest) { // todo: vladi: Replace with code for odbc object for SQL Server return false; }
protected abstract bool EnableInstance(ref ServiceCredentials provisionedCredential, ref Dictionary<string, object> bindingCredentialsHash);
protected override bool Unbind(ServiceCredentials credentials) { if (credentials == null) { return false; } Logger.Debug(Strings.SqlNodeUnbindServiceDebugMessage, credentials.SerializeToJson()); string user = credentials.User; string databaseName = credentials.Name; using (SqlConnection databaseConnection = new SqlConnection(this.ConnectionString)) { databaseConnection.Open(); databaseConnection.ChangeDatabase(databaseName); using (SqlCommand cmdUserExists = new SqlCommand(string.Format(CultureInfo.InvariantCulture, "select count(*) from sys.sysusers where name=N'{0}'", user), databaseConnection)) { int userCount = (int)cmdUserExists.ExecuteScalar(); if (userCount != 1) { throw new MSSqlErrorException(MSSqlErrorException.MSSqlCredentialsNotFound, user); } } } this.DeleteDatabaseUser(user); return true; }
/// <summary> /// Subclasses have to implement this in order to provision services. /// </summary> /// <param name="planRequest">The payment plan for the service.</param> /// <param name="credentials">Existing credentials for the service.</param> /// <param name="version">The service version.</param> /// <returns> /// Credentials for the provisioned service. /// </returns> protected abstract ServiceCredentials Provision(string planRequest, ServiceCredentials credentials, string version);
/// <summary> /// Creates a <see cref="ServiceCredentials"/> object using a database name, a username and a password. /// </summary> /// <param name="name">The name of the database.</param> /// <param name="user">The user.</param> /// <param name="password">The password.</param> /// <returns>A ServiceCredentials object.</returns> private ServiceCredentials GenerateCredential(string name, string user, string password) { ServiceCredentials response = new ServiceCredentials(); response.Name = name; response.HostName = this.localIp; response.Port = this.mssqlConfig.Port; response.User = user; response.UserName = user; response.Password = password; return response; }
public void CreateDatabaseTest() { try { Node_Accessor target = new Node_Accessor(); target.mssqlConfig = new MSSqlOptions(); UhuruSection config = UhuruSection.GetSection(); target.mssqlConfig.Host = config.Service.MSSql.Host; target.mssqlConfig.User = config.Service.MSSql.User; target.mssqlConfig.Password = config.Service.MSSql.Password; target.mssqlConfig.Port = config.Service.MSSql.Port; target.maxLongQuery = config.Service.MaxLengthyQuery; target.mssqlConfig.LogicalStorageUnits = config.Service.MSSql.LogicalStorageUnits; target.mssqlConfig.InitialDataSize = config.Service.MSSql.InitialDataSize; target.mssqlConfig.InitialLogSize = config.Service.MSSql.InitialLogSize; target.mssqlConfig.MaxDataSize = config.Service.MSSql.MaxDataSize; target.mssqlConfig.MaxLogSize = config.Service.MSSql.MaxLogSize; target.mssqlConfig.DataFileGrowth = config.Service.MSSql.DataFileGrowth; target.mssqlConfig.LogFileGrowth = config.Service.MSSql.LogFileGrowth; target.connection = target.ConnectMSSql(); ProvisionedService provisionedService = new ProvisionedService(); DateTime now = DateTime.Now; string decoration = string.Format( "{0}_{1}_{2}", now.Hour, now.Minute, now.Second); provisionedService.Name = "CreateDatabaseTest_" + decoration; provisionedService.User = "******" + decoration; provisionedService.Password = "******"; provisionedService.Plan = ProvisionedServicePlanType.Free; ////////////////////////////////////////////////////////////////////////// // create the provisioned service db and user ////////////////////////////////////////////////////////////////////////// target.CreateDatabase(provisionedService); Thread.Sleep(500); ////////////////////////////////////////////////////////////////////////// // assert the existence of the db files ////////////////////////////////////////////////////////////////////////// string dbScript = target.createDBScript; Regex fnRegex = new Regex(@"FILENAME = N'(.*)'"); MatchCollection matches = fnRegex.Matches(dbScript); foreach (Match m in matches) { string fileName = m.Value.Substring(m.Value.IndexOf('\'')).Trim(new char[] { '\'' }); Assert.IsTrue(File.Exists(fileName), string.Format("File '{0}' does not exist", fileName)); } ////////////////////////////////////////////////////////////////////////// // try to connect as the newly created user ////////////////////////////////////////////////////////////////////////// string sqlTestConnString = string.Format( CultureInfo.InvariantCulture, "Data Source={0},{1};User Id={2};Password={3};MultipleActiveResultSets=true;Pooling=false", target.mssqlConfig.Host, target.mssqlConfig.Port, provisionedService.User, provisionedService.Password); SqlConnection sqlTest = new SqlConnection(sqlTestConnString); sqlTest.Open(); ////////////////////////////////////////////////////////////////////////// // try to connect create a table as the newly created user ////////////////////////////////////////////////////////////////////////// SqlCommand cmdTest = new SqlCommand( string.Format("CREATE TABLE [{0}].[dbo].[TestTable]([Command] [varchar](100) NULL, [Description] [varchar](50) NULL) ON [DATA]", provisionedService.Name), sqlTest); cmdTest.ExecuteNonQuery(); sqlTest.Close(); ////////////////////////////////////////////////////////////////////////// // try to operate on the service db as a different user ////////////////////////////////////////////////////////////////////////// // connect as sa sqlTest.ConnectionString = string.Format( CultureInfo.InvariantCulture, "Data Source={0},{1};User Id={2};Password={3};MultipleActiveResultSets=true;Pooling=false", target.mssqlConfig.Host, target.mssqlConfig.Port, target.mssqlConfig.User, target.mssqlConfig.Password); sqlTest.Open(); string dummyUser = "******" + decoration; string dummyPwd = "password1234!"; //create a dummy user string createLoginString = string.Format(@"CREATE LOGIN {0} WITH PASSWORD = '******'", dummyUser, dummyPwd); cmdTest = new SqlCommand(createLoginString, sqlTest); cmdTest.ExecuteNonQuery(); sqlTest.Close(); // connect as the dummy user sqlTest.ConnectionString = string.Format( CultureInfo.InvariantCulture, "Data Source={0},{1};User Id={2};Password={3};MultipleActiveResultSets=true;Pooling=false", target.mssqlConfig.Host, target.mssqlConfig.Port, dummyUser, dummyPwd); sqlTest.Open(); // try to drop the service db try { cmdTest.CommandText = string.Format("CREATE TABLE [{0}].[dbo].[DummyTable]([Command] [varchar](100) NULL, [Description] [varchar](50) NULL) ON [DATA]", provisionedService.Name); cmdTest.ExecuteNonQuery(); Assert.Fail("Other users have read/write access to the service db"); } catch (SqlException sex) { } ////////////////////////////////////////////////////////////////////////// //Remove database ////////////////////////////////////////////////////////////////////////// ServiceCredentials sc = new ServiceCredentials(); sc.UserName = provisionedService.User; sc.Password = provisionedService.Password; sc.Name = provisionedService.Name; sc.User = provisionedService.User; target.DeleteDatabase(provisionedService); //target.Unprovision(provisionedService.Name, new ServiceCredentials[] { sc }); sqlTest.Close(); target.connection.Close(); } catch (System.Exception ex) { Assert.Fail(ex.Message); } }