コード例 #1
0
        private async Task <HttpResponseMessage> CreateOrUpdateHelper(string name, Task <FunctionEnvelope> functionEnvelopeBuilder)
        {
            if (!FunctionNameValidationRegex.IsMatch(name))
            {
                // it returns the same error object if the PUT request does not come from Arm
                return(ArmUtils.CreateErrorResponse(Request, HttpStatusCode.BadRequest, new ArgumentException($"{name} is not a valid function name")));
            }

            var tracer = _traceFactory.GetTracer();

            using (tracer.Step($"FunctionsController.CreateOrUpdate({name})"))
            {
                var  functionEnvelope = await functionEnvelopeBuilder;
                bool configChanged    = false;
                functionEnvelope = await _manager.CreateOrUpdateAsync(name, functionEnvelope, () => { configChanged = true; });

                AddFunctionAppIdToEnvelope(functionEnvelope);

                if (configChanged)
                {
                    // Fire and forget SyncTrigger request.
                    FireSyncTriggers(tracer);
                }

                return(Request.CreateResponse(HttpStatusCode.Created, ArmUtils.AddEnvelopeOnArmRequest(functionEnvelope, Request)));
            }
        }
コード例 #2
0
        public async Task <HttpResponseMessage> GetSecrets(string name)
        {
            // "name".json will be created as function keys, (runtime will always have lowercase "name")
            // kudu REST api does not care, "name" can be camelcase (ex: function portal)
            // windows file system is case insensitive, but this might not work in linux
            var tracer = _traceFactory.GetTracer();

            using (tracer.Step($"FunctionsController.GetSecrets({name})"))
            {
                try
                {
                    return(Request.CreateResponse(HttpStatusCode.OK, await _manager.GetFunctionSecretsAsync(name)));
                }
                catch (InvalidOperationException ex)
                {
                    return(ArmUtils.CreateErrorResponse(Request, HttpStatusCode.Conflict, ex));
                }
            }
        }
コード例 #3
0
        public override void OnException(HttpActionExecutedContext context)
        {
            var statusCode = HttpStatusCode.InternalServerError;

            if (context.Exception is FileNotFoundException)
            {
                statusCode = HttpStatusCode.NotFound;
            }
            else if (context.Exception is InvalidOperationException)
            {
                statusCode = HttpStatusCode.Conflict;
            }
            else if (context.Exception is ArgumentException)
            {
                statusCode = HttpStatusCode.BadRequest;
            }

            context.Response = ArmUtils.CreateErrorResponse(context.Request, statusCode, context.Exception);
        }
コード例 #4
0
        public async Task <HttpResponseMessage> SyncTriggers()
        {
            var tracer = _traceFactory.GetTracer();

            using (tracer.Step("FunctionController.SyncTriggers"))
            {
                try
                {
                    await _manager.SyncTriggers();

                    return(Request.CreateResponse(HttpStatusCode.OK));
                }
                catch (Exception ex)
                {
                    tracer.TraceError(ex);

                    return(ArmUtils.CreateErrorResponse(Request, HttpStatusCode.BadRequest, ex));
                }
            }
        }
