Example #1
0
        public async Task <IActionResult> Post([FromRoute] string secret, [FromBody] DockerHubHookData data)
        {
            if (!_dockerHubSecretValidator.IsTheRightSecret(secret))
            {
                _logger.LogWarning("Hook event with a wrong secret! secret: {secret}; data: {@data}", secret, data);
                return(new UnauthorizedResult());
            }

            _logger.LogDebug("Hook event. Data: {@data}", data);

            var currentServices = await _swarmClient.GetServices();

            var servicesToRedeploy = _swarmServiceSelector.GetServicesToRedeploy(data, currentServices);

            _logger.LogDebug("Services to redeploy: {@servicesToRedeploy}", servicesToRedeploy);

            foreach (var service in servicesToRedeploy)
            {
                // TODO: Consider compare local service digest with docker hub one.
                // Since hook data does not contain digest information, we cannot confirm if
                // the service is not already updated.
                _logger.LogDebug("Redeploying {@service}", service);
                await _swarmClient.RedeployService(service.id);

                _logger.LogDebug("Done {@service}", service);
            }

            return(new OkResult());
        }
Example #2
0
        public async Task POST_dockerhub_handler_should_get_services_from_swarmpit_filter_them_and_update_filtered_ones()
        {
            // Arrange
            const string secret                 = "my_secret";
            const string baseUrl                = "http://swarmpit/api/";
            const string accessToken            = "abc123";
            const string helloRepositoryName    = "dopplerdock/hello-microservice";
            const string cdHelperRepositoryName = "dopplerdock/doppler-cd-helper";
            const string intTag                 = "INT";
            const string qaTag = "QA";

            var hookData = new DockerHubHookData()
            {
                callback_url = "https://callback_url",
                push_data    = new DockerHubHookDataPushData()
                {
                    tag = intTag
                },
                repository = new DockerHubHookDataRepository()
                {
                    repo_name = helloRepositoryName
                }
            };

            // should be redeployed
            var helloServiceInt = new SwarmServiceDescription()
            {
                id          = "penpnhep0bsciofxzd542v62n",
                serviceName = "hello-int_hello-service",
                repository  = new SwarmServiceDescriptionRepository()
                {
                    name        = helloRepositoryName,
                    tag         = intTag,
                    imageDigest = "sha256:c7a459f13dbf082fe9b6631783f897d54978a32cc91aa8dee5fcb5630fa18a0b"
                }
            };

            // should not be redeployed
            var cdHelperServiceInt = new SwarmServiceDescription()
            {
                id          = "qn3jq891p77lyigwysj4fcww2",
                serviceName = "swarmpit_doppler-cd-helper",
                repository  = new SwarmServiceDescriptionRepository()
                {
                    name        = cdHelperRepositoryName,
                    tag         = intTag,
                    imageDigest = "sha256:a247c00ad3ae505bbcbcbc48eb58a50a16e0628339803da65c9081be365b3b9c"
                }
            };

            // Exactly the same image with another configuration
            // should be redeployed
            var helloServiceIntWithAlternativeConfiguration = helloServiceInt with
            {
                id          = "riq6gv8d0xr9rpagr9lg5xqrw",
                serviceName = "hello-int_hello-service_with_alternative_configuration",
            };

            // The same image name with a different tag with another configuration
            // should not be redeployed
            var helloServiceQA = helloServiceInt with
            {
                id          = "riq6gv8d0xr9rpagr9lg5xqrw",
                serviceName = "hello-int_hello-service_with_alternative_configuration",
                repository  = helloServiceInt.repository with
                {
                    tag = qaTag
                }
            };

            using var customFactory = _factory.WithWebHostBuilder(c =>
            {
                c.ConfigureServices(s =>
                                    s.AddSingleton(Options.Create(new SwarmpitSwarmClientSettings()
                {
                    BaseUrl     = baseUrl,
                    AccessToken = accessToken
                }))
                                    .AddSingleton(Options.Create(new DockerHubHookSettings()
                {
                    Secret = secret
                })));
            });

            customFactory.Server.PreserveExecutionContext = true;

            using var httpTest = new HttpTest();

            httpTest.ForCallsTo($"{baseUrl}services")
            .WithHeader("Authorization", $"Bearer {accessToken}")
            .WithVerb("GET")
            .RespondWithJson(new[] {
                helloServiceInt,
                cdHelperServiceInt,
                helloServiceIntWithAlternativeConfiguration,
                helloServiceQA
            });

            var client = customFactory.CreateClient(new WebApplicationFactoryClientOptions()
            {
                AllowAutoRedirect = false
            });

            // Act
            var response = await client.PostAsync(
                $"/hooks/{secret}/",
                JsonContent.Create(hookData));

            // Assert
            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            Assert.Equal(3, httpTest.CallLog.Count());
            httpTest.ShouldHaveCalled($"{baseUrl}services/{helloServiceInt.id}/redeploy")
            .WithOAuthBearerToken(accessToken)
            .WithVerb("POST");
            httpTest.ShouldHaveCalled($"{baseUrl}services/{helloServiceIntWithAlternativeConfiguration.id}/redeploy")
            .WithOAuthBearerToken(accessToken)
            .WithVerb("POST");
        }
Example #3
0
 public IEnumerable <SwarmServiceDescription> GetServicesToRedeploy(
     DockerHubHookData hookData,
     IEnumerable <SwarmServiceDescription> allSwarmServices)
 => allSwarmServices.Where(x =>
                           x.repository.name == hookData.repository.repo_name &&
                           x.repository.tag == hookData.push_data.tag);
Example #4
0
 public IEnumerable <SwarmServiceDescription> GetServicesToRedeploy(DockerHubHookData hookData, IEnumerable <SwarmServiceDescription> allSwarmServices)
 {
     _logger.LogInformation("GetServicesToRedeploy({@hookData}, {@allSwarmServices})", hookData, allSwarmServices);
     return(Enumerable.Empty <SwarmServiceDescription>());
 }