public async Task <IActionResult> Create([Bind] ResourceToCreateViewModel creationInfo) { _logger.LogTrace($"HomeController.Create (POST) with {creationInfo.ResourceName} entered."); try { if (ModelState.IsValid) { // Trying without the privileged backend service should demonstrate the value of the concept of // creating privileged, private microservices for control plane operations of an PaaS/SaaS platform // that needs to provision resources when dynamically provisioning customer instances / tenants for their offering. if (creationInfo.TryWithoutPrivilegedBackend) { _logger.LogInformation($"HomeController.Create (POST) trying to create resource of type {creationInfo.FriendlyType} without backend-service."); switch (creationInfo.FriendlyType) { case "Datalake": await _storageRepo.CreateAsync( creationInfo.ResourceName, creationInfo.Location, StorageType.Datalake, creationInfo.ResourceSku, _frontendSettings.SecurityConfig.ClientId, creationInfo.ResourcePropertiesForCreation["Filesystem"], creationInfo.ResourcePropertiesForCreation["Folder"]); break; case "Blob": await _storageRepo.CreateAsync( creationInfo.ResourceName, creationInfo.Location, StorageType.Blob, creationInfo.ResourceSku); break; default: throw new System.ArgumentException("Invalid resource type passed in. Please check valid types for this sample!"); } ; _logger.LogInformation($"HomeController.Create (POST) created resource of type {creationInfo.FriendlyType} without backend-service, SUCCESSFULLY."); } else { _logger.LogInformation($"HomeController.Create (POST) trying to create resource of type {creationInfo.FriendlyType} WITH gRPC backend-service."); // Call the privileged backend service. In a setup in which the managed identity of this frontend web app // has reader permissions, only (which should be the case), only by calling the privileged backend service // the resource creation operations should succeed. #pragma warning disable CS8524 // The switch expression does not handle some values of its input type (it is not exhaustive) involving an unnamed enum value. var requestMessage = new ResourceCreationRequest { Name = creationInfo.ResourceName, Location = creationInfo.Location, Sku = creationInfo.ResourceSku switch // This here caused CS8524 - probably a compiler bug? { ResourcesRepository.Sku.Basic => SupportedSkus.Basic, ResourcesRepository.Sku.Standard => SupportedSkus.Standard, ResourcesRepository.Sku.Premium => SupportedSkus.Premium }, ResType = creationInfo.FriendlyType switch { "Datalake" => SupportedResourceTypes.Datalake, "Blob" => SupportedResourceTypes.Storage, _ => SupportedResourceTypes.Generic } };
public async override Task <GrpcResourceManagement.ResourceResponse> CreateStorage(GrpcResourceManagement.ResourceCreationRequest request, ServerCallContext context) { _logger.LogTrace("GRPC ResourcesService.CreateStorage entering..."); // Craft a skeleton for a response message. var responseMsg = new GrpcResourceManagement.ResourceResponse { Succeeded = false, Message = string.Empty }; try { // Some basic request message processing. var fsName = request.Props.GetValueOrDefault("Filesystem", string.Empty); var folderName = request.Props.GetValueOrDefault("Folder", string.Empty); var repoSku = request.Sku switch { GrpcResourceManagement.SupportedSkus.Basic => ResourcesRepository.Sku.Basic, _ => ResourcesRepository.Sku.Basic }; // Try creating the resources. switch (request.ResType) { case GrpcResourceManagement.SupportedResourceTypes.Datalake: if (string.IsNullOrWhiteSpace(fsName) || string.IsNullOrWhiteSpace(folderName)) { throw new ArgumentException("Both, Filesystem and Folder properties need to be passed with none-empty strings!"); } await _storageRepo.CreateAsync( request.Name, request.Location, StorageType.Datalake, repoSku, _config.SecurityConfig.ClientId, fsName, folderName); break; case GrpcResourceManagement.SupportedResourceTypes.Storage: await _storageRepo.CreateAsync( request.Name, request.Location, StorageType.Blob, repoSku); break; default: throw new Exception("Unsupported resource type used in request!"); } responseMsg.Succeeded = true; responseMsg.Message = $"Successfully created {request.ResType} in {_config.ResourcesConfig.ResourceGroupName} of subscription {_config.ResourcesConfig.SubscriptionId}!"; } catch (Exception ex) { _logger.LogError(ex, "GRPC ResourcesService.Create ran into exception."); responseMsg.Succeeded = false; responseMsg.Message = $"Failed creating a new {request.ResType.ToString()} in {_config.ResourcesConfig.ResourceGroupName} of subscription {_config.ResourcesConfig.SubscriptionId} due to the following error: {ex.Message}"; } _logger.LogTrace($"GRPC ResourcesService.Create exiting with responseMsg.Succeeded = {responseMsg.Succeeded} and responseMsg.Message = {responseMsg.Message}."); return(responseMsg); }