コード例 #5
0
        private async Task <HttpResponseMessage> PushDeployAsync(ZipDeploymentInfo deploymentInfo, bool isAsync)
        {
            var content       = Request.Content;
            var isRequestJSON = content.Headers?.ContentType?.MediaType?.Equals("application/json", StringComparison.OrdinalIgnoreCase);

            if (isRequestJSON == true)
            {
                try
                {
                    var requestObject = await Request.Content.ReadAsAsync <JObject>();

                    deploymentInfo.ZipURL = ArmUtils.IsArmRequest(Request) ? GetZipURLFromARMJSON(requestObject) : GetZipURLFromJSON(requestObject);
                }
                catch (Exception ex)
                {
                    return(ArmUtils.CreateErrorResponse(Request, HttpStatusCode.BadRequest, ex));
                }
            }
            else
            {
                if (_settings.RunFromLocalZip())
                {
                    await WriteSitePackageZip(deploymentInfo, _tracer, Request.Content);
                }
                else
                {
                    var zipFileName = Path.ChangeExtension(Path.GetRandomFileName(), "zip");
                    var zipFilePath = Path.Combine(_environment.ZipTempPath, zipFileName);

                    using (_tracer.Step("Saving request content to {0}", zipFilePath))
                    {
                        await content.CopyToAsync(zipFilePath, _tracer);
                    }

                    deploymentInfo.RepositoryUrl = zipFilePath;
                }
            }

            isAsync = ArmUtils.IsArmRequest(Request) ? true : isAsync;

            var result = await _deploymentManager.FetchDeploy(deploymentInfo, isAsync, UriHelper.GetRequestUri(Request), "HEAD");

            var response = Request.CreateResponse();

            switch (result)
            {
            case FetchDeploymentRequestResult.RunningAynschronously:
                if (ArmUtils.IsArmRequest(Request))
                {
                    DeployResult deployResult = new DeployResult();
                    response = Request.CreateResponse(HttpStatusCode.Accepted, ArmUtils.AddEnvelopeOnArmRequest(deployResult, Request));
                    string statusURL = GetStatusUrl();
                    // Should not happen: If we couldn't make the URL, there must have been an error in the request
                    if (string.IsNullOrEmpty(statusURL))
                    {
                        var badResponse = Request.CreateResponse();
                        badResponse.StatusCode = HttpStatusCode.BadRequest;
                        return(badResponse);
                    }
                    // latest deployment keyword reserved to poll till deployment done
                    response.Headers.Location = new Uri(statusURL +
                                                        String.Format("/deployments/{0}?api-version=2018-02-01&deployer={1}&time={2}", Constants.LatestDeployment, deploymentInfo.Deployer, DateTime.UtcNow.ToString("yyy-MM-dd_HH-mm-ssZ")));
                }
                else if (isAsync)
                {
                    // latest deployment keyword reserved to poll till deployment done
                    response.Headers.Location = new Uri(UriHelper.GetRequestUri(Request),
                                                        String.Format("/api/deployments/{0}?deployer={1}&time={2}", Constants.LatestDeployment, deploymentInfo.Deployer, DateTime.UtcNow.ToString("yyy-MM-dd_HH-mm-ssZ")));
                }
                response.StatusCode = HttpStatusCode.Accepted;
                break;

            case FetchDeploymentRequestResult.ForbiddenScmDisabled:
                // Should never hit this for zip push deploy
                response.StatusCode = HttpStatusCode.Forbidden;
                _tracer.Trace("Scm is not enabled, reject all requests.");
                break;

            case FetchDeploymentRequestResult.ConflictAutoSwapOngoing:
                response.StatusCode = HttpStatusCode.Conflict;
                response.Content    = new StringContent(Resources.Error_AutoSwapDeploymentOngoing);
                break;

            case FetchDeploymentRequestResult.Pending:
                // Shouldn't happen here, as we disallow deferral for this use case
                response.StatusCode = HttpStatusCode.Accepted;
                break;

            case FetchDeploymentRequestResult.RanSynchronously:
                response.StatusCode = HttpStatusCode.OK;
                break;

            case FetchDeploymentRequestResult.ConflictDeploymentInProgress:
                response.StatusCode = HttpStatusCode.Conflict;
                response.Content    = new StringContent(Resources.Error_DeploymentInProgress);
                break;

            case FetchDeploymentRequestResult.ConflictRunFromRemoteZipConfigured:
                response.StatusCode = HttpStatusCode.Conflict;
                response.Content    = new StringContent(Resources.Error_RunFromRemoteZipConfigured);
                break;

            default:
                response.StatusCode = HttpStatusCode.BadRequest;
                break;
            }

            return(response);
        }
