public async Task <IActionResult> Delete(long?id, [FromServices] ITenantRepository tenantRepository) { //データの入力チェック if (id == null) { return(JsonBadRequest("Invalid inputs.")); } //データの存在チェック var node = await nodeRepository.GetByIdAsync(id.Value); if (node == null) { return(JsonNotFound($"Node ID {id.Value} is not found.")); } // 削除対象のノードでコンテナ稼働中の場合、削除しない var response = await clusterManagementLogic.GetAllContainerDetailsInfosAsync(); if (response.IsSuccess) { int runningCount = 0; foreach (var container in response.Value) { // ステータスによらず、全て稼働中と見做す if (node.Name.Equals(container.NodeName)) { runningCount++; } } if (runningCount > 0) { return(JsonConflict($"Running containers exists deleting node. node name=[{node.Name}], running container count=[{runningCount}]")); } } if (string.IsNullOrEmpty(node.Partition) != false) { //パーティションが設定されていたら、消す //既にノードが外されている場合を考慮し、もし失敗しても気にせず削除処理を続ける await clusterManagementLogic.UpdatePartitionLabelAsync(node.Name, ""); } // 全てのアサイン情報を削除する var tenants = tenantRepository.GetAllTenants(); foreach (Tenant tenant in tenants) { await clusterManagementLogic.UpdateTenantEnabledLabelAsync(node.Name, tenant.Name, false); } // KQI管理者用名前空間のアサイン情報を削除する await clusterManagementLogic.UpdateTenantEnabledLabelAsync(node.Name, containerManageOptions.KqiAdminNamespace, false); nodeRepository.ResetAssinedTenants(node.Id); nodeRepository.Delete(node); unitOfWork.Commit(); return(JsonNoContent()); }
public async Task <IActionResult> DeleteTenantAsync(long id, [FromBody] DeleteInputModel model) { // 返却データ DeleteOutputModel result = new DeleteOutputModel(); // 入力モデル・データのチェック if (!ModelState.IsValid) { return(JsonBadRequest($"Invalid inputs: illegal input model")); } // 引数 id のエントリーが存在しない Tenant tenant = tenantRepository.Get(id); if (tenant == null) { return(JsonNotFound($"Invalid inputs: not found tanant id [{id}].")); } // 自分自身の接続中のテナントが対象なら削除不可 if (CurrentUserInfo.SelectedTenant.Id == id) { return(JsonConflict($"Illegal state: CurrentUserInfo.SelectedTenant.Id is [{id}].")); } // 削除対象のテナントでコンテナ稼働中の場合は削除しない var containers = await clusterManagementLogic.GetAllContainerDetailsInfosAsync(); if (!containers.IsSuccess) { JsonError(HttpStatusCode.ServiceUnavailable, $"ClusterManagementLogic#GetAllContainerDetailsInfosAsync() retusns error. tenantName=[{tenant.Name}]"); } else if (containers.Value.Count() > 0) { var runningCount = 0; // Where().Count() で個数を一括取得できるが、ステータスを確認するかもしれないので foreach 文とした。 foreach (var c in containers.Value) { // ステータスによらず、全て稼働中と見做す if (c.TenantName.Equals(tenant.Name)) { runningCount += 1; } } if (runningCount > 0) { return(JsonConflict($"Running containers exists deleting tenant. tenant name=[{tenant.Name}], running container count=[{runningCount}]")); } containers.Value.Where(x => x.TenantName.Equals(tenant.Name)); } // 削除対象のテナントを所有するユーザ・リストを獲得 IEnumerable <User> users = userRepository.GetUsers(id); foreach (User user in users) { UserInfo userInfo = userRepository.GetUserInfo(user); // 削除対象のテナントを、アクセス中のユーザが利用している場合がありうるが、判別できないので無視する // ユーザにおいて削除対象のテナントを detach userRepository.DetachTenant(user.Id, id, false); // 第3引数は true/false どちらでもよい // DefaultTenant が削除対象のテナントなら変更 if (user.DefaultTenantId == id) { if (userInfo.TenantDic.Count() > 1) { // 他の登録テナントを DefaultTenant とする Tenant anotherTenant = userInfo.TenantDic.Keys.FirstOrDefault(t => t.Id != id); user.DefaultTenantId = anotherTenant.Id; } else { // サンドボックステナントを DefaultTenant とする userRepository.AttachSandbox(user); } } // 更新したユーザ ID を結果データとして返却 result.UpdateUserIdList.Add(user.Id); } // バケットの削除 // DeleteInputModel の IgnoreMinioBucketDeletion が false なら削除 // ファイル数が膨大な時は、このロジックで削除しないこと if (model.IgnoreMinioBucketDeletion != null && !model.IgnoreMinioBucketDeletion.Value) { var storage = tenantRepository.GetStorage(tenant.StorageId.Value); if (storage == null) { return(JsonNotFound($"Illegal state: not found storage id [{tenant.StorageId}].")); } try { await storageLogic.DeleteBucketAsync(tenant, storage); } catch (Exception e) { // 例外発生時はメッセージを警告として格納し処理の中断は行わない var msg = $"StorageLogic#DeleteBucketAsync() throws exception: msg=[{e.Message}]."; LogWarning(msg); result.StorageWarnMsg = msg; } } else { var msg = $"Not deleted minio bucket. You should delete bucket minio [{tenant.Name}] by manual operation."; LogWarning(msg); result.StorageWarnMsg = $"Not deleted minio bucket. You should delete bucket minio [{tenant.Name}] by manual operation."; } // k8s の名前空間の抹消(削除) var k8sResult = await clusterManagementLogic.EraseTenantAsync(tenant.Name); if (!k8sResult) { // 削除に失敗したならメッセージを警告として格納し処理の中断は行わない var msg = $"Couldn't delete cluster master namespace [{tenant.Name}]. Please check the configuration to the connect cluster manager service."; LogWarning(msg); result.KubernetesWarnMsg = msg; } // テナントの削除(関連するDBのエントリも自動削除) tenantRepository.DeleteTenant(tenant); // コミットとリフレッシュ(Tenant, Role) unitOfWork.Commit(); tenantRepository.Refresh(); roleRepository.Refresh(); // 結果の返却 return(JsonOK(result)); }
public async Task <IActionResult> GetResourceByNode([FromServices] INodeRepository nodeRepository) { var nodes = nodeRepository.GetAll(); var nodeInfos = (await clusterManagementLogic.GetAllNodesAsync())?.ToList(); //Removeできるように、Listにしておく if (nodeInfos == null) { return(JsonError(HttpStatusCode.ServiceUnavailable, string.Join("\n", "Fetching nodes is failed."))); } var result = new Dictionary <string, NodeResourceOutputModel>(); //DBから探索 foreach (var node in nodes) { var info = nodeInfos.FirstOrDefault(i => i.Name == node.Name); if (info == null) { result.Add(node.Name, new NodeResourceOutputModel(node)); } else { result.Add(node.Name, new NodeResourceOutputModel(node, info)); nodeInfos.Remove(info); } } //k8sにしかないノードを追加 foreach (var info in nodeInfos) { result.Add(info.Name, new NodeResourceOutputModel(info)); } var response = await clusterManagementLogic.GetAllContainerDetailsInfosAsync(); if (response.IsSuccess) { foreach (var container in response.Value) { if (string.IsNullOrEmpty(container.NodeName)) { //ノード名がNULL=まだ未割当 if (result.ContainsKey("*Unassigned*") == false) { result.Add("*Unassigned*", new NodeResourceOutputModel()); } result["*Unassigned*"].Add(CreateContainerDetailsOutputModel(container)); } else if (result.ContainsKey(container.NodeName)) { result[container.NodeName].Add(CreateContainerDetailsOutputModel(container)); } else { //nodeInfoから必要な情報を取って、結果に含める var nodeInfo = nodeInfos.Find(n => n.Name == container.NodeName); if (nodeInfo == null) { //ノード一覧にないコンテナなので、あり得ない。ログだけ出して、無視。 JsonError(HttpStatusCode.ServiceUnavailable, $"The container {container.Name} is in the unknown node {container.NodeName}."); continue; } var model = new NodeResourceOutputModel(nodeInfo); model.Add(CreateContainerDetailsOutputModel(container)); result.Add(container.NodeName, model); } } return(JsonOK(result.Values)); } else { return(JsonError(HttpStatusCode.ServiceUnavailable, string.Join("\n", "Fetching container resource is failed.", response.Error))); } }
public async Task <IActionResult> DeleteTenantAsync(long id, [FromServices] INodeRepository nodeRepository) { // 返却データ DeleteOutputModel result = new DeleteOutputModel(); // 入力モデル・データのチェック if (!ModelState.IsValid) { return(JsonBadRequest($"Invalid inputs: illegal input model")); } // 引数 id のエントリーが存在しない Tenant tenant = tenantRepository.Get(id); if (tenant == null) { return(JsonNotFound($"Invalid inputs: not found tanant id [{id}].")); } // "sandbox"テナントは削除させない if (tenant.Name == ApplicationConst.DefaultFirstTenantName) { return(JsonBadRequest($"Tenant [{ApplicationConst.DefaultFirstTenantName}] is not allowed to delete.")); } // 自分自身の接続中のテナントが対象なら削除不可 if (CurrentUserInfo.SelectedTenant.Id == id) { return(JsonConflict($"Illegal state: CurrentUserInfo.SelectedTenant.Id is [{id}].")); } // 削除対象のテナントでコンテナ稼働中の場合は削除しない var containers = await clusterManagementLogic.GetAllContainerDetailsInfosAsync(); if (!containers.IsSuccess) { JsonError(HttpStatusCode.ServiceUnavailable, $"ClusterManagementLogic#GetAllContainerDetailsInfosAsync() retusns error. tenantName=[{tenant.Name}]"); } else if (containers.Value.Count() > 0) { var runningCount = 0; // Where().Count() で個数を一括取得できるが、ステータスを確認するかもしれないので foreach 文とした。 foreach (var c in containers.Value) { // ステータスによらず、全て稼働中と見做す if (c.TenantName.Equals(tenant.Name)) { runningCount += 1; } } if (runningCount > 0) { return(JsonConflict($"Running containers exists deleting tenant. tenant name=[{tenant.Name}], running container count=[{runningCount}]")); } containers.Value.Where(x => x.TenantName.Equals(tenant.Name)); } // 削除対象のテナントを所有するユーザ・リストを獲得 IEnumerable <User> users = userRepository.GetUsers(id); foreach (User user in users) { UserInfo userInfo = userRepository.GetUserInfo(user); // 削除対象のテナントを、アクセス中のユーザが利用している場合がありうるが、判別できないので無視する // ユーザにおいて削除対象のテナントを detach userRepository.DetachTenant(user.Id, id, false); // 第3引数は true/false どちらでもよい // DefaultTenant が削除対象のテナントなら変更 if (user.DefaultTenantId == id) { if (userInfo.TenantDic.Count() > 1) { // 他の登録テナントを DefaultTenant とする Tenant anotherTenant = userInfo.TenantDic.Keys.FirstOrDefault(t => t.Id != id); user.DefaultTenantId = anotherTenant.Id; } else { // サンドボックステナントを DefaultTenant とする userRepository.AttachSandbox(user); } } } // k8s の名前空間の抹消(削除) var k8sResult = await clusterManagementLogic.EraseTenantAsync(tenant.Name); if (!k8sResult) { // 削除に失敗したならメッセージを警告として格納し処理の中断は行わない var msg = $"Couldn't delete cluster master namespace [{tenant.Name}]. Please check the configuration to the connect cluster manager service."; LogWarning(msg); } // 全てのアサイン情報を削除する var nodes = nodeRepository.GetAll(); foreach (Node node in nodes) { await clusterManagementLogic.UpdateTenantEnabledLabelAsync(node.Name, tenant.Name, false); } // テナントの削除(関連するDBのエントリも自動削除) tenantRepository.DeleteTenant(tenant); // コミットとリフレッシュ(Tenant, Role) unitOfWork.Commit(); tenantRepository.Refresh(); roleRepository.Refresh(); // バケット(テナントのデータ)削除用のコンテナを起動する。 var resultContainer = await clusterManagementLogic.RunDeletingTenantDataContainerAsync(tenant); if (resultContainer == null || resultContainer.Status.Succeed() == false) { // コンテナ起動に失敗した場合警告としてメッセージを格納し処理の中断は行わない。 var msg = $"Failed to run container for delete minio bucket. You should delete bucket minio [{tenant.Name}] by manual operation."; LogWarning(msg); result.ContainerWarnMsg = msg; } // 結果の返却 return(JsonOK(result)); }