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()); }
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"); }
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);
public IEnumerable <SwarmServiceDescription> GetServicesToRedeploy(DockerHubHookData hookData, IEnumerable <SwarmServiceDescription> allSwarmServices) { _logger.LogInformation("GetServicesToRedeploy({@hookData}, {@allSwarmServices})", hookData, allSwarmServices); return(Enumerable.Empty <SwarmServiceDescription>()); }