コード例 #6
0
        public async Task <HttpResponseMessage> OneDeploy(
            [FromUri] string type      = null,
            [FromUri] bool async       = false,
            [FromUri] string path      = null,
            [FromUri] bool?restart     = true,
            [FromUri] bool?clean       = null,
            [FromUri] bool ignoreStack = false
            )
        {
            using (_tracer.Step(Constants.OneDeploy))
            {
                JObject requestObject = null;

                try
                {
                    if (ArmUtils.IsArmRequest(Request))
                    {
                        requestObject = await Request.Content.ReadAsAsync <JObject>();

                        var armProperties = requestObject.Value <JObject>("properties");

                        type        = armProperties.Value <string>("type");
                        async       = armProperties.Value <bool>("async");
                        path        = armProperties.Value <string>("path");
                        restart     = armProperties.Value <bool?>("restart");
                        clean       = armProperties.Value <bool?>("clean");
                        ignoreStack = armProperties.Value <bool>("ignorestack");
                    }
                }
                catch (Exception ex)
                {
                    return(ArmUtils.CreateErrorResponse(Request, HttpStatusCode.BadRequest, ex));
                }

                //
                // 'async' is not a CSharp-ish variable name. And although it is a valid variable name, some
                // IDEs confuse it to be the 'async' keyword in C#.
                // On the other hand, isAsync is not a good name for the query-parameter.
                // So we use 'async' as the query parameter, and then assign it to the C# variable 'isAsync'
                // at the earliest. Hereon, we use just 'isAsync'.
                //
                bool isAsync = async;

                ArtifactType artifactType = ArtifactType.Unknown;
                try
                {
                    artifactType = (ArtifactType)Enum.Parse(typeof(ArtifactType), type, ignoreCase: true);
                }
                catch
                {
                    return(StatusCode400($"type='{type}' not recognized"));
                }

                var deploymentInfo = new ArtifactDeploymentInfo(_environment, _traceFactory)
                {
                    AllowDeploymentWhileScmDisabled = true,
                    Deployer                = Constants.OneDeploy,
                    IsContinuous            = false,
                    AllowDeferredDeployment = false,
                    IsReusable              = false,
                    TargetRootPath          = _environment.WebRootPath,
                    TargetChangeset         = DeploymentManager.CreateTemporaryChangeSet(message: Constants.OneDeploy),
                    CommitId                = null,
                    RepositoryType          = RepositoryType.None,
                    Fetch = OneDeployFetch,
                    DoFullBuildByDefault = false,
                    Message                = Constants.OneDeploy,
                    WatchedFileEnabled     = false,
                    CleanupTargetDirectory = clean.GetValueOrDefault(false),
                    RestartAllowed         = restart.GetValueOrDefault(true),
                };

                string error;
                switch (artifactType)
                {
                case ArtifactType.War:
                    if (!OneDeployHelper.EnsureValidStack(OneDeployHelper.Tomcat, ignoreStack, out error))
                    {
                        return(StatusCode400(error));
                    }

                    // If path is non-null, we assume this is a legacy war deployment, i.e. equivalent of wardeploy
                    if (!string.IsNullOrWhiteSpace(path))
                    {
                        //
                        // For legacy war deployments, the only path allowed is webapps/<directory-name>
                        //

                        if (!OneDeployHelper.IsLegacyWarPathValid(path))
                        {
                            return(StatusCode400($"path='{path}'. Only allowed path when type={artifactType} is webapps/<directory-name>. Example: path=webapps/ROOT"));
                        }

                        deploymentInfo.TargetRootPath = Path.Combine(_environment.WebRootPath, path);
                        deploymentInfo.Fetch          = LocalZipHandler;

                        // Legacy war deployment is equivalent to wardeploy
                        // So always do clean deploy.
                        deploymentInfo.CleanupTargetDirectory = true;
                        artifactType = ArtifactType.Zip;
                    }
                    else
                    {
                        // For type=war, if no path is specified, the target file is app.war
                        deploymentInfo.TargetFileName = "app.war";
                    }

                    break;

                case ArtifactType.Jar:
                    if (!OneDeployHelper.EnsureValidStack(OneDeployHelper.JavaSE, ignoreStack, out error))
                    {
                        return(StatusCode400(error));
                    }

                    deploymentInfo.TargetFileName = "app.jar";
                    break;

                case ArtifactType.Ear:
                    if (!OneDeployHelper.EnsureValidStack(OneDeployHelper.JBossEap, ignoreStack, out error))
                    {
                        return(StatusCode400(error));
                    }

                    deploymentInfo.TargetFileName = "app.ear";
                    break;

                case ArtifactType.Lib:
                    if (!OneDeployHelper.EnsureValidPath(artifactType, path, out error))
                    {
                        return(StatusCode400(error));
                    }

                    deploymentInfo.TargetRootPath = OneDeployHelper.GetLibsDirectoryAbsolutePath(_environment);
                    OneDeployHelper.SetTargetSubDirectoyAndFileNameFromPath(deploymentInfo, path);
                    break;

                case ArtifactType.Startup:
                    deploymentInfo.TargetRootPath = OneDeployHelper.GetScriptsDirectoryAbsolutePath(_environment);
                    OneDeployHelper.SetTargetSubDirectoyAndFileNameFromPath(deploymentInfo, OneDeployHelper.GetStartupFileName());
                    break;

                case ArtifactType.Script:
                    if (!OneDeployHelper.EnsureValidPath(artifactType, path, out error))
                    {
                        return(StatusCode400(error));
                    }

                    deploymentInfo.TargetRootPath = OneDeployHelper.GetScriptsDirectoryAbsolutePath(_environment);
                    OneDeployHelper.SetTargetSubDirectoyAndFileNameFromPath(deploymentInfo, path);

                    break;

                case ArtifactType.Static:
                    if (!OneDeployHelper.EnsureValidPath(artifactType, path, out error))
                    {
                        return(StatusCode400(error));
                    }

                    OneDeployHelper.SetTargetSubDirectoyAndFileNameFromPath(deploymentInfo, path);

                    break;

                case ArtifactType.Zip:
                    deploymentInfo.Fetch = LocalZipHandler;
                    deploymentInfo.TargetSubDirectoryRelativePath = path;

                    // Deployments for type=zip default to clean=true
                    deploymentInfo.CleanupTargetDirectory = clean.GetValueOrDefault(true);

                    break;

                default:
                    return(StatusCode400($"Artifact type '{artifactType}' not supported"));
                }

                return(await PushDeployAsync(deploymentInfo, isAsync, requestObject, artifactType));
            }
        }
