예제 #1
0
        public async Task <IActionResult> Edit(long?id, [FromBody] CreateInputModel model) //EditとCreateで項目が同じなので、入力モデルを使いまわし
        {
            //データの入力チェック
            if (!ModelState.IsValid || !id.HasValue)
            {
                return(JsonBadRequest("Invalid inputs."));
            }
            //データの存在チェック
            var storage = await tenantRepository.GetStorageForUpdateAsync(id.Value);

            if (storage == null)
            {
                return(JsonNotFound($"Storage ID {id.Value} is not found."));
            }

            storage.Name          = model.Name;
            storage.ServerAddress = model.ServerUrl;
            storage.AccessKey     = model.AccessKey;
            storage.SecretKey     = model.SecretKey;
            storage.NfsServer     = model.NfsServer;
            storage.NfsRoot       = model.NfsRoot;

            tenantRepository.UpdateStorage(storage);

            // このStorageを登録しているテナントがいた場合、バケットを作成する
            var tenants = tenantRepository.GetAllTenants().Where(t => t.StorageId == id.Value);

            foreach (Tenant tenant in tenants)
            {
                //バケットを作成する
                await storageLogic.CreateBucketAsync(tenant, storage);
            }

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

            return(JsonOK(new IndexOutputModel(storage)));
        }
