From a4c0696d815f4299473e74ce793468da61b56ad7 Mon Sep 17 00:00:00 2001 From: David Byron <82477955+dbyron-sf@users.noreply.github.com> Date: Tue, 9 Apr 2024 16:00:03 -0700 Subject: [PATCH] feat(build): add halyard-integration module to exercise the just-built docker image (#2144) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(core): move @Bean methods from GoogleProfileReader so separate config class to remove circular dependency error on startup *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: versionsController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/VersionsController.class] ↓ versionsService (field com.netflix.spinnaker.halyard.core.registry.v1.ProfileRegistry com.netflix.spinnaker.halyard.config.services.v1.VersionsService.profileRegistry) ↓ profileRegistry (field com.netflix.spinnaker.halyard.core.registry.v1.GoogleProfileReader com.netflix.spinnaker.halyard.core.registry.v1.ProfileRegistry.googleProfileReader) ┌─────┐ | googleProfileReader (field com.google.api.services.storage.Storage com.netflix.spinnaker.halyard.core.registry.v1.GoogleProfileReader.applicationDefaultGoogleStorage) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(config): remove unused ProviderService variable from EcsAccountValidator to prevent circular dependency startup error: *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: haServiceController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/HaServiceController.class] ↓ haServiceService (field private com.netflix.spinnaker.halyard.config.services.v1.ValidateService com.netflix.spinnaker.halyard.config.services.v1.HaServiceService.validateService) ┌─────┐ | validateService (field com.netflix.spinnaker.halyard.config.validate.v1.ValidatorCollection com.netflix.spinnaker.halyard.config.services.v1.ValidateService.validatorCollection) ↑ ↓ | validatorCollection (field private java.util.List com.netflix.spinnaker.halyard.config.validate.v1.ValidatorCollection.validators) ↑ ↓ | ecsAccountValidator (field com.netflix.spinnaker.halyard.config.services.v1.ProviderService com.netflix.spinnaker.halyard.config.validate.v1.providers.ecs.EcsAccountValidator.providerService) ↑ ↓ | providerService (field private com.netflix.spinnaker.halyard.config.services.v1.ValidateService com.netflix.spinnaker.halyard.config.services.v1.ProviderService.validateService) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(config): Use @Lazy with ValidatorCollection.validators to remove circular dependency startup error *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: haServiceController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/HaServiceController.class] ↓ haServiceService (field private com.netflix.spinnaker.halyard.config.services.v1.ValidateService com.netflix.spinnaker.halyard.config.services.v1.HaServiceService.validateService) ┌─────┐ | validateService (field com.netflix.spinnaker.halyard.config.validate.v1.ValidatorCollection com.netflix.spinnaker.halyard.config.services.v1.ValidateService.validatorCollection) ↑ ↓ | validatorCollection (field private java.util.List com.netflix.spinnaker.halyard.config.validate.v1.ValidatorCollection.validators) ↑ ↓ | ecsAccountValidator (field com.netflix.spinnaker.halyard.config.services.v1.AccountService com.netflix.spinnaker.halyard.config.validate.v1.providers.ecs.EcsAccountValidator.accountService) ↑ ↓ | accountService (field private com.netflix.spinnaker.halyard.config.services.v1.ProviderService com.netflix.spinnaker.halyard.config.services.v1.AccountService.providerService) ↑ ↓ | providerService (field private com.netflix.spinnaker.halyard.config.services.v1.ValidateService com.netflix.spinnaker.halyard.config.services.v1.ProviderService.validateService) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(config): add @Lazy to DeploymentService.storageService to fix circular dependency startup error: *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: haServiceController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/HaServiceController.class] ↓ haServiceService (field private com.netflix.spinnaker.halyard.config.services.v1.DeploymentService com.netflix.spinnaker.halyard.config.services.v1.HaServiceService.deploymentService) ┌─────┐ | deploymentService (field private com.netflix.spinnaker.halyard.config.services.v1.PersistentStorageService com.netflix.spinnaker.halyard.config.services.v1.DeploymentService.storageService) ↑ ↓ | persistentStorageService (field private com.netflix.spinnaker.halyard.config.services.v1.DeploymentService com.netflix.spinnaker.halyard.config.services.v1.PersistentStorageService.deploymentService) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(dpeloy): add @Lazy annotation to GoogleIgorService.googleDistributedServiceDelegate to fix circular dependency startup error: *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: deploymentController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/DeploymentController.class] ↓ generateService (field private com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory com.netflix.spinnaker.halyard.deploy.services.v1.GenerateService.serviceProviderFactory) ↓ serviceProviderFactory (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory.kubectlServiceProvider) ↓ kubectlServiceProvider (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider.clouddriverService) ↓ kubernetesV2ClouddriverService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService.serviceDelegate) ↓ kubernetesV2ServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2MonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate.monitoringDaemonService) ↓ kubernetesV2MonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) ┌─────┐ | googleIgorService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleIgorService.googleDistributedServiceDelegate) ↑ ↓ | googleDistributedServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleMonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate.monitoringDaemonService) ↑ ↓ | googleMonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(deploy): add @Lazy annotation to GoogleRedisBootstrapService.googleDistributedServiceDelegate to fix circular dependency error on startup: *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: deploymentController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/DeploymentController.class] ↓ generateService (field private com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory com.netflix.spinnaker.halyard.deploy.services.v1.GenerateService.serviceProviderFactory) ↓ serviceProviderFactory (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory.kubectlServiceProvider) ↓ kubectlServiceProvider (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider.clouddriverService) ↓ kubernetesV2ClouddriverService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService.serviceDelegate) ↓ kubernetesV2ServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2MonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate.monitoringDaemonService) ↓ kubernetesV2MonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) ┌─────┐ | googleRedisBootstrapService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleRedisBootstrapService.googleDistributedServiceDelegate) ↑ ↓ | googleDistributedServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleMonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate.monitoringDaemonService) ↑ ↓ | googleMonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(deploy): add @Lazy annotation to GoogleDeckService.googleDistributedServiceDelegate to fix circular dependency error on startup *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: deploymentController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/DeploymentController.class] ↓ generateService (field private com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory com.netflix.spinnaker.halyard.deploy.services.v1.GenerateService.serviceProviderFactory) ↓ serviceProviderFactory (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory.kubectlServiceProvider) ↓ kubectlServiceProvider (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider.clouddriverService) ↓ kubernetesV2ClouddriverService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService.serviceDelegate) ↓ kubernetesV2ServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2MonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate.monitoringDaemonService) ↓ kubernetesV2MonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) ┌─────┐ | googleDeckService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDeckService.googleDistributedServiceDelegate) ↑ ↓ | googleDistributedServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleMonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate.monitoringDaemonService) ↑ ↓ | googleMonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(deploy): add @Lazy annotation to GoogleEchoService.googleDistributedServiceDelegate to fix circular dependency error on startup: *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: deploymentController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/DeploymentController.class] ↓ generateService (field private com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory com.netflix.spinnaker.halyard.deploy.services.v1.GenerateService.serviceProviderFactory) ↓ serviceProviderFactory (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory.kubectlServiceProvider) ↓ kubectlServiceProvider (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider.clouddriverService) ↓ kubernetesV2ClouddriverService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService.serviceDelegate) ↓ kubernetesV2ServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2MonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate.monitoringDaemonService) ↓ kubernetesV2MonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) ┌─────┐ | googleEchoService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleEchoService.googleDistributedServiceDelegate) ↑ ↓ | googleDistributedServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleMonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate.monitoringDaemonService) ↑ ↓ | googleMonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(deploy): add @Lazy annotation to GoogleConsulServerService.googleDistributedServiceDelegate to fix circular dependency error on startup: *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: deploymentController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/DeploymentController.class] ↓ generateService (field private com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory com.netflix.spinnaker.halyard.deploy.services.v1.GenerateService.serviceProviderFactory) ↓ serviceProviderFactory (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory.kubectlServiceProvider) ↓ kubectlServiceProvider (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider.clouddriverService) ↓ kubernetesV2ClouddriverService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService.serviceDelegate) ↓ kubernetesV2ServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2MonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate.monitoringDaemonService) ↓ kubernetesV2MonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) ┌─────┐ | googleConsulServerService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleConsulServerService.googleDistributedServiceDelegate) ↑ ↓ | googleDistributedServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleMonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate.monitoringDaemonService) ↑ ↓ | googleMonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(deploy): add @Lazy annotation to GoogleFront50Service.googleDistributedServiceDelegate to fix circular dependency error on startup: *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: deploymentController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/DeploymentController.class] ↓ generateService (field private com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory com.netflix.spinnaker.halyard.deploy.services.v1.GenerateService.serviceProviderFactory) ↓ serviceProviderFactory (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory.kubectlServiceProvider) ↓ kubectlServiceProvider (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider.clouddriverService) ↓ kubernetesV2ClouddriverService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService.serviceDelegate) ↓ kubernetesV2ServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2MonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate.monitoringDaemonService) ↓ kubernetesV2MonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) ┌─────┐ | googleFront50Service (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleFront50Service.googleDistributedServiceDelegate) ↑ ↓ | googleDistributedServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleMonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate.monitoringDaemonService) ↑ ↓ | googleMonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(deploy): add @Lazy annotation to GoogleClouddriverService.googleDistributedServiceDelegate to fix circular dependency error on startup: *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: deploymentController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/DeploymentController.class] ↓ generateService (field private com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory com.netflix.spinnaker.halyard.deploy.services.v1.GenerateService.serviceProviderFactory) ↓ serviceProviderFactory (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory.kubectlServiceProvider) ↓ kubectlServiceProvider (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider.clouddriverService) ↓ kubernetesV2ClouddriverService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService.serviceDelegate) ↓ kubernetesV2ServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2MonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate.monitoringDaemonService) ↓ kubernetesV2MonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) ┌─────┐ | googleClouddriverService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleClouddriverService.googleDistributedServiceDelegate) ↑ ↓ | googleDistributedServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleMonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate.monitoringDaemonService) ↑ ↓ | googleMonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(deploy): add @Lazy annotation to GoogleOrcaBootstrapService.googleDistributedServiceDelegate to fix circular dependency error on startup: *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: deploymentController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/DeploymentController.class] ↓ generateService (field private com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory com.netflix.spinnaker.halyard.deploy.services.v1.GenerateService.serviceProviderFactory) ↓ serviceProviderFactory (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory.kubectlServiceProvider) ↓ kubectlServiceProvider (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider.clouddriverService) ↓ kubernetesV2ClouddriverService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService.serviceDelegate) ↓ kubernetesV2ServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2MonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate.monitoringDaemonService) ↓ kubernetesV2MonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) ┌─────┐ | googleOrcaService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleOrcaService.googleDistributedServiceDelegate) ↑ ↓ | googleDistributedServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleMonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate.monitoringDaemonService) ↑ ↓ | googleMonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(deploy): add @Lazy annotation to GoogleOrcaService.googleDistributedServiceDelegate to fix circular dependency issue on startup *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: deploymentController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/DeploymentController.class] ↓ generateService (field private com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory com.netflix.spinnaker.halyard.deploy.services.v1.GenerateService.serviceProviderFactory) ↓ serviceProviderFactory (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory.kubectlServiceProvider) ↓ kubectlServiceProvider (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider.clouddriverService) ↓ kubernetesV2ClouddriverService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService.serviceDelegate) ↓ kubernetesV2ServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2MonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate.monitoringDaemonService) ↓ kubernetesV2MonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) ┌─────┐ | googleOrcaService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleOrcaService.googleDistributedServiceDelegate) ↑ ↓ | googleDistributedServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleMonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate.monitoringDaemonService) ↑ ↓ | googleMonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(deploy): add @Lazy annotation to GoogleRoscoService.googleDistributedServiceDelegate to fix circular dependency error on startup *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: deploymentController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/DeploymentController.class] ↓ generateService (field private com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory com.netflix.spinnaker.halyard.deploy.services.v1.GenerateService.serviceProviderFactory) ↓ serviceProviderFactory (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory.kubectlServiceProvider) ↓ kubectlServiceProvider (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider.clouddriverService) ↓ kubernetesV2ClouddriverService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService.serviceDelegate) ↓ kubernetesV2ServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2MonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate.monitoringDaemonService) ↓ kubernetesV2MonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) ┌─────┐ | googleRoscoService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleRoscoService.googleDistributedServiceDelegate) ↑ ↓ | googleDistributedServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleMonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate.monitoringDaemonService) ↑ ↓ | googleMonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(deploy): add @Lazy annotation to GoogleFiatService.googleDistributedServiceDelegate to fix circular dependency error on startup *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: deploymentController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/DeploymentController.class] ↓ generateService (field private com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory com.netflix.spinnaker.halyard.deploy.services.v1.GenerateService.serviceProviderFactory) ↓ serviceProviderFactory (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory.kubectlServiceProvider) ↓ kubectlServiceProvider (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider.clouddriverService) ↓ kubernetesV2ClouddriverService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService.serviceDelegate) ↓ kubernetesV2ServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2MonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate.monitoringDaemonService) ↓ kubernetesV2MonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) ┌─────┐ | googleFiatService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleFiatService.googleDistributedServiceDelegate) ↑ ↓ | googleDistributedServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleMonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate.monitoringDaemonService) ↑ ↓ | googleMonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(deploy): add @Lazy annotation to GoogleClouddriverBootstrapService.googleDistributedServiceDelegate to fix circular dependency startup error *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: deploymentController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/DeploymentController.class] ↓ generateService (field private com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory com.netflix.spinnaker.halyard.deploy.services.v1.GenerateService.serviceProviderFactory) ↓ serviceProviderFactory (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory.kubectlServiceProvider) ↓ kubectlServiceProvider (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider.clouddriverService) ↓ kubernetesV2ClouddriverService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService.serviceDelegate) ↓ kubernetesV2ServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2MonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate.monitoringDaemonService) ↓ kubernetesV2MonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) ┌─────┐ | googleClouddriverBootstrapService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleClouddriverBootstrapService.googleDistributedServiceDelegate) ↑ ↓ | googleDistributedServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleMonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate.monitoringDaemonService) ↑ ↓ | googleMonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(deploy): add @Lazy annotation to GoogleRedisService.googleDistributedServiceDelegate to fix circular dependency error on startup: *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: deploymentController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/DeploymentController.class] ↓ generateService (field private com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory com.netflix.spinnaker.halyard.deploy.services.v1.GenerateService.serviceProviderFactory) ↓ serviceProviderFactory (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory.kubectlServiceProvider) ↓ kubectlServiceProvider (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider.clouddriverService) ↓ kubernetesV2ClouddriverService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService.serviceDelegate) ↓ kubernetesV2ServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2MonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate.monitoringDaemonService) ↓ kubernetesV2MonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) ┌─────┐ | googleRedisService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleRedisService.googleDistributedServiceDelegate) ↑ ↓ | googleDistributedServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleMonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate.monitoringDaemonService) ↑ ↓ | googleMonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(deploy): add @Lazy annotation to GoogleGateService.googleDistributedServiceDelegate to fix circular dependency error at startup *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: deploymentController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/DeploymentController.class] ↓ generateService (field private com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory com.netflix.spinnaker.halyard.deploy.services.v1.GenerateService.serviceProviderFactory) ↓ serviceProviderFactory (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory.kubectlServiceProvider) ↓ kubectlServiceProvider (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider.clouddriverService) ↓ kubernetesV2ClouddriverService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService.serviceDelegate) ↓ kubernetesV2ServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2MonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate.monitoringDaemonService) ↓ kubernetesV2MonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) ┌─────┐ | googleGateService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleGateService.googleDistributedServiceDelegate) ↑ ↓ | googleDistributedServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleMonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate.monitoringDaemonService) ↑ ↓ | googleMonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(deploy): add @Lazy annotation to GoogleKayentaService.googleDistributedServiceDelegate to fix circular dependency error on startup *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: deploymentController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/DeploymentController.class] ↓ generateService (field private com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory com.netflix.spinnaker.halyard.deploy.services.v1.GenerateService.serviceProviderFactory) ↓ serviceProviderFactory (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory.kubectlServiceProvider) ↓ kubectlServiceProvider (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider.clouddriverService) ↓ kubernetesV2ClouddriverService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService.serviceDelegate) ↓ kubernetesV2ServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2MonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate.monitoringDaemonService) ↓ kubernetesV2MonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) ┌─────┐ | googleMonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) ↑ ↓ | googleKayentaService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleKayentaService.googleDistributedServiceDelegate) ↑ ↓ | googleDistributedServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleMonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate.monitoringDaemonService) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(deploy): add @Lazy annotation to GoogleVaultServerService.googleDistributedServiceDelegate to fix circular dependency error on startup: *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: deploymentController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/DeploymentController.class] ↓ generateService (field private com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory com.netflix.spinnaker.halyard.deploy.services.v1.GenerateService.serviceProviderFactory) ↓ serviceProviderFactory (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory.kubectlServiceProvider) ↓ kubectlServiceProvider (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider.clouddriverService) ↓ kubernetesV2ClouddriverService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService.serviceDelegate) ↓ kubernetesV2ServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2MonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate.monitoringDaemonService) ↓ kubernetesV2MonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) ┌─────┐ | googleMonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) ↑ ↓ | googleVaultServerService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleVaultServerService.googleDistributedServiceDelegate) ↑ ↓ | googleDistributedServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleMonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.google.GoogleDistributedServiceDelegate.monitoringDaemonService) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(deploy): add @Lazy annotation to KubernetesV2ServiceDelegate.monitoringDaemonService to fix circular dependency error on startup *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: deploymentController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/DeploymentController.class] ↓ generateService (field private com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory com.netflix.spinnaker.halyard.deploy.services.v1.GenerateService.serviceProviderFactory) ↓ serviceProviderFactory (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory.kubectlServiceProvider) ↓ kubectlServiceProvider (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider.clouddriverService) ┌─────┐ | kubernetesV2ClouddriverService (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ClouddriverService.serviceDelegate) ↑ ↓ | kubernetesV2ServiceDelegate (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2MonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2ServiceDelegate.monitoringDaemonService) ↑ ↓ | kubernetesV2MonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) ↑ ↓ | googleMonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * fix(deploy): remove unused SpinnakerMonitoringDaemonService.service property to fix circular dependency error on startup: *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: deploymentController defined in URL [jar:file:/opt/halyard/lib/halyard-web.jar!/com/netflix/spinnaker/halyard/controllers/v1/DeploymentController.class] ↓ generateService (field private com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory com.netflix.spinnaker.halyard.deploy.services.v1.GenerateService.serviceProviderFactory) ↓ serviceProviderFactory (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider com.netflix.spinnaker.halyard.deploy.deployment.v1.ServiceProviderFactory.kubectlServiceProvider) ↓ kubectlServiceProvider (field com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubernetesV2MonitoringDaemonService com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.distributed.kubernetes.v2.KubectlServiceProvider.monitoringDaemonService) ┌─────┐ | kubernetesV2MonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) ↑ ↓ | googleMonitoringDaemonService (field java.util.List com.netflix.spinnaker.halyard.deploy.spinnaker.v1.service.SpinnakerMonitoringDaemonService.services) └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. * feat(docker): add HEALTHCHECK to facilitate testing container startup * feat(build): add halyard-integration module to exercise the just-built docker image * feat(gha): run integration test in pr builds multi-arch with --load doesn't work, so add a separate step using the local platform to make an image available for testing. see docker/buildx#59 * feat(gha): run integration test in branch builds * refactor(core): remove unused GoogleProfileReader.createGoogleStorage method --- .github/workflows/build.yml | 13 +++ .github/workflows/pr.yml | 13 +++ Dockerfile.slim | 2 + Dockerfile.ubuntu | 2 + .../config/services/v1/DeploymentService.java | 3 +- .../validate/v1/ValidatorCollection.java | 2 + .../v1/providers/ecs/EcsAccountValidator.java | 3 - .../core/registry/v1/GoogleProfileReader.java | 49 -------- .../v1/GoogleProfileReaderConfig.java | 78 +++++++++++++ .../SpinnakerMonitoringDaemonService.java | 2 - .../GoogleClouddriverBootstrapService.java | 3 +- .../google/GoogleClouddriverService.java | 3 +- .../google/GoogleConsulServerService.java | 3 +- .../distributed/google/GoogleDeckService.java | 3 +- .../distributed/google/GoogleEchoService.java | 3 +- .../distributed/google/GoogleFiatService.java | 3 +- .../google/GoogleFront50Service.java | 3 +- .../distributed/google/GoogleGateService.java | 3 +- .../distributed/google/GoogleIgorService.java | 3 +- .../google/GoogleKayentaService.java | 3 +- .../google/GoogleOrcaBootstrapService.java | 3 +- .../distributed/google/GoogleOrcaService.java | 3 +- .../google/GoogleRedisBootstrapService.java | 3 +- .../google/GoogleRedisService.java | 3 +- .../google/GoogleRoscoService.java | 3 +- .../google/GoogleVaultServerService.java | 3 +- .../v2/KubernetesV2ServiceDelegate.java | 3 +- .../halyard-integration.gradle | 26 +++++ .../halyard/StandaloneContainerTest.java | 108 ++++++++++++++++++ .../src/test/resources/logback.xml | 36 ++++++ settings.gradle | 1 + 31 files changed, 317 insertions(+), 72 deletions(-) create mode 100644 halyard-core/src/main/java/com/netflix/spinnaker/halyard/core/registry/v1/GoogleProfileReaderConfig.java create mode 100644 halyard-integration/halyard-integration.gradle create mode 100644 halyard-integration/src/test/java/com/netflix/spinnaker/halyard/StandaloneContainerTest.java create mode 100644 halyard-integration/src/test/resources/logback.xml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d6e438c1f5..af85971da4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,6 +37,19 @@ jobs: env: ORG_GRADLE_PROJECT_version: ${{ steps.build_variables.outputs.VERSION }} run: ./gradlew build --stacktrace ${{ steps.build_variables.outputs.REPO }}-web:installDist + - name: Build local slim container image for testing + uses: docker/build-push-action@v5 + with: + context: . + file: Dockerfile.slim + load: true + platforms: local + tags: | + "${{ steps.build_variables.outputs.REPO }}:${{ steps.build_variables.outputs.VERSION }}-unvalidated" + - name: Test local slim container image + env: + FULL_DOCKER_IMAGE_NAME: "${{ steps.build_variables.outputs.REPO }}:${{ steps.build_variables.outputs.VERSION }}-unvalidated" + run: ./gradlew ${{ steps.build_variables.outputs.REPO }}-integration:test - name: Login to GAR # Only run this on repositories in the 'spinnaker' org, not on forks. if: startsWith(github.repository, 'spinnaker/') diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 4a01dca2ab..2b068dfafd 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -51,3 +51,16 @@ jobs: tags: | "${{ env.CONTAINER_REGISTRY }}/${{ steps.build_variables.outputs.REPO }}:latest-ubuntu" "${{ env.CONTAINER_REGISTRY }}/${{ steps.build_variables.outputs.REPO }}:${{ steps.build_variables.outputs.VERSION }}-ubuntu" + - name: Build local slim container image for testing + uses: docker/build-push-action@v5 + with: + context: . + file: Dockerfile.slim + load: true + platforms: local + tags: | + "${{ steps.build_variables.outputs.REPO }}:${{ steps.build_variables.outputs.VERSION }}" + - name: Test local slim container image + env: + FULL_DOCKER_IMAGE_NAME: "${{ steps.build_variables.outputs.REPO }}:${{ steps.build_variables.outputs.VERSION }}" + run: ./gradlew ${{ steps.build_variables.outputs.REPO }}-integration:test diff --git a/Dockerfile.slim b/Dockerfile.slim index dd5af23566..b2cd71021e 100644 --- a/Dockerfile.slim +++ b/Dockerfile.slim @@ -34,4 +34,6 @@ RUN adduser -S -G spinnaker -u 1000 spinnaker COPY halyard-web/build/install/halyard /opt/halyard USER spinnaker +HEALTHCHECK CMD curl http://localhost:8064/health | grep UP || exit 1 + CMD ["/opt/halyard/bin/halyard"] diff --git a/Dockerfile.ubuntu b/Dockerfile.ubuntu index 22fcbbd3d3..69be710006 100644 --- a/Dockerfile.ubuntu +++ b/Dockerfile.ubuntu @@ -30,4 +30,6 @@ RUN adduser --system --uid 1000 --group spinnaker COPY halyard-web/build/install/halyard /opt/halyard USER spinnaker +HEALTHCHECK CMD curl http://localhost:8064/health | grep UP || exit 1 + CMD ["/opt/halyard/bin/halyard"] diff --git a/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/services/v1/DeploymentService.java b/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/services/v1/DeploymentService.java index d1375b25d7..822c21cd4f 100644 --- a/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/services/v1/DeploymentService.java +++ b/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/services/v1/DeploymentService.java @@ -29,6 +29,7 @@ import com.netflix.spinnaker.halyard.core.problem.v1.ProblemSet; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; /** @@ -43,7 +44,7 @@ public class DeploymentService { @Autowired private HalconfigParser halconfigParser; - @Autowired private PersistentStorageService storageService; + @Lazy @Autowired private PersistentStorageService storageService; public void setDeploymentConfiguration( String deploymentName, DeploymentConfiguration deploymentConfiguration) { diff --git a/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/validate/v1/ValidatorCollection.java b/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/validate/v1/ValidatorCollection.java index 5b35555aa8..9632269046 100644 --- a/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/validate/v1/ValidatorCollection.java +++ b/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/validate/v1/ValidatorCollection.java @@ -26,6 +26,7 @@ import java.util.List; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; /** @@ -35,6 +36,7 @@ @Slf4j @Component public class ValidatorCollection { + @Lazy @Autowired(required = false) private List validators = new ArrayList<>(); diff --git a/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/validate/v1/providers/ecs/EcsAccountValidator.java b/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/validate/v1/providers/ecs/EcsAccountValidator.java index 661fb12623..f0aba6d8e2 100644 --- a/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/validate/v1/providers/ecs/EcsAccountValidator.java +++ b/halyard-config/src/main/java/com/netflix/spinnaker/halyard/config/validate/v1/providers/ecs/EcsAccountValidator.java @@ -6,7 +6,6 @@ import com.netflix.spinnaker.halyard.config.problem.v1.ConfigProblemSetBuilder; import com.netflix.spinnaker.halyard.config.services.v1.AccountService; import com.netflix.spinnaker.halyard.config.services.v1.ConfigService; -import com.netflix.spinnaker.halyard.config.services.v1.ProviderService; import com.netflix.spinnaker.halyard.core.problem.v1.Problem.Severity; import java.util.List; import java.util.Optional; @@ -15,8 +14,6 @@ @Component public class EcsAccountValidator extends Validator { - @Autowired ProviderService providerService; - @Autowired AccountService accountService; @Autowired ConfigService configService; diff --git a/halyard-core/src/main/java/com/netflix/spinnaker/halyard/core/registry/v1/GoogleProfileReader.java b/halyard-core/src/main/java/com/netflix/spinnaker/halyard/core/registry/v1/GoogleProfileReader.java index 8ab634737b..9024dc8060 100644 --- a/halyard-core/src/main/java/com/netflix/spinnaker/halyard/core/registry/v1/GoogleProfileReader.java +++ b/halyard-core/src/main/java/com/netflix/spinnaker/halyard/core/registry/v1/GoogleProfileReader.java @@ -19,22 +19,15 @@ package com.netflix.spinnaker.halyard.core.registry.v1; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.api.client.http.HttpRequestInitializer; -import com.google.api.client.json.JsonFactory; -import com.google.api.client.json.jackson2.JacksonFactory; import com.google.api.services.storage.Storage; -import com.google.api.services.storage.StorageScopes; -import com.netflix.spinnaker.halyard.core.provider.v1.google.GoogleCredentials; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.util.Collections; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; import org.yaml.snakeyaml.Yaml; @@ -56,16 +49,6 @@ private Yaml getYamlParser() { return applicationContext.getBean(Yaml.class); } - @Bean - public Storage applicationDefaultGoogleStorage() { - return createGoogleStorage(true); - } - - @Bean - public Storage unauthenticatedGoogleStorage() { - return createGoogleStorage(false); - } - public InputStream readProfile(String artifactName, String version, String profileName) throws IOException { String path = profilePath(artifactName, version, profileName); @@ -118,36 +101,4 @@ private InputStream getContents(String objectName) throws IOException { return new ByteArrayInputStream(output.toByteArray()); } - - private Storage createGoogleStorage(boolean useApplicationDefaultCreds) { - JsonFactory jsonFactory = JacksonFactory.getDefaultInstance(); - String applicationName = "Spinnaker/Halyard"; - HttpRequestInitializer requestInitializer = null; - - if (useApplicationDefaultCreds) { - try { - com.google.auth.oauth2.GoogleCredentials credentials = - com.google.auth.oauth2.GoogleCredentials.getApplicationDefault(); - if (credentials.createScopedRequired()) { - credentials = - credentials.createScoped( - Collections.singleton(StorageScopes.DEVSTORAGE_FULL_CONTROL)); - } - requestInitializer = GoogleCredentials.setHttpTimeout(credentials); - log.info("Loaded application default credential for reading BOMs & profiles."); - } catch (Exception e) { - log.debug( - "No application default credential could be loaded for reading BOMs & profiles. Continuing unauthenticated: {}", - e.getMessage()); - } - } - if (requestInitializer == null) { - requestInitializer = GoogleCredentials.retryRequestInitializer(); - } - - return new Storage.Builder( - GoogleCredentials.buildHttpTransport(), jsonFactory, requestInitializer) - .setApplicationName(applicationName) - .build(); - } } diff --git a/halyard-core/src/main/java/com/netflix/spinnaker/halyard/core/registry/v1/GoogleProfileReaderConfig.java b/halyard-core/src/main/java/com/netflix/spinnaker/halyard/core/registry/v1/GoogleProfileReaderConfig.java new file mode 100644 index 0000000000..213df27433 --- /dev/null +++ b/halyard-core/src/main/java/com/netflix/spinnaker/halyard/core/registry/v1/GoogleProfileReaderConfig.java @@ -0,0 +1,78 @@ +/* + * Copyright 2017 Google, 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.halyard.core.registry.v1; + +import com.google.api.client.http.HttpRequestInitializer; +import com.google.api.client.json.JsonFactory; +import com.google.api.client.json.jackson2.JacksonFactory; +import com.google.api.services.storage.Storage; +import com.google.api.services.storage.StorageScopes; +import com.netflix.spinnaker.halyard.core.provider.v1.google.GoogleCredentials; +import java.util.Collections; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConditionalOnProperty("spinnaker.config.input.gcs.enabled") +@Slf4j +public class GoogleProfileReaderConfig { + @Bean + public Storage applicationDefaultGoogleStorage() { + return createGoogleStorage(true); + } + + @Bean + public Storage unauthenticatedGoogleStorage() { + return createGoogleStorage(false); + } + + private Storage createGoogleStorage(boolean useApplicationDefaultCreds) { + JsonFactory jsonFactory = JacksonFactory.getDefaultInstance(); + String applicationName = "Spinnaker/Halyard"; + HttpRequestInitializer requestInitializer = null; + + if (useApplicationDefaultCreds) { + try { + com.google.auth.oauth2.GoogleCredentials credentials = + com.google.auth.oauth2.GoogleCredentials.getApplicationDefault(); + if (credentials.createScopedRequired()) { + credentials = + credentials.createScoped( + Collections.singleton(StorageScopes.DEVSTORAGE_FULL_CONTROL)); + } + requestInitializer = GoogleCredentials.setHttpTimeout(credentials); + log.info("Loaded application default credential for reading BOMs & profiles."); + } catch (Exception e) { + log.debug( + "No application default credential could be loaded for reading BOMs & profiles. Continuing unauthenticated: {}", + e.getMessage()); + } + } + if (requestInitializer == null) { + requestInitializer = GoogleCredentials.retryRequestInitializer(); + } + + return new Storage.Builder( + GoogleCredentials.buildHttpTransport(), jsonFactory, requestInitializer) + .setApplicationName(applicationName) + .build(); + } +} diff --git a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/SpinnakerMonitoringDaemonService.java b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/SpinnakerMonitoringDaemonService.java index fe86dd5ad5..7c25a6f537 100644 --- a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/SpinnakerMonitoringDaemonService.java +++ b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/SpinnakerMonitoringDaemonService.java @@ -47,8 +47,6 @@ public abstract class SpinnakerMonitoringDaemonService @Autowired MetricRegistryProfileFactoryBuilder metricRegistryProfileFactoryBuilder; - @Autowired List services; - @Override public SpinnakerArtifact getArtifact() { return SpinnakerArtifact.SPINNAKER_MONITORING_DAEMON; diff --git a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleClouddriverBootstrapService.java b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleClouddriverBootstrapService.java index d585f9b345..749c08a37d 100644 --- a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleClouddriverBootstrapService.java +++ b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleClouddriverBootstrapService.java @@ -27,6 +27,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Delegate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @EqualsAndHashCode(callSuper = true) @@ -37,7 +38,7 @@ public class GoogleClouddriverBootstrapService extends ClouddriverBootstrapServi final DeployPriority deployPriority = new DeployPriority(6); final boolean requiredToBootstrap = true; - @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; + @Lazy @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; @Override public List getSidecars(SpinnakerRuntimeSettings runtimeSettings) { diff --git a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleClouddriverService.java b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleClouddriverService.java index 7c41624f14..81c2d7c9ad 100644 --- a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleClouddriverService.java +++ b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleClouddriverService.java @@ -28,6 +28,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Delegate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @EqualsAndHashCode(callSuper = true) @@ -38,7 +39,7 @@ public class GoogleClouddriverService extends ClouddriverService final DeployPriority deployPriority = new DeployPriority(4); final boolean requiredToBootstrap = false; - @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; + @Lazy @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; @Override public List getProfiles( diff --git a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleConsulServerService.java b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleConsulServerService.java index 2f88e1ef43..d35b1e0ca4 100644 --- a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleConsulServerService.java +++ b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleConsulServerService.java @@ -30,6 +30,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Delegate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @EqualsAndHashCode(callSuper = true) @@ -37,7 +38,7 @@ @Data public class GoogleConsulServerService extends ConsulServerService implements GoogleDistributedService { - @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; + @Lazy @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; @Override public String getDefaultInstanceType() { diff --git a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleDeckService.java b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleDeckService.java index 8f8225f671..608bebf66e 100644 --- a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleDeckService.java +++ b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleDeckService.java @@ -27,6 +27,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Delegate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @EqualsAndHashCode(callSuper = true) @@ -37,7 +38,7 @@ public class GoogleDeckService extends DeckService final DeployPriority deployPriority = new DeployPriority(4); final boolean requiredToBootstrap = false; - @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; + @Lazy @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; @Override public List getSidecars(SpinnakerRuntimeSettings runtimeSettings) { diff --git a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleEchoService.java b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleEchoService.java index 530782c3be..d902aba7fc 100644 --- a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleEchoService.java +++ b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleEchoService.java @@ -27,6 +27,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Delegate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @EqualsAndHashCode(callSuper = true) @@ -37,7 +38,7 @@ public class GoogleEchoService extends EchoService final DeployPriority deployPriority = new DeployPriority(4); final boolean requiredToBootstrap = false; - @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; + @Lazy @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; @Override public List getSidecars(SpinnakerRuntimeSettings runtimeSettings) { diff --git a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleFiatService.java b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleFiatService.java index 74f162e5cf..a3abda27dc 100644 --- a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleFiatService.java +++ b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleFiatService.java @@ -27,6 +27,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Delegate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @EqualsAndHashCode(callSuper = true) @@ -37,7 +38,7 @@ public class GoogleFiatService extends FiatService final DeployPriority deployPriority = new DeployPriority(4); final boolean requiredToBootstrap = false; - @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; + @Lazy @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; @Override public List getSidecars(SpinnakerRuntimeSettings runtimeSettings) { diff --git a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleFront50Service.java b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleFront50Service.java index da6d14247a..5e4a510bdb 100644 --- a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleFront50Service.java +++ b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleFront50Service.java @@ -28,6 +28,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Delegate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @EqualsAndHashCode(callSuper = true) @@ -38,7 +39,7 @@ public class GoogleFront50Service extends Front50Service final DeployPriority deployPriority = new DeployPriority(4); final boolean requiredToBootstrap = false; - @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; + @Lazy @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; @Override public List getProfiles( diff --git a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleGateService.java b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleGateService.java index affd5e655c..7809bd829b 100644 --- a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleGateService.java +++ b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleGateService.java @@ -27,6 +27,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Delegate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @EqualsAndHashCode(callSuper = true) @@ -37,7 +38,7 @@ public class GoogleGateService extends GateService final DeployPriority deployPriority = new DeployPriority(4); final boolean requiredToBootstrap = false; - @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; + @Lazy @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; @Override public List getSidecars(SpinnakerRuntimeSettings runtimeSettings) { diff --git a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleIgorService.java b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleIgorService.java index 6a94c88922..c0df95d26d 100644 --- a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleIgorService.java +++ b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleIgorService.java @@ -27,6 +27,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Delegate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @EqualsAndHashCode(callSuper = true) @@ -37,7 +38,7 @@ public class GoogleIgorService extends IgorService final DeployPriority deployPriority = new DeployPriority(4); final boolean requiredToBootstrap = false; - @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; + @Lazy @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; @Override public List getSidecars(SpinnakerRuntimeSettings runtimeSettings) { diff --git a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleKayentaService.java b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleKayentaService.java index 8ca5eddaa6..ca3e664806 100644 --- a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleKayentaService.java +++ b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleKayentaService.java @@ -26,6 +26,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Delegate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @EqualsAndHashCode(callSuper = true) @@ -36,7 +37,7 @@ public class GoogleKayentaService extends KayentaService final DeployPriority deployPriority = new DeployPriority(4); final boolean requiredToBootstrap = false; - @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; + @Lazy @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; @Override public List getSidecars(SpinnakerRuntimeSettings runtimeSettings) { diff --git a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleOrcaBootstrapService.java b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleOrcaBootstrapService.java index 3ca2976fbb..fa009596b2 100644 --- a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleOrcaBootstrapService.java +++ b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleOrcaBootstrapService.java @@ -28,6 +28,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Delegate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @EqualsAndHashCode(callSuper = true) @@ -38,7 +39,7 @@ public class GoogleOrcaBootstrapService extends OrcaBootstrapService final DeployPriority deployPriority = new DeployPriority(6); final boolean requiredToBootstrap = true; - @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; + @Lazy @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; @Override public List getSidecars(SpinnakerRuntimeSettings runtimeSettings) { diff --git a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleOrcaService.java b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleOrcaService.java index fb4f593a96..f20fecd2f9 100644 --- a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleOrcaService.java +++ b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleOrcaService.java @@ -27,6 +27,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Delegate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @EqualsAndHashCode(callSuper = true) @@ -38,7 +39,7 @@ public class GoogleOrcaService extends OrcaService final boolean requiredToBootstrap = false; final boolean stateful = true; - @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; + @Lazy @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; @Override public List getSidecars(SpinnakerRuntimeSettings runtimeSettings) { diff --git a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleRedisBootstrapService.java b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleRedisBootstrapService.java index bbd5022581..1007c8bc44 100644 --- a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleRedisBootstrapService.java +++ b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleRedisBootstrapService.java @@ -30,6 +30,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Delegate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import redis.clients.jedis.Jedis; @@ -41,7 +42,7 @@ public class GoogleRedisBootstrapService extends RedisBootstrapService final DeployPriority deployPriority = new DeployPriority(8); final boolean requiredToBootstrap = true; - @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; + @Lazy @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; @Override public List getSidecars(SpinnakerRuntimeSettings runtimeSettings) { diff --git a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleRedisService.java b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleRedisService.java index f09323df1d..8b23f925ff 100644 --- a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleRedisService.java +++ b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleRedisService.java @@ -32,6 +32,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Delegate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import redis.clients.jedis.Jedis; @@ -42,7 +43,7 @@ public class GoogleRedisService extends RedisService implements GoogleDistribute final DeployPriority deployPriority = new DeployPriority(8); final boolean requiredToBootstrap = true; - @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; + @Lazy @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; @Override public Jedis connectToPrimaryService( diff --git a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleRoscoService.java b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleRoscoService.java index fd74d724f4..ff834f3528 100644 --- a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleRoscoService.java +++ b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleRoscoService.java @@ -27,6 +27,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Delegate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @EqualsAndHashCode(callSuper = true) @@ -38,7 +39,7 @@ public class GoogleRoscoService extends RoscoService final boolean requiredToBootstrap = false; final boolean stateful = true; - @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; + @Lazy @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; @Override public List getSidecars(SpinnakerRuntimeSettings runtimeSettings) { diff --git a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleVaultServerService.java b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleVaultServerService.java index 56108bc1f6..6b0c8bd9fb 100644 --- a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleVaultServerService.java +++ b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/google/GoogleVaultServerService.java @@ -29,6 +29,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Delegate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @EqualsAndHashCode(callSuper = true) @@ -36,7 +37,7 @@ @Data public class GoogleVaultServerService extends VaultServerService implements GoogleDistributedService { - @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; + @Lazy @Delegate @Autowired GoogleDistributedServiceDelegate googleDistributedServiceDelegate; @Override public String getDefaultInstanceType() { diff --git a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/kubernetes/v2/KubernetesV2ServiceDelegate.java b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/kubernetes/v2/KubernetesV2ServiceDelegate.java index d22856915e..6d2674c866 100644 --- a/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/kubernetes/v2/KubernetesV2ServiceDelegate.java +++ b/halyard-deploy/src/main/java/com/netflix/spinnaker/halyard/deploy/spinnaker/v1/service/distributed/kubernetes/v2/KubernetesV2ServiceDelegate.java @@ -25,6 +25,7 @@ import com.netflix.spinnaker.halyard.deploy.spinnaker.v1.SpinnakerArtifact; import lombok.Getter; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @Component @@ -41,5 +42,5 @@ public String getDockerRegistry(String deploymentName, SpinnakerArtifact artifac @Autowired @Getter ObjectMapper objectMapper; - @Autowired @Getter KubernetesV2MonitoringDaemonService monitoringDaemonService; + @Lazy @Autowired @Getter KubernetesV2MonitoringDaemonService monitoringDaemonService; } diff --git a/halyard-integration/halyard-integration.gradle b/halyard-integration/halyard-integration.gradle new file mode 100644 index 0000000000..c860d5c9da --- /dev/null +++ b/halyard-integration/halyard-integration.gradle @@ -0,0 +1,26 @@ +dependencies { + testImplementation "com.fasterxml.jackson.core:jackson-databind" + testImplementation "org.assertj:assertj-core" + testImplementation "org.junit.jupiter:junit-jupiter-api" + testImplementation "org.slf4j:slf4j-api" + testImplementation "org.testcontainers:testcontainers" + testImplementation "org.testcontainers:junit-jupiter" + testImplementation "org.testcontainers:mysql" + testRuntimeOnly "ch.qos.logback:logback-classic" + testRuntimeOnly "mysql:mysql-connector-java" +} + +test.configure { + def fullDockerImageName = System.getenv('FULL_DOCKER_IMAGE_NAME') + onlyIf("there is a docker image to test") { + fullDockerImageName != null && fullDockerImageName.trim() != '' + } +} + +test { + // So stdout and stderr from the just-built container are available in CI + testLogging.showStandardStreams = true + + // Run the tests when the docker image changes + inputs.property 'fullDockerImageName', System.getenv('FULL_DOCKER_IMAGE_NAME') +} diff --git a/halyard-integration/src/test/java/com/netflix/spinnaker/halyard/StandaloneContainerTest.java b/halyard-integration/src/test/java/com/netflix/spinnaker/halyard/StandaloneContainerTest.java new file mode 100644 index 0000000000..435be1c124 --- /dev/null +++ b/halyard-integration/src/test/java/com/netflix/spinnaker/halyard/StandaloneContainerTest.java @@ -0,0 +1,108 @@ +/* + * Copyright 2024 Salesforce, 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.halyard; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assumptions.assumeTrue; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.Map; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.output.Slf4jLogConsumer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +@Testcontainers +class StandaloneContainerTest { + + private static final Logger logger = LoggerFactory.getLogger(StandaloneContainerTest.class); + + private static GenericContainer halyardContainer; + + @BeforeAll + static void setupOnce() throws Exception { + String fullDockerImageName = System.getenv("FULL_DOCKER_IMAGE_NAME"); + + // Skip the tests if there's no docker image. This allows gradlew build to work. + assumeTrue(fullDockerImageName != null); + + DockerImageName dockerImageName = DockerImageName.parse(fullDockerImageName); + + halyardContainer = + new GenericContainer(dockerImageName) + .withExposedPorts(8064) + .waitingFor(Wait.forHealthcheck()) + .withEnv("SPRING_APPLICATION_JSON", getSpringApplicationJson()); + + Slf4jLogConsumer logConsumer = new Slf4jLogConsumer(logger); + halyardContainer.start(); + halyardContainer.followOutput(logConsumer); + } + + private static String getSpringApplicationJson() throws JsonProcessingException { + Map properties = Map.of(); + ObjectMapper mapper = new ObjectMapper(); + return mapper.writeValueAsString(properties); + } + + @AfterAll + static void cleanupOnce() { + if (halyardContainer != null) { + halyardContainer.stop(); + } + } + + @BeforeEach + void init(TestInfo testInfo) { + System.out.println("--------------- Test " + testInfo.getDisplayName()); + } + + @Test + void testHealthCheck() throws Exception { + // hit an arbitrary endpoint + HttpRequest request = + HttpRequest.newBuilder() + .uri( + new URI( + "http://" + + halyardContainer.getHost() + + ":" + + halyardContainer.getFirstMappedPort() + + "/health")) + .GET() + .build(); + + HttpClient client = HttpClient.newHttpClient(); + + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + assertThat(response).isNotNull(); + logger.info("response: {}, {}", response.statusCode(), response.body()); + assertThat(response.statusCode()).isEqualTo(200); + } +} diff --git a/halyard-integration/src/test/resources/logback.xml b/halyard-integration/src/test/resources/logback.xml new file mode 100644 index 0000000000..d0573f0bfc --- /dev/null +++ b/halyard-integration/src/test/resources/logback.xml @@ -0,0 +1,36 @@ + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + diff --git a/settings.gradle b/settings.gradle index 4cad784879..bcb5f29644 100644 --- a/settings.gradle +++ b/settings.gradle @@ -29,6 +29,7 @@ include 'halyard-cli' include 'halyard-config' include 'halyard-core' include 'halyard-deploy' +include 'halyard-integration' include 'halyard-proto' include 'halyard-web'