コード例 #7
0
        public async Task <HttpResponseMessage> OneDeploy(
            [FromUri] string type  = null,
            [FromUri] bool async   = false,
            [FromUri] string path  = null,
            [FromUri] bool restart = true,
            [FromUri] string stack = null
            )
        {
            using (_tracer.Step("OnePushDeploy"))
            {
                JObject requestObject = null;

                try
                {
                    if (ArmUtils.IsArmRequest(Request))
                    {
                        requestObject = await Request.Content.ReadAsAsync <JObject>();

                        var armProperties = requestObject.Value <JObject>("properties");
                        type    = armProperties.Value <string>("type");
                        async   = armProperties.Value <bool>("async");
                        path    = armProperties.Value <string>("path");
                        restart = armProperties.Value <bool>("restart");
                        stack   = armProperties.Value <string>("stack");
                    }
                }
                catch (Exception ex)
                {
                    return(ArmUtils.CreateErrorResponse(Request, HttpStatusCode.BadRequest, ex));
                }

                //
                // 'async' is not a CSharp-ish variable name. And although it is a valid variable name, some
                // IDEs confuse it to be the 'async' keyword in C#.
                // On the other hand, isAsync is not a good name for the query-parameter.
                // So we use 'async' as the query parameter, and then assign it to the C# variable 'isAsync'
                // at the earliest. Hereon, we use just 'isAsync'.
                //
                bool isAsync = async;

                var deploymentInfo = new ArtifactDeploymentInfo(_environment, _traceFactory)
                {
                    AllowDeploymentWhileScmDisabled = true,
                    Deployer                = Constants.OneDeploy,
                    IsContinuous            = false,
                    AllowDeferredDeployment = false,
                    IsReusable              = false,
                    TargetChangeset         = DeploymentManager.CreateTemporaryChangeSet(message: "OneDeploy"),
                    CommitId                = null,
                    RepositoryType          = RepositoryType.None,
                    Fetch = OneDeployFetch,
                    DoFullBuildByDefault = false,
                    Message            = "OneDeploy",
                    WatchedFileEnabled = false,
                    RestartAllowed     = restart,
                };

                string websiteStack = !string.IsNullOrWhiteSpace(stack) ? stack : _settings.GetValue(Constants.StackEnvVarName);

                ArtifactType artifactType = ArtifactType.Invalid;
                try
                {
                    artifactType = (ArtifactType)Enum.Parse(typeof(ArtifactType), type, ignoreCase: true);
                }
                catch
                {
                    return(Request.CreateResponse(HttpStatusCode.BadRequest, $"type='{type}' not recognized"));
                }

                switch (artifactType)
                {
                case ArtifactType.War:
                    if (!string.Equals(websiteStack, Constants.Tomcat, StringComparison.OrdinalIgnoreCase))
                    {
                        return(Request.CreateResponse(HttpStatusCode.BadRequest, $"WAR files cannot be deployed to stack='{websiteStack}'. Expected stack='TOMCAT'"));
                    }

                    // Support for legacy war deployments
                    // Sets TargetDirectoryPath then deploys the War file as a Zip so it can be extracted
                    // then deployed
                    if (!string.IsNullOrWhiteSpace(path))
                    {
                        //
                        // For legacy war deployments, the only path allowed is site/wwwroot/webapps/<directory-name>
                        //

                        var segments = path.Split('/');
                        if (segments.Length != 4 || !path.StartsWith("site/wwwroot/webapps/") || string.IsNullOrWhiteSpace(segments[3]))
                        {
                            return(Request.CreateResponse(HttpStatusCode.BadRequest, $"path='{path}'. Only allowed path when type={artifactType} is site/wwwroot/webapps/<directory-name>. Example: path=site/wwwroot/webapps/ROOT"));
                        }

                        deploymentInfo.TargetDirectoryPath = Path.Combine(_environment.RootPath, path);
                        deploymentInfo.Fetch = LocalZipHandler;
                        deploymentInfo.CleanupTargetDirectory = true;
                        artifactType = ArtifactType.Zip;
                    }
                    else
                    {
                        // For type=war, the target file is app.war
                        // As we want app.war to be deployed to wwwroot, no need to configure TargetDirectoryPath
                        deploymentInfo.TargetFileName = "app.war";
                    }

                    break;

                case ArtifactType.Jar:
                    if (!string.Equals(websiteStack, Constants.JavaSE, StringComparison.OrdinalIgnoreCase))
                    {
                        return(Request.CreateResponse(HttpStatusCode.BadRequest, $"JAR files cannot be deployed to stack='{websiteStack}'. Expected stack='JAVASE'"));
                    }

                    deploymentInfo.TargetFileName = "app.jar";

                    break;

                case ArtifactType.Ear:
                    // Currently not supported on Windows but here for future use
                    if (!string.Equals(websiteStack, Constants.JBossEap, StringComparison.OrdinalIgnoreCase))
                    {
                        return(Request.CreateResponse(HttpStatusCode.BadRequest, $"EAR files cannot be deployed to stack='{websiteStack}'. Expected stack='JBOSSEAP'"));
                    }

                    deploymentInfo.TargetFileName = "app.ear";

                    break;

                case ArtifactType.Lib:
                    if (string.IsNullOrWhiteSpace(path))
                    {
                        return(Request.CreateResponse(HttpStatusCode.BadRequest, $"Path must be defined for library deployments"));
                    }

                    SetTargetFromPath(deploymentInfo, path);

                    break;

                case ArtifactType.Startup:
                    SetTargetFromPath(deploymentInfo, GetStartupFileName());

                    break;

                case ArtifactType.Static:
                    if (string.IsNullOrWhiteSpace(path))
                    {
                        return(Request.CreateResponse(HttpStatusCode.BadRequest, $"Path must be defined for static file deployments"));
                    }

                    SetTargetFromPath(deploymentInfo, path);

                    break;

                case ArtifactType.Zip:
                    deploymentInfo.Fetch = LocalZipHandler;

                    break;

                default:
                    return(Request.CreateResponse(HttpStatusCode.BadRequest, $"Artifact type '{artifactType}' not supported"));
                }

                return(await PushDeployAsync(deploymentInfo, isAsync, requestObject, artifactType));
            }
        }
