When using spring.main.cloud-platform: none as a property under the /config folder, in order to override main's platform and disable config.import kubernetes mechanism (https://docs.spring.io/spring-cloud-kubernetes/docs/current/reference/html/#breaking-changes-in-3-0-x),
spring.config.import attempts to import anyway, therefore breaking the build with "Unable to load config data from 'kubernetes:'".
That does not happen when the same property is placed in a profiled application-test.yml for @ActiveProfiles("test"), and that is why I assume it is a matter of Boot and not Cloud, but please let me know if this is the wrong project to post this
To reproduce it:
mkdir configissue && cd configissue && curl 'https://start.spring.io/starter.zip?type=maven-project&dependencies=cloud-config-client' | tar xvf -
sed -i '' 's|spring-cloud-starter-config|spring-cloud-starter-kubernetes-fabric8-config|' pom.xml
echo 'spring.main.cloud-platform=kubernetes' > src/main/resources/application.properties
echo 'spring.config.import=kubernetes:' >> src/main/resources/application.properties
mkdir -p src/test/resources/config
echo 'spring.main.cloud-platform=none' > src/test/resources/config/application.properties
chmod +x ./mvnw && ./mvnw clean test
Comment From: wilkinsona
As far as I can tell, the expectations about the behaviour are a little back to front here.
When the cloud platform is none, the resolver for kubernetes: switches itself off. This results in a failure when the prefix is used. It only works when the cloud platform is set to none in a profile-specific file because the import is processed before the profile-specific configuration. In other words, a failure indicates that setting the cloud platform to none is working.
Have you considered using spring.config.activate.on-cloud-platform to control when the import is applied? Another option is to use optional:kubernetes so that it does not fail when not running on Kubernetes.
Comment From: nightswimmings
Thanks for the explanation Andy!
.activate.on-cloud-platform would be useful to me if it applied only to the spring.config section, but as per my tests it does to the whole property file, so I need to start managing more than one file.
the optional:kubernetes approach would be a bit like not using disabling anything indeed, since it does not complain in my test. But i jsut want to go an extra mile and make sure it won't change it's behavior depending on whether boot detects there's a kubernetes in the machine where this runs
Is there a way to override spring.cloud.import with a keyword value signaling a clearing manner? Something like spring.cloud.import=none or null or empty string, so at least the context is not blocked for a minute in every attempt to find out the config
I know the alternative is using profiles for test as most people do but Ive been working with the /config approach in test scope for long time as it saves you from having to define a test profile and remember the side-effect of defining every test with the @ActiveProfiles.
Comment From: wilkinsona
it does to the whole property file, so I need to start managing more than one file
That doesn't have to be the case. As described in the reference documentation, you can split a single physical properties file into multiple logical documents using the #--- separator:
com.example.property.always-configured=whatever
#---
spring.config.activate.on-cloud-platform=kubernetes
spring.config.import=kubernetes:
With this example, com.example.property.always-configured will always be configured irrespective of the cloud platform and spring.config.import=kubernetes: will only apply when the cloud platform is Kubernetes.
go an extra mile and make sure it won't change it's behavior depending on whether boot detects there's a kubernetes in the machine where this runs
The arrangement above plus setting spring.main.cloud-platform=none in your src/test/resources/config/application.properties file should achieve this.
Is there a way to override spring.cloud.import with a keyword value signaling a clearing manner?
Not at the moment. https://github.com/spring-projects/spring-boot/issues/24133 is tracking an enhancement in this area but it's not an easy change to make.
I'll close this one now as I think a multi-document properties file should give you what you want. If that turns out not to be the case, please comment again explaining why and we can re-open and take another look.
Comment From: nightswimmings
Brilliant! Worked flawlessly (had to figure out the separator has to be '---' in yaml) Thanks @wilkinsona as always!
Comment From: nightswimmings
@wilkinsona Found a cornercase or a bug where the scenario we discussed does not work: it happens when you provide the property with default value on the application.yml
I wrote the following comment (https://github.com/spring-cloud/spring-cloud-kubernetes/issues/1491#issuecomment-1907161295) in the issue thread I was following in spring-cloud-kubernetes because I feel it's more on their side, although I am not completely sure, because if you do a test and place it in application.yml without the second section with conditional on-cloud-platform activation, it works as expected (it retrieves the cloud configmap property whether you provide a default or not in application.yml)