예제 #2
0
        /// <summary>
        /// DB のテナント・レジストリ・ノード情報を Cluster(k8s)・ObjectStorage へ同期させるメソッドです。
        /// </summary>
        protected override void DoWork(object state, int doWorkCount)
        {
            LogInfo($"DB のテナント・レジストリ・ノード情報を Cluster(k8s) へ同期させます。");
            try
            {
                // DB のテナント情報に対応する名前空間、ロール、クォータを Cluster(k8s) へ同期
                var tenants = tenantRepository.GetAllTenants();
                foreach (Tenant tenant in tenants)
                {
                    // 名前空間とロールを同期
                    bool ret = clusterManagementService.RegistTenantAsync(tenant.Name).Result;
                    if (ret)
                    {
                        LogDebug($"DB のテナント \"{tenant.Name}\" に対応する名前空間とロールを Cluster(k8s) へ同期させました。");
                    }
                    else
                    {
                        LogError($"DB のテナント \"{tenant.Name}\" に対応する名前空間とロールを Cluster(k8s) へ同期させる処理に失敗しました。");
                    }
                    // クォータを同期
                    int cpu    = tenant.LimitCpu == null ? 0 : tenant.LimitCpu.Value;
                    int memory = tenant.LimitMemory == null ? 0 : tenant.LimitMemory.Value;
                    int gpu    = tenant.LimitGpu == null ? 0 : tenant.LimitGpu.Value;
                    ret = clusterManagementService.SetQuotaAsync(tenant.Name, cpu, memory, gpu).Result;
                    string quotaInfo = $"cpu={cpu} memory={memory} gpu={gpu}";
                    if (ret)
                    {
                        LogDebug($"DB のテナント \"{tenant.Name}\" に対応するクォータ [{quotaInfo}] を Cluster(k8s) へ同期させました。");
                    }
                    if (!ret)
                    {
                        LogError($"DB のテナント \"{tenant.Name}\" に対応するクォータ [{quotaInfo}] を Cluster(k8s) へ同期させる処理に失敗しました。");
                    }
                    // テナントの古い ClusterToken を削除
                    tenantRepository.DeleteClusterToken(tenant.Id);

                    // ObjectStorage への同期処理を行う
                    if (tenant.Storage != null)
                    {
                        // ObjectStorage に バケットを作成する
                        storageLogic.CreateBucketAsync(tenant, tenant.Storage);
                    }
                }
                // テナントの古い ClusterToken 削除を確定する
                unitOfWork.Commit();

                // DB のレジストリ情報(UserTenantRegistryMap)に対応するシークレットを Cluster(k8s) へ同期
                var userTenantRegistryMaps = registryRepository.GetUserTenantRegistryMapAll();
                foreach (UserTenantRegistryMap userTenantRegistryMap in userTenantRegistryMaps)
                {
                    // ログ情報
                    string registryPasswd = string.IsNullOrEmpty(userTenantRegistryMap.RegistryPassword) ? "無し" : "有り";
                    string mapInfo        = $"UserTenantRegistryMapId={userTenantRegistryMap.Id}, UserId={userTenantRegistryMap.UserId}, " +
                                            $"RegistryPassword={registryPasswd}, TenantRegistryMapId={userTenantRegistryMap.TenantRegistryMapId}, " +
                                            $"TernantId={userTenantRegistryMap.TenantRegistryMap.TenantId}, " +
                                            $"RegistryId={userTenantRegistryMap.TenantRegistryMap.RegistryId}";
                    Registry registry = userTenantRegistryMap.Registry;
                    if (registry == null)
                    {
                        // Registry が null というのはあり得ないが、取り敢えずはチェック
                        LogDebug($"DB のレジストリ情報 [{mapInfo}] に対応する Registry が存在しません。");
                        continue;
                    }
                    mapInfo += $", RegistryServiceType={registry.ServiceType}";

                    // テナントの取得
                    Tenant tenant = tenantRepository.Get(userTenantRegistryMap.TenantRegistryMap.TenantId);
                    if (tenant == null)
                    {
                        // テナントが null というのはあり得ないが、取り敢えずはチェック
                        LogError($"DB のレジストリ情報 [{ mapInfo}] に対応するテナントが存在しません。");
                        continue;
                    }
                    // RegistryService の取得
                    IRegistryService registryService = GetRegistryService(registry);
                    if (registryService == null)
                    {
                        LogError($"DB のレジストリ情報 [{mapInfo}] に対応する RegistryService を取得できませんでした。");
                        continue;
                    }

                    // パスワードが空なら同期させない
                    if (string.IsNullOrEmpty(userTenantRegistryMap.RegistryPassword))
                    {
                        LogDebug($"DB のレジストリ情報 [{mapInfo}] のレジストリ・パスワードが空なので Cluster(k8s) への同期は行いません。");
                        continue;
                    }

                    // Docker コンフィグの取得
                    string dockerCfg = registryService.GetDockerCfgAuthString(userTenantRegistryMap);
                    if (dockerCfg == null)
                    {
                        LogError($"DB のレジストリ情報 [{ mapInfo}] に同期させる Docker コンフィグを取得できませんでした。");
                        continue;
                    }
                    // シークレット情報の生成
                    var inModel = new RegistRegistryTokenInputModel()
                    {
                        TenantName          = tenant.Name,
                        RegistryTokenKey    = userTenantRegistryMap.RegistryTokenKey,
                        DockerCfgAuthString = dockerCfg,
                        Url = userTenantRegistryMap.Registry.RegistryUrl
                    };

                    // Cluster(k8s) にシークレットを同期
                    bool ret = clusterManagementService.RegistRegistryTokenyAsync(inModel).Result;
                    if (ret)
                    {
                        LogDebug($"DB のレジストリ情報 [{mapInfo}] に対応するシークレットを Cluster(k8s) へ同期させました。");
                    }
                    else
                    {
                        LogError($"DB のレジストリ情報 [{mapInfo}] に対応するシークレットを Cluster(k8s) へ同期させる処理に失敗しました。");
                    }
                }

                // DB のノード情報に対応するパーティションを Cluster(k8s) へ同期
                var nodes = nodeRepository.GetAll();
                foreach (Node node in nodes)
                {
                    bool ret = clusterManagementLogic.UpdatePartitionLabelAsync(node.Name, node.Partition).Result;
                    if (!ret)
                    {
                        LogError($"DB のノード情報 [{node.Name}] に対応するパーティションを Cluster(k8s) へ同期させる処理に失敗しました。");
                        continue;
                    }
                    ret = clusterManagementLogic.UpdateTensorBoardEnabledLabelAsync(node.Name, node.TensorBoardEnabled).Result;
                    if (ret)
                    {
                        LogDebug($"DB のノード情報 [{node.Name}] に対応する TensorBoard 可否設定を Cluster(k8s) へ同期させました。");
                    }
                    else
                    {
                        LogError($"DB のノード情報 [{node.Name}] に対応する TensorBoard 可否設定を Cluster(k8s) へ同期させる処理に失敗しました。");
                    }
                    ret = clusterManagementLogic.UpdateNotebookEnabledLabelAsync(node.Name, node.NotebookEnabled).Result;
                    if (ret)
                    {
                        LogDebug($"DB のノード情報 [{node.Name}] に対応する Notebook 可否設定を Cluster(k8s) へ同期させました。");
                    }
                    else
                    {
                        LogError($"DB のノード情報 [{node.Name}] に対応する Notebook 可否設定を Cluster(k8s) へ同期させる処理に失敗しました。");
                    }

                    // KQI管理者用名前空間の実行可否設定を Cluster(k8s) へ同期する
                    ret = SyncKqiAdminEnabledLabel(node).Result;
                    if (ret)
                    {
                        LogDebug($"DB のノード [{node.Name}] に対応する KQI管理者用名前空間 [{containerManageOptions.KqiAdminNamespace}] のアクセス可否設定を Cluster(k8s) へ同期させました。");
                    }
                    else
                    {
                        LogError($"DB のノード [{node.Name}] に対応する KQI管理者用名前空間 [{containerManageOptions.KqiAdminNamespace}] のアクセス可否設定を Cluster(k8s) へ同期させる処理に失敗しました。");
                    }
                    // テナントの実行可否設定を Cluster(k8s) へ同期する
                    int failedCount = SyncTenantEnabledLabel(node).Result;
                    if (failedCount == 0)
                    {
                        LogInfo($"DB のノード [{node.Name}] に対するテナントの実行可否設定情報を Cluster(k8s) へ同期させる処理は終了しました。");
                    }
                    else
                    {
                        LogError($"DB のノード [{node.Name}] に対するテナントの実行可否設定情報 {failedCount} 件の Cluster(k8s) へ同期させる処理に失敗しました。");
                    }
                }
                LogInfo("DB のテナント・レジストリ・ノード情報を Cluster(k8s) へ同期させる処理は終了しました。");
            }
            catch (Exception e)
            {
                //例外をキャッチしたが ERROR ログを出力して処理を継続
                LogError($"DB のテナント・レジストリ・ノード情報を Cluster(k8s) へ同期させる時に例外をキャッチしましたが web-api は継続処理します。 例外メッセージ=\"{e.Message}\"");
            }
        }
예제 #3
0
        public async Task <IActionResult> CreateForTenant([FromBody] CreateInputModel model)
        {
            //データの入力チェック
            if (!ModelState.IsValid)
            {
                return(JsonBadRequest("Invalid inputs."));
            }

            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 Gity 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
            };

            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."));
            }
            //初期データ投入処理
            commonDiLogic.InitializeTenant(tenant);

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

            var result = new IndexOutputModel(tenant);

            return(JsonOK(result));
        }