コード例 #8
0
        private async Task <HttpResponseMessage> PushDeployAsync(ArtifactDeploymentInfo deploymentInfo, bool isAsync, JObject requestObject = null, ArtifactType artifactType = ArtifactType.Zip)
        {
            var content       = Request.Content;
            var isRequestJSON = content.Headers?.ContentType?.MediaType?.Equals("application/json", StringComparison.OrdinalIgnoreCase);

            if (isRequestJSON == true)
            {
                try
                {
                    // Read the request body if it hasn't been read already
                    if (requestObject == null)
                    {
                        requestObject = await Request.Content.ReadAsAsync <JObject>();
                    }
                    deploymentInfo.RemoteURL = ArmUtils.IsArmRequest(Request) ? GetArticfactURLFromARMJSON(requestObject) : GetArtifactURLFromJSON(requestObject);
                }
                catch (Exception ex)
                {
                    return(ArmUtils.CreateErrorResponse(Request, HttpStatusCode.BadRequest, ex));
                }
            }
            // For zip artifacts (zipdeploy, wardeploy, onedeploy with type=zip), copy the request body in a temp zip file.
            // It will be extracted to the appropriate directory by the Fetch handler
            else if (artifactType == ArtifactType.Zip)
            {
                await _deploymentLock.LockHttpOperationAsync(async() =>
                {
                    if (_settings.RunFromLocalZip())
                    {
                        await WriteSitePackageZip(deploymentInfo, _tracer, Request.Content);
                    }
                    else
                    {
                        var zipFileName = Path.ChangeExtension(Path.GetRandomFileName(), "zip");
                        var zipFilePath = Path.Combine(_environment.ZipTempPath, zipFileName);

                        using (_tracer.Step("Saving request content to {0}", zipFilePath))
                        {
                            await content.CopyToAsync(zipFilePath, _tracer);
                        }

                        deploymentInfo.RepositoryUrl = zipFilePath;
                    }
                }, "Preparing zip package");
            }
            // Copy the request body to a temp file.
            // It will be moved to the appropriate directory by the Fetch handler
            else if (deploymentInfo.Deployer == Constants.OneDeploy)
            {
                await _deploymentLock.LockHttpOperationAsync(async() =>
                {
                    var artifactTempPath = Path.Combine(_environment.ZipTempPath, deploymentInfo.TargetFileName);
                    using (_tracer.Step("Saving request content to {0}", artifactTempPath))
                    {
                        await content.CopyToAsync(artifactTempPath, _tracer);
                    }

                    deploymentInfo.RepositoryUrl = artifactTempPath;
                }, "Preparing zip package");
            }

            isAsync = ArmUtils.IsArmRequest(Request) ? true : isAsync;

            var result = await _deploymentManager.FetchDeploy(deploymentInfo, isAsync, Request.GetRequestUri(), "HEAD");

            var response = Request.CreateResponse();

            switch (result)
            {
            case FetchDeploymentRequestResult.RunningAynschronously:
                if (ArmUtils.IsArmRequest(Request))
                {
                    DeployResult deployResult = new DeployResult();
                    response = Request.CreateResponse(HttpStatusCode.Accepted, ArmUtils.AddEnvelopeOnArmRequest(deployResult, Request));
                    string statusURL = GetStatusUrl(Request.Headers.Referrer ?? Request.RequestUri);
                    // Should not happen: If we couldn't make the URL, there must have been an error in the request
                    if (string.IsNullOrEmpty(statusURL))
                    {
                        var badResponse = Request.CreateResponse();
                        badResponse.StatusCode = HttpStatusCode.BadRequest;
                        return(badResponse);
                    }
                    // latest deployment keyword reserved to poll till deployment done
                    response.Headers.Location = new Uri(statusURL +
                                                        String.Format("/deployments/{0}?api-version=2018-02-01&deployer={1}&time={2}", Constants.LatestDeployment, deploymentInfo.Deployer, DateTime.UtcNow.ToString("yyy-MM-dd_HH-mm-ssZ")));
                    response.Headers.RetryAfter = new RetryConditionHeaderValue(TimeSpan.FromSeconds(ScmHostingConfigurations.ArmRetryAfterSeconds));
                }
                else if (isAsync)
                {
                    // latest deployment keyword reserved to poll till deployment done
                    response.Headers.Location = new Uri(Request.GetRequestUri(),
                                                        String.Format("/api/deployments/{0}?deployer={1}&time={2}", Constants.LatestDeployment, deploymentInfo.Deployer, DateTime.UtcNow.ToString("yyy-MM-dd_HH-mm-ssZ")));
                    response.Headers.RetryAfter = new RetryConditionHeaderValue(TimeSpan.FromSeconds(ScmHostingConfigurations.ArmRetryAfterSeconds));
                }
                response.StatusCode = HttpStatusCode.Accepted;
                break;

            case FetchDeploymentRequestResult.ForbiddenScmDisabled:
                // Should never hit this for zip push deploy
                response.StatusCode = HttpStatusCode.Forbidden;
                _tracer.Trace("Scm is not enabled, reject all requests.");
                break;

            case FetchDeploymentRequestResult.ConflictAutoSwapOngoing:
                response.StatusCode = HttpStatusCode.Conflict;
                response.Content    = new StringContent(Resources.Error_AutoSwapDeploymentOngoing);
                break;

            case FetchDeploymentRequestResult.Pending:
                // Shouldn't happen here, as we disallow deferral for this use case
                response.StatusCode = HttpStatusCode.Accepted;
                break;

            case FetchDeploymentRequestResult.RanSynchronously:
                response.StatusCode = HttpStatusCode.OK;
                break;

            case FetchDeploymentRequestResult.ConflictDeploymentInProgress:
                response.StatusCode = HttpStatusCode.Conflict;
                response.Content    = new StringContent(Resources.Error_DeploymentInProgress);
                break;

            case FetchDeploymentRequestResult.ConflictRunFromRemoteZipConfigured:
                response.StatusCode = HttpStatusCode.Conflict;
                response.Content    = new StringContent(Resources.Error_RunFromRemoteZipConfigured);
                break;

            default:
                response.StatusCode = HttpStatusCode.BadRequest;
                break;
            }

            return(response);
        }
コード例 #9
0
ファイル: ZipController.cs プロジェクト: Rhayar-dr/kudu-1
        protected override async Task <HttpResponseMessage> CreateDirectoryPutResponse(DirectoryInfoBase info, string localFilePath)
        {
            try
            {
                var     isRequestJSON  = Request.Content.Headers?.ContentType?.MediaType?.Equals("application/json", StringComparison.OrdinalIgnoreCase);
                var     targetPath     = localFilePath;
                var     isArmTemplate  = false;
                JObject requestContent = null;
                Uri     packageUri     = null;
                if (isRequestJSON == true)
                {
                    requestContent = await Request.Content.ReadAsAsync <JObject>();

                    var payload = requestContent;
                    if (ArmUtils.IsArmRequest(Request))
                    {
                        payload       = payload.Value <JObject>("properties");
                        isArmTemplate = ArmUtils.IsAzureResourceManagerUserAgent(Request);
                    }

                    var uri = payload?.Value <string>("packageUri");
                    if (!Uri.TryCreate(uri, UriKind.Absolute, out packageUri))
                    {
                        throw new InvalidOperationException($"Payload contains invalid '{uri}' packageUri property");
                    }

                    var path = payload?.Value <string>("path");
                    if (!string.IsNullOrEmpty(path))
                    {
                        targetPath = Path.Combine(targetPath, path);
                        FileSystemHelpers.CreateDirectory(targetPath);
                    }
                }

                using (packageUri == null ? Tracer.Step($"Extracting content to {targetPath}")
                    : Tracer.Step("Extracting content from {0} to {1}", StringUtils.ObfuscatePath(packageUri.AbsoluteUri), targetPath))
                {
                    var content = packageUri == null ? Request.Content
                        : await DeploymentHelper.GetArtifactContentFromURL(new ArtifactDeploymentInfo(null, null) { RemoteURL = packageUri.AbsoluteUri }, Tracer);

                    using (var stream = await content.ReadAsStreamAsync())
                    {
                        // The unzipping is done over the existing folder, without first removing existing files.
                        // Hence it's more of a PATCH than a PUT. We should consider supporting both with the right semantic.
                        // Though a true PUT at the root would be scary as it would wipe all existing files!
                        var zipArchive = new ZipArchive(stream, ZipArchiveMode.Read);
                        zipArchive.Extract(targetPath, Tracer);
                    }
                }

                if (isArmTemplate && requestContent != null)
                {
                    requestContent.Value <JObject>("properties").Add("provisioningState", "Succeeded");
                    return(Request.CreateResponse(HttpStatusCode.OK, requestContent));
                }

                return(Request.CreateResponse(HttpStatusCode.OK));
            }
            catch (Exception ex)
            {
                return(ArmUtils.CreateErrorResponse(Request, HttpStatusCode.BadRequest, ex));
            }
        }