Exemplo n.º 1
0
        public async Task <IActionResult> LoginAsync([FromBody] LoginInputModel model, [FromServices] ITenantRepository tenantRepository)
        {
            //入力値チェック
            if (!ModelState.IsValid)
            {
                return(JsonBadRequest("Invalid inputs."));
            }

            // ユーザ名の前後の空白は除去
            model.UserName = model.UserName.Trim();

            //ユーザ情報からクレームを取得
            Result <List <Claim>, string> signInResult = await loginLogic.SignInAsync(model.UserName, model.Password, model.TenantId);

            if (!signInResult.IsSuccess)
            {
                //失敗
                return(JsonBadRequest(signInResult.Error));
            }

            // 結果からトークンを作成
            var token = loginLogic.GenerateToken(signInResult.Value, model.ExpiresIn);

            //Tenant name must not be null. Hence "Single" is intended use here.
            // string tenantName = signInResult.Value.Single(c => c.Type == ApplicationConst.ClaimTypeTenantName).Value;
            long tenantId = long.Parse(signInResult.Value.FirstOrDefault(c => c.Type == ClaimTypes.GroupSid).Value);

            //テナント取得(ここまでに存在チェックは行われているハズ)
            var tenant = tenantRepository.Get(tenantId);

            var result = new LoginOutputModel()
            {
                Token      = token.AccessToken,
                UserName   = model.UserName,
                TenantId   = tenantId,
                TenantName = tenant.DisplayName,
                ExpiresIn  = token.ExpiresIn
            };

            return(JsonOK(result));
        }
        /// <summary>
        /// 新規に前処理用コンテナを作成する。
        /// </summary>
        /// <param name="preprocessHistory">対象の前処理履歴</param>
        /// <returns>作成したコンテナのステータス</returns>
        public async Task <Result <ContainerInfo, string> > RunPreprocessingContainerAsync(PreprocessHistory preprocessHistory)
        {
            string token = await GetUserAccessTokenAsync();

            if (token == null)
            {
                //トークンがない場合、結果はnull
                return(Result <ContainerInfo, string> .CreateErrorResult("Access denied. Failed to get token to access the cluster management system."));
            }

            var registryMap = registryLogic.GetCurrentRegistryMap(preprocessHistory.Preprocess.ContainerRegistryId.Value);

            string tags = "-t " + preprocessHistory.Preprocess.Name; //生成されるデータのタグを設定

            foreach (var tag in preprocessHistory.InputData.Tags)
            {
                tags += " -t " + tag;
            }

            //コンテナを起動するために必要な設定値をインスタンス化
            var inputModel = new RunContainerInputModel()
            {
                ID              = preprocessHistory.Id,
                TenantName      = TenantName,
                LoginUser       = CurrentUserInfo.Alias, //アカウントはエイリアスから指定
                Name            = preprocessHistory.Name,
                ContainerImage  = registryMap.Registry.GetImagePath(preprocessHistory.Preprocess.ContainerImage, preprocessHistory.Preprocess.ContainerTag),
                ScriptType      = "preproc", // 実行スクリプトの指定
                Cpu             = preprocessHistory.Cpu.Value,
                Memory          = preprocessHistory.Memory.Value,
                Gpu             = preprocessHistory.Gpu.Value,
                KqiToken        = loginLogic.GenerateToken().AccessToken,
                KqiImage        = "kamonohashi/cli:" + versionLogic.GetVersion(),
                LogPath         = "/kqi/attach/preproc_stdout_stderr_${PREPROCESSING_ID}_${DATA_ID}.log", // 前処理履歴IDは現状ユーザーに見えないので前処理+データIDをつける
                NfsVolumeMounts = new List <NfsVolumeMountModel>()
                {
                    // 添付ファイルを保存するディレクトリ
                    // 前処理結果ディレクトリを前処理完了時にzip圧縮して添付するために使用
                    new NfsVolumeMountModel()
                    {
                        Name       = "nfs-preproc-attach",
                        MountPath  = "/kqi/attach",
                        SubPath    = preprocessHistory.Id.ToString(),
                        Server     = CurrentUserInfo.SelectedTenant.Storage.NfsServer,
                        ServerPath = CurrentUserInfo.SelectedTenant.PreprocContainerAttachedNfsPath,
                        ReadOnly   = false
                    }
                },
                ContainerSharedPath = new Dictionary <string, string>()
                {
                    { "tmp", "/kqi/tmp/" },
                    { "input", "/kqi/input/" },
                    { "git", "/kqi/git/" },
                    { "output", "/kqi/output/" }
                },
                EnvList = new Dictionary <string, string>()
                {
                    { "DATA_ID", preprocessHistory.InputDataId.ToString() },
                    { "DATA_NAME", preprocessHistory.InputData.Name },
                    { "PREPROCESSING_ID", preprocessHistory.PreprocessId.ToString() },
                    { "TAGS", tags },
                    { "COMMIT_ID", preprocessHistory.Preprocess.RepositoryCommitId },
                    { "KQI_SERVER", containerOptions.WebServerUrl },
                    { "KQI_TOKEN", loginLogic.GenerateToken().AccessToken },
                    { "http_proxy", containerOptions.Proxy },
                    { "https_proxy", containerOptions.Proxy },
                    { "no_proxy", containerOptions.NoProxy },
                    { "HTTP_PROXY", containerOptions.Proxy },
                    { "HTTPS_PROXY", containerOptions.Proxy },
                    { "NO_PROXY", containerOptions.NoProxy },
                    { "COLUMNS", containerOptions.ShellColumns },
                    { "PYTHONUNBUFFERED", "true" }, // python実行時の標準出力・エラーのバッファリングをなくす
                    { "LC_ALL", "C.UTF-8" },        // python実行時のエラー回避
                    { "LANG", "C.UTF-8" }  // python実行時のエラー回避
                },
                EntryPoint = preprocessHistory.Preprocess.EntryPoint,

                ClusterManagerToken = token,
                RegistryTokenName   = registryMap.RegistryTokenKey,
                IsNodePort          = true
            };

            // 前処理はGitの未指定も許可するため、その判定
            if (preprocessHistory.Preprocess.RepositoryGitId != null)
            {
                long gitId = preprocessHistory.Preprocess.RepositoryGitId == -1 ?
                             CurrentUserInfo.SelectedTenant.DefaultGitId.Value : preprocessHistory.Preprocess.RepositoryGitId.Value;

                var gitEndpoint = gitLogic.GetPullUrl(preprocessHistory.Preprocess.RepositoryGitId.Value, preprocessHistory.Preprocess.RepositoryName, preprocessHistory.Preprocess.RepositoryOwner);
                if (gitEndpoint != null)
                {
                    inputModel.EnvList.Add("MODEL_REPOSITORY", gitEndpoint.FullUrl);
                    inputModel.EnvList.Add("MODEL_REPOSITORY_URL", gitEndpoint.Url);
                    inputModel.EnvList.Add("MODEL_REPOSITORY_TOKEN", gitEndpoint.Token);
                }
                else
                {
                    //Git情報は必須にしているので、無ければエラー
                    return(Result <ContainerInfo, string> .CreateErrorResult("Git credential is not valid."));
                }
            }

            // ユーザの任意追加環境変数をマージする
            AddUserEnvToInputModel(preprocessHistory.OptionDic, inputModel);

            //使用できるノードを取得し、制約に追加
            inputModel.ConstraintList = new Dictionary <string, List <string> >()
            {
                { containerOptions.ContainerLabelHostName, GetAccessibleNode() }
            };

            if (string.IsNullOrEmpty(preprocessHistory.Partition) == false)
            {
                // パーティション指定があれば追加
                inputModel.ConstraintList.Add(containerOptions.ContainerLabelPartition, new List <string> {
                    preprocessHistory.Partition
                });
            }

            var outModel = await clusterManagementService.RunContainerAsync(inputModel);

            if (outModel.IsSuccess == false)
            {
                return(Result <ContainerInfo, string> .CreateErrorResult(outModel.Error));
            }
            return(Result <ContainerInfo, string> .CreateResult(new ContainerInfo()
            {
                Name = outModel.Value.Name,
                Status = outModel.Value.Status,
                Host = outModel.Value.Host,
                Configuration = outModel.Value.Configuration
            }));
        }