/// <summary>
 /// ノードにKQI管理者用名前空間の実行可否設定を Cluster(k8s) へ同期する
 /// </summary>
 /// <param name="node">同期させるノード情報</param>
 /// <returns>同期処理の成否</returns>
 private async Task <bool> SyncKqiAdminEnabledLabel(Node node)
 {
     if (node.AccessLevel != NodeAccessLevel.Disabled)
     {
         // アクセスレベルが "Public" または "Private" の場合、KQI管理者用名前空間の実行を許可する
         return(await clusterManagementLogic.UpdateTenantEnabledLabelAsync(node.Name, containerManageOptions.KqiAdminNamespace, true));
     }
     else
     {
         // アクセスレベルが "Disable" の場合、KQI管理者用名前空間の実行を拒否する
         return(await clusterManagementLogic.UpdateTenantEnabledLabelAsync(node.Name, containerManageOptions.KqiAdminNamespace, false));
     }
 }
Esempio n. 2
0
        public async Task <IActionResult> Create([FromBody] CreateInputModel model,
                                                 [FromServices] ITenantRepository tenantRepository)
        {
            //データの入力チェック
            if (!ModelState.IsValid)
            {
                return(JsonBadRequest("Invalid inputs."));
            }

            //同じ名前のノードは登録できないので、確認する
            Node node = await nodeRepository.GetByNameAsync(model.Name);

            if (node != null)
            {
                return(JsonConflict($"Node {model.Name} already exists: ID = {node.Id}"));
            }

            node = new Node()
            {
                Name               = model.Name,
                Memo               = model.Memo,
                Partition          = model.Partition,
                AccessLevel        = model.AccessLevel == null ? NodeAccessLevel.Disabled : model.AccessLevel.Value,
                TensorBoardEnabled = model.TensorBoardEnabled,
                NotebookEnabled    = model.NotebookEnabled
            };

            if (node.AccessLevel != NodeAccessLevel.Disabled)
            {
                //アクセスレベルがDisable以外であれば、k8sとの同期を行う
                //ノードが存在しない場合を考慮し、もし失敗しても気にせず更新処理を続ける
                await clusterManagementLogic.UpdatePartitionLabelAsync(node.Name, node.Partition);

                if (node.TensorBoardEnabled)
                {
                    await clusterManagementLogic.UpdateTensorBoardEnabledLabelAsync(node.Name, true);
                }

                if (node.NotebookEnabled)
                {
                    await clusterManagementLogic.UpdateNotebookEnabledLabelAsync(node.Name, true);
                }

                // KQI管理者用名前空間の実行を許可する
                await clusterManagementLogic.UpdateTenantEnabledLabelAsync(node.Name, containerManageOptions.KqiAdminNamespace, true);

                if (node.AccessLevel == NodeAccessLevel.Private)
                {
                    //テナントをアサイン
                    if (model.AssignedTenantIds != null)
                    {
                        foreach (long tenantId in model.AssignedTenantIds)
                        {
                            Tenant tenant = tenantRepository.Get(tenantId);
                            if (tenant == null)
                            {
                                return(JsonNotFound($"Tenant ID {tenantId} is not found."));
                            }
                            await clusterManagementLogic.UpdateTenantEnabledLabelAsync(node.Name, tenant.Name, true);
                        }
                        nodeRepository.AssignTenants(node, model.AssignedTenantIds, true);
                    }
                }
                else
                {
                    // アクセスレベルが "Public" の場合、全てのテナントをアサイン
                    var tenants = tenantRepository.GetAllTenants();
                    foreach (Tenant tenant in tenants)
                    {
                        await clusterManagementLogic.UpdateTenantEnabledLabelAsync(node.Name, tenant.Name, true);
                    }
                }
            }

            nodeRepository.Add(node);
            unitOfWork.Commit();

            return(JsonCreated(new IndexOutputModel(node)));
        }
