Exemplo n.º 1
0
        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());
        }
Exemplo n.º 2
0
        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));
        }
Exemplo n.º 3
0
        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)));
            }
        }
Exemplo n.º 4
0
        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));
        }