<repo_name>litichevskiydv/DockerHubToTravisCiProxy<file_sep>/DockerHubToTravisCiProxy/Controllers/ProxyController.cs
﻿namespace DockerHubToTravisCiProxy.Controllers
{
    using System;
    using System.Linq;
    using System.Net.Http;
    using System.Text;
    using System.Threading.Tasks;
    using Flurl.Http;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Logging;
    using Microsoft.Extensions.Options;
    using Models;

    [Route("[controller]")]
    public class ProxyController : Controller
    {
        private readonly ILogger<ProxyController> _logger;
        private readonly TravisCiIntegrationOptions _integrationOptions;

        public ProxyController(ILogger<ProxyController> logger, IOptionsSnapshot<TravisCiIntegrationOptions> options)
        {
            if (logger == null)
                throw new ArgumentNullException(nameof(logger));
            if(options == null)
                throw new ArgumentNullException(nameof(options));

            _logger = logger;
            _integrationOptions = options.Value;
        }

        [HttpPost]
        public async Task Post([FromBody] DockerRequest request)
        {
            var body = @"
{
  ""request"": {
    ""branch"":""<ImageValidatorBranch>"",
    ""config"": {
      ""env"": {
        ""IMAGE_TAG"": ""<ImageTag>""
      }
    }
  }
}"
                .Replace("<ImageValidatorBranch>", _integrationOptions.ImageValidatorBranch)
                .Replace("<ImageTag>", request.PushData.Tag);

            var labelParts = request.Repository.Dockerfile.Split('\n')
                .Single(x => x.StartsWith("LABEL", StringComparison.OrdinalIgnoreCase))
                .Split('/')
                .Select(x => x.Trim('"'))
                .ToArray();

            var response =
                await $"https://api.travis-ci.org/repo/{labelParts[labelParts.Length - 2]}%2F{labelParts[labelParts.Length - 1]}/requests"
                    .WithHeader("Accept", "application/json")
                    .WithHeader("Travis-API-Version", "3")
                    .WithHeader("Authorization", $"token {_integrationOptions.ApiKey}")
                    .PostAsync(new StringContent(body, Encoding.UTF8, "application/json"))
                    .ReceiveJson();

            _logger.LogInformation($"Validation build was started for image {request.Repository.RepoName}:{request.PushData.Tag}");
        }
    }
}
<file_sep>/DockerHubToTravisCiProxy/Dockerfile
FROM microsoft/dotnet:1.1-runtime
LABEL name="DockerHubToTravisCiProxy"
WORKDIR /app
COPY . ./
ENV ASPNETCORE_URLS http://*:80
EXPOSE 80
ENTRYPOINT ["dotnet", "DockerHubToTravisCiProxy.dll"]
<file_sep>/DockerHubToTravisCiProxy/Startup.cs
﻿namespace DockerHubToTravisCiProxy
{
    using Controllers;
    using JetBrains.Annotations;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Logging;
    using Newtonsoft.Json.Serialization;

    [UsedImplicitly(ImplicitUseTargetFlags.WithMembers)]
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", false, true)
                .AddEnvironmentVariables("TRAVISCIPROXY_");
            Configuration = builder.Build();
        }

        private IConfigurationRoot Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddOptions()
                .Configure<TravisCiIntegrationOptions>(
                    x =>
                    {
                        x.ApiKey = Configuration[nameof(TravisCiIntegrationOptions.ApiKey)];
                        x.ImageValidatorBranch = Configuration[nameof(TravisCiIntegrationOptions.ImageValidatorBranch)];
                    });

            services.AddMvc()
                .AddJsonOptions(x =>
                                {
                                    x.SerializerSettings.ContractResolver =
                                        new DefaultContractResolver(true)
                                        {
                                            NamingStrategy = new SnakeCaseNamingStrategy(true, true)
                                        };
                                });
        }

        public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
        {
            loggerFactory
                .AddConsole(Configuration.GetSection("Logging"));

            app.UseMvc();
        }
    }
}
<file_sep>/README.md
# DockerHubToTravisCiProxy
Docker Hub webhook that transfers requests to Travis CI
<file_sep>/DockerHubToTravisCiProxy/Controllers/Models/DockerRequest.cs
﻿namespace DockerHubToTravisCiProxy.Controllers.Models
{
    using JetBrains.Annotations;

    [UsedImplicitly(ImplicitUseTargetFlags.WithMembers)]
    public class PushDataDescription
    {
        public string Tag { get; set; }
    }

    [UsedImplicitly(ImplicitUseTargetFlags.WithMembers)]
    public class RepositoryDescription
    {
        public string Dockerfile { get; set; }

        public string RepoName { get; set; }
    }

    [UsedImplicitly(ImplicitUseTargetFlags.WithMembers)]
    public class DockerRequest
    {
        public PushDataDescription PushData { get; set; }

        public RepositoryDescription Repository { get; set; }
    }
}<file_sep>/DockerHubToTravisCiProxy/Controllers/TravisCIIntegrationOptions.cs
﻿namespace DockerHubToTravisCiProxy.Controllers
{
    using JetBrains.Annotations;

    [UsedImplicitly]
    public class TravisCiIntegrationOptions
    {
        public string ApiKey { get; set; }

        public string ImageValidatorBranch { get; set; }
    }
}