diff --git a/gate-core/gate-core.gradle b/gate-core/gate-core.gradle index eec3036aad..1766f72eb6 100644 --- a/gate-core/gate-core.gradle +++ b/gate-core/gate-core.gradle @@ -30,6 +30,7 @@ dependencies { implementation "com.netflix.spinnaker.kork:kork-core" implementation "com.netflix.spinnaker.kork:kork-security" + implementation "com.netflix.spinnaker.kork:kork-manageddelivery" implementation "com.netflix.spectator:spectator-api" implementation "com.github.ben-manes.caffeine:guava" implementation "com.netflix.hystrix:hystrix-core" diff --git a/gate-core/src/main/groovy/com/netflix/spinnaker/gate/config/ServiceConfiguration.groovy b/gate-core/src/main/groovy/com/netflix/spinnaker/gate/config/ServiceConfiguration.groovy index 2cec3321e5..97ac1f8058 100644 --- a/gate-core/src/main/groovy/com/netflix/spinnaker/gate/config/ServiceConfiguration.groovy +++ b/gate-core/src/main/groovy/com/netflix/spinnaker/gate/config/ServiceConfiguration.groovy @@ -41,7 +41,7 @@ class ServiceConfiguration { void postConstruct() { // this check is done in a @PostConstruct to avoid Spring's list merging in @ConfigurationProperties (vs. overriding) healthCheckableServices = healthCheckableServices ?: [ - "orca", "clouddriver", "echo", "igor", "flex", "front50", "mahe", "mine" + "orca", "clouddriver", "echo", "igor", "flex", "front50", "mahe", "mine", "keel" ] } diff --git a/gate-core/src/main/groovy/com/netflix/spinnaker/gate/services/internal/KeelService.java b/gate-core/src/main/groovy/com/netflix/spinnaker/gate/services/internal/KeelService.java new file mode 100644 index 0000000000..a7d29e0cb9 --- /dev/null +++ b/gate-core/src/main/groovy/com/netflix/spinnaker/gate/services/internal/KeelService.java @@ -0,0 +1,31 @@ +/* + * + * Copyright 2019 Netflix, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package com.netflix.spinnaker.gate.services.internal; + +import com.netflix.spinnaker.kork.manageddelivery.model.ResourceEvent; +import java.time.Instant; +import java.util.List; +import retrofit.http.GET; +import retrofit.http.Path; +import retrofit.http.Query; + +public interface KeelService { + + @GET("/resources/events/{name}") + List getResourceEvents(@Path("name") String name, @Query("since") Instant since); +} diff --git a/gate-web/gate-web.gradle b/gate-web/gate-web.gradle index d8d08bc355..c6298adf2f 100644 --- a/gate-web/gate-web.gradle +++ b/gate-web/gate-web.gradle @@ -36,6 +36,7 @@ dependencies { implementation "com.netflix.spinnaker.kork:kork-web" implementation "com.netflix.spinnaker.kork:kork-secrets-aws" implementation "com.netflix.spinnaker.kork:kork-core" + implementation "com.netflix.spinnaker.kork:kork-manageddelivery" implementation "com.netflix.frigga:frigga" implementation "redis.clients:jedis" implementation "com.netflix.hystrix:hystrix-core" diff --git a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/config/GateConfig.groovy b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/config/GateConfig.groovy index aa554647a4..88f208a064 100644 --- a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/config/GateConfig.groovy +++ b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/config/GateConfig.groovy @@ -39,6 +39,7 @@ import com.netflix.spinnaker.gate.services.internal.EchoService import com.netflix.spinnaker.gate.services.internal.Front50Service import com.netflix.spinnaker.gate.services.internal.IgorService import com.netflix.spinnaker.gate.services.internal.KayentaService +import com.netflix.spinnaker.gate.services.internal.KeelService import com.netflix.spinnaker.gate.services.internal.MineService import com.netflix.spinnaker.gate.services.internal.OrcaService import com.netflix.spinnaker.gate.services.internal.OrcaServiceSelector @@ -174,6 +175,12 @@ class GateConfig extends RedisHttpSessionConfiguration { createClient "clouddriver", ClouddriverService, okHttpClient } + @Bean + @ConditionalOnProperty("services.keel.enabled") + KeelService keelService(OkHttpClient okHttpClient) { + createClient "keel", KeelService, okHttpClient + } + @Bean ClouddriverServiceSelector clouddriverServiceSelector(ClouddriverService defaultClouddriverService, OkHttpClient okHttpClient) { // support named clouddriver service clients diff --git a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/controllers/HistoryController.java b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/controllers/HistoryController.java new file mode 100644 index 0000000000..16755d241f --- /dev/null +++ b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/controllers/HistoryController.java @@ -0,0 +1,40 @@ +package com.netflix.spinnaker.gate.controllers; + +import com.netflix.spinnaker.gate.services.internal.KeelService; +import com.netflix.spinnaker.kork.manageddelivery.model.ResourceEvent; +import groovy.util.logging.Slf4j; +import io.swagger.annotations.ApiOperation; +import java.time.Instant; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RequestMapping("/history") +@RestController +@Slf4j +@ConditionalOnProperty("services.keel.enabled") +public class HistoryController { + + private static final Logger log = LoggerFactory.getLogger(HistoryController.class); + private final KeelService keelService; + + @Autowired + public HistoryController(KeelService keelService) { + this.keelService = keelService; + } + + @ApiOperation(value = "Get history for a resource", response = List.class) + @RequestMapping(value = "/{name}", method = RequestMethod.GET) + List getHistory( + @PathVariable("name") String name, + @RequestParam(value = "since", required = false) Instant since) { + return keelService.getResourceEvents(name, since); + } +} diff --git a/gradle.properties b/gradle.properties index ba25b65c2d..4d09d9383a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,6 +2,6 @@ fiatVersion=1.1.0 enablePublishing=false spinnakerGradleVersion=6.5.0 -korkVersion=5.6.3 +korkVersion=5.7.0 includeProviders=basic,iap,ldap,oauth2,saml,x509 org.gradle.parallel=true