Esempio n. 3
0
        public async Task <IActionResult> CreateForTenant([FromBody] CreateInputModel model, [FromServices] INodeRepository nodeRepository)
        {
            //データの入力チェック
            if (!ModelState.IsValid)
            {
                return(JsonBadRequest("Invalid inputs."));
            }

            if (model.TenantName.StartsWith(containerManageOptions.KqiNamespacePrefix) || model.TenantName.StartsWith(containerManageOptions.KubernetesNamespacePrefix))
            {
                // KqiNamespacePrefix または KubernetesNamespacePrefix で始まるテナント名は許可しないためエラー
                return(JsonBadRequest($"Invalid inputs. 'TenantName' cannot start with '{ containerManageOptions.KqiNamespacePrefix }' or '{ containerManageOptions.KubernetesNamespacePrefix }'."));
            }

            Tenant tenant = tenantRepository.GetFromTenantName(model.TenantName);

            if (tenant != null)
            {
                //テナント名の重複があるのでエラー
                return(JsonConflict($"Tenant {model.TenantName} already exists: ID = {tenant.Id}"));
            }
            if (model.DefaultGitId != null && model.GitIds.Contains(model.DefaultGitId.Value) == false)
            {
                //デフォルトGitがGit一覧の中になかったらエラー
                return(JsonConflict($"Default Git ID {model.DefaultGitId.Value} does NOT exist in selected gits."));
            }
            if (model.DefaultRegistryId != null && model.RegistryIds.Contains(model.DefaultRegistryId.Value) == false)
            {
                //デフォルトレジストリがレジストリ一覧の中になかったらエラー
                return(JsonConflict($"Default Registry ID {model.DefaultRegistryId.Value} does NOT exist in selected registries."));
            }

            tenant = new Tenant()
            {
                Name          = model.TenantName,
                DisplayName   = model.DisplayName,
                StorageBucket = model.TenantName,
                StorageId     = model.StorageId,
                AvailableInfiniteTimeNotebook = model.AvailableInfiniteTimeNotebook
            };

            Git git = null;

            if (model.GitIds != null && model.GitIds.Count() > 0)
            {
                //デフォルトGitの設定(無ければ一個目)
                tenant.DefaultGitId = model.DefaultGitId == null?
                                      model.GitIds.ElementAt(0) : model.DefaultGitId.Value;

                foreach (long gitId in model.GitIds)
                {
                    //データの存在チェック
                    git = await gitRepository.GetByIdAsync(gitId);

                    if (git == null)
                    {
                        return(JsonNotFound($"The selected git ID {gitId} is not found."));
                    }
                    await gitRepository.AttachGitToTenantAsync(tenant, git, true);
                }
            }
            Registry registry = null;

            if (model.RegistryIds != null && model.RegistryIds.Count() > 0)
            {
                //デフォルトレジストリの設定(無ければ一個目)
                tenant.DefaultRegistryId = model.DefaultRegistryId == null?
                                           model.RegistryIds.ElementAt(0) : model.DefaultRegistryId.Value;

                foreach (long registryId in model.RegistryIds)
                {
                    //データの存在チェック
                    registry = await registryRepository.GetByIdAsync(registryId);

                    if (registry == null)
                    {
                        return(JsonNotFound($"The selected registry ID {registryId} is not found."));
                    }
                    await registryRepository.AttachRegistryToTenantAsync(tenant, registry, true);
                }
            }

            //データの存在チェック
            var storage = tenantRepository.GetStorage(model.StorageId.Value);

            if (storage == null)
            {
                return(JsonNotFound($"The selected storage ID {model.StorageId.Value} is not found."));
            }

            //ObjectStorage に バケットを作成する
            bool isCreated = await storageLogic.CreateBucketAsync(tenant, storage);

            if (!isCreated)
            {
                // 既にバケットが存在していたならエラーとする
                return(JsonNotFound($"Can not create because [{tenant.Name}] exists in the NFS server. Please delete it from the NFS server."));
            }

            tenantRepository.AddTenant(tenant);

            //コンテナ管理サービス作業
            //テナントを登録
            var tenantResult = await clusterManagementLogic.RegistTenantAsync(tenant.Name);

            if (tenantResult == false)
            {
                return(JsonError(HttpStatusCode.ServiceUnavailable, "Couldn't create cluster master namespace. Please check the configuration to the connect cluster manager service."));
            }

            // アクセスレベルが "Public" のノードにアサイン
            var nodes = nodeRepository.GetAll().Where(n => n.AccessLevel == NodeAccessLevel.Public);

            foreach (Node node in nodes)
            {
                await clusterManagementLogic.UpdateTenantEnabledLabelAsync(node.Name, tenant.Name, true);
            }

            //初期データ投入処理
            commonDiLogic.InitializeTenant(tenant);

            unitOfWork.Commit();
            tenantRepository.Refresh();
            roleRepository.Refresh();

            var result = new IndexOutputModel(tenant);

            return(JsonOK(result));
        }