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))); }
/// <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}\""); } }
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)); }