forked from helidon-io/helidon
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use helidon.oci prefix for OCI Config and allow some oci auth types t…
…o accept federation-endpoint and tenancy-id (helidon-io#9740) The PR fixes Issues 9681 and 9734 which includes the following: 1. Allow instance-principal, resource-principal and oke-workload-identity to accept federation-endpoint and tenancy-id as config parameters. This is originally targeted just for oke-workload-identity where Instance Metadata Service (IMDS) does not work on an OKE environment. Because of these, it is unable to assemble the target endpoint as it needs the IMDS to retrieve the region. To resolve the issue, the federation-endpoint configuration is now allowed to be explicitly specified to avoid generation of endpoint using the region from IMDS. In some examples of the use of oke-workload-identity, the tenancy id is required, so this configuration parameter is also added as an option. Furthermore, because instance-principal and resource-principal providers extends AbstractRequestingAuthenticationDetailsProvider similar to oke-workload-instance, hence they are included in the change to allow those optional parameters. 2. Fix a bug where the oci configuration does not work when prefixed with "helidon.oci". 3. Add comprehensive testing coverage for above changes. 4. Remove unnecessary Weight annotation with default value and replace WARNING message with TRACE when oci config does not use "helidon.oci"
- Loading branch information
Showing
23 changed files
with
634 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,6 +30,7 @@ jaxb.index | |
/MANIFEST.MF | ||
/README | ||
/CONTRIBUTING.md | ||
.crt | ||
.pem | ||
.p8 | ||
.pkcs8.pem | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
...n/integrations/oci/authentication/instance/AuthenticationMethodInstancePrincipalTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/* | ||
* Copyright (c) 2025 Oracle and/or its affiliates. | ||
* | ||
* 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 io.helidon.integrations.oci.authentication.instance; | ||
|
||
import java.util.Properties; | ||
|
||
import io.helidon.webserver.WebServer; | ||
import io.helidon.webserver.http.HttpRules; | ||
import io.helidon.webserver.http.ServerRequest; | ||
import io.helidon.webserver.http.ServerResponse; | ||
import io.helidon.webserver.testing.junit5.ServerTest; | ||
import io.helidon.webserver.testing.junit5.SetUpRoute; | ||
|
||
import io.helidon.service.registry.ServiceRegistry; | ||
import io.helidon.service.registry.ServiceRegistryManager; | ||
|
||
import com.oracle.bmc.auth.BasicAuthenticationDetailsProvider; | ||
import org.junit.jupiter.api.AfterEach; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import static org.hamcrest.CoreMatchers.containsString; | ||
import static org.hamcrest.CoreMatchers.is; | ||
import static org.hamcrest.MatcherAssert.assertThat; | ||
import static org.junit.jupiter.api.Assertions.assertThrows; | ||
|
||
@ServerTest | ||
public class AuthenticationMethodInstancePrincipalTest { | ||
private static ServiceRegistryManager registryManager; | ||
private static ServiceRegistry registry; | ||
private static String imdsBaseUri; | ||
|
||
AuthenticationMethodInstancePrincipalTest(WebServer server) { | ||
imdsBaseUri = "http://localhost:%d/opc/v2/".formatted(server.port()); | ||
} | ||
|
||
@SetUpRoute | ||
static void routing(HttpRules rules) { | ||
rules.get("/opc/v2/instance", ImdsEmulator::emulateImdsInstance); | ||
} | ||
|
||
void setUp(Properties p) { | ||
p.put("helidon.oci.authentication-method", "instance-principal"); | ||
p.put("helidon.oci.imds-timeout", "PT1S"); | ||
p.put("helidon.oci.imds-detect-retries", "0"); | ||
p.put("helidon.oci.imds-base-uri", imdsBaseUri); | ||
System.setProperties(p); | ||
|
||
registryManager = ServiceRegistryManager.create(); | ||
registry = registryManager.registry(); | ||
} | ||
|
||
@AfterEach | ||
void cleanUp() { | ||
registry = null; | ||
if (registryManager != null) { | ||
registryManager.shutdown(); | ||
} | ||
} | ||
|
||
@Test | ||
public void testInstancePrincipalConfigurationAndInstantiation() { | ||
final String FEDERATION_ENDPOINT = "https://auth.us-myregion-1.oraclecloud.com"; | ||
final String TENANT_ID = "ocid1.tenancy.oc1..mytenancyid"; | ||
|
||
Properties p = System.getProperties(); | ||
p.put("helidon.oci.federation-endpoint", FEDERATION_ENDPOINT); | ||
p.put("helidon.oci.tenant-id", TENANT_ID); | ||
setUp(p); | ||
|
||
// This error indicates that the instance principal provider has been instantiated | ||
var thrown = assertThrows(IllegalArgumentException.class, | ||
() -> registry.get(BasicAuthenticationDetailsProvider.class)); | ||
assertThat(thrown.getMessage(), | ||
containsString(MockedInstancePrincipalBuilderProvider.INSTANCE_PRINCIPAL_INSTANTIATION_MESSAGE)); | ||
|
||
// The following validation indicates that the instance principal provider has been configured properly | ||
assertThat(MockedAuthenticationMethodInstancePrincipal.getBuilder().getMetadataBaseUrl(), is(imdsBaseUri)); | ||
assertThat(MockedAuthenticationMethodInstancePrincipal.getBuilder().getFederationEndpoint(), is(FEDERATION_ENDPOINT)); | ||
assertThat(MockedAuthenticationMethodInstancePrincipal.getBuilder().getTenancyId(), is(TENANT_ID)); | ||
} | ||
|
||
public static class ImdsEmulator { | ||
// This will allow HelidonOci.imdsAvailable() to be tested by making the server that simulates IMDS to return a JSON value | ||
// when instance property is queried | ||
private static final String IMDS_INSTANCE_RESPONSE = """ | ||
{ | ||
"displayName": "helidon-server" | ||
} | ||
"""; | ||
|
||
private static void emulateImdsInstance(ServerRequest req, ServerResponse res) { | ||
res.send(IMDS_INSTANCE_RESPONSE); | ||
} | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
...integrations/oci/authentication/instance/MockedAuthenticationMethodInstancePrincipal.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Copyright (c) 2025 Oracle and/or its affiliates. | ||
* | ||
* 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 io.helidon.integrations.oci.authentication.instance; | ||
|
||
import java.util.Optional; | ||
import java.util.function.Supplier; | ||
|
||
import io.helidon.common.Weight; | ||
import io.helidon.common.Weighted; | ||
import io.helidon.integrations.oci.OciConfig; | ||
import io.helidon.service.registry.Service; | ||
|
||
import com.oracle.bmc.auth.InstancePrincipalsAuthenticationDetailsProvider.InstancePrincipalsAuthenticationDetailsProviderBuilder; | ||
|
||
@Weight(Weighted.DEFAULT_WEIGHT) | ||
@Service.Provider | ||
class MockedAuthenticationMethodInstancePrincipal extends AuthenticationMethodInstancePrincipal { | ||
|
||
private static InstancePrincipalsAuthenticationDetailsProviderBuilder providerBuilder; | ||
|
||
MockedAuthenticationMethodInstancePrincipal(OciConfig config, | ||
Supplier<Optional<InstancePrincipalsAuthenticationDetailsProviderBuilder>> | ||
builder) { | ||
super(config, builder); | ||
providerBuilder = builder.get().get(); | ||
} | ||
|
||
static InstancePrincipalsAuthenticationDetailsProviderBuilder getBuilder() { | ||
return providerBuilder; | ||
} | ||
} |
84 changes: 84 additions & 0 deletions
84
...idon/integrations/oci/authentication/instance/MockedInstancePrincipalBuilderProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* | ||
* Copyright (c) 2025 Oracle and/or its affiliates. | ||
* | ||
* 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 io.helidon.integrations.oci.authentication.instance; | ||
|
||
import java.util.function.Supplier; | ||
|
||
import io.helidon.common.Weight; | ||
import io.helidon.common.Weighted; | ||
import io.helidon.integrations.oci.OciConfig; | ||
import io.helidon.service.registry.Service; | ||
|
||
import com.oracle.bmc.auth.InstancePrincipalsAuthenticationDetailsProvider.InstancePrincipalsAuthenticationDetailsProviderBuilder; | ||
|
||
import static org.mockito.Mockito.any; | ||
import static org.mockito.Mockito.doAnswer; | ||
import static org.mockito.Mockito.mock; | ||
|
||
@Weight(Weighted.DEFAULT_WEIGHT + 10) | ||
@Service.Provider | ||
class MockedInstancePrincipalBuilderProvider extends InstancePrincipalBuilderProvider | ||
implements Supplier<InstancePrincipalsAuthenticationDetailsProviderBuilder> { | ||
static final String INSTANCE_PRINCIPAL_INSTANTIATION_MESSAGE = "Instance Principal has been instantiated"; | ||
private String metadataBaseUrl = null; | ||
private String tenancyID = null; | ||
private String federationEndpoint = null; | ||
|
||
MockedInstancePrincipalBuilderProvider(OciConfig config) { | ||
super(config); | ||
} | ||
|
||
@Override | ||
InstancePrincipalsAuthenticationDetailsProviderBuilder getBuilder() { | ||
// Mock the InstancePrincipalsAuthenticationDetailsProviderBuilder | ||
final InstancePrincipalsAuthenticationDetailsProviderBuilder builder = | ||
mock(InstancePrincipalsAuthenticationDetailsProviderBuilder.class); | ||
|
||
doAnswer(invocation -> { | ||
throw new IllegalArgumentException(INSTANCE_PRINCIPAL_INSTANTIATION_MESSAGE); | ||
}).when(builder).build(); | ||
|
||
// Process metadataBaseUrl | ||
doAnswer(invocation -> { | ||
metadataBaseUrl = invocation.getArgument(0); | ||
return null; | ||
}).when(builder).metadataBaseUrl(any()); | ||
doAnswer(invocation -> { | ||
return metadataBaseUrl; | ||
}).when(builder).getMetadataBaseUrl(); | ||
|
||
// Process federationEndpoint | ||
doAnswer(invocation -> { | ||
federationEndpoint = invocation.getArgument(0); | ||
return null; | ||
}).when(builder).federationEndpoint(any()); | ||
doAnswer(invocation -> { | ||
return federationEndpoint; | ||
}).when(builder).getFederationEndpoint(); | ||
|
||
// Process tenancyId | ||
doAnswer(invocation -> { | ||
tenancyID = invocation.getArgument(0); | ||
return null; | ||
}).when(builder).tenancyId(any()); | ||
doAnswer(invocation -> { | ||
return tenancyID; | ||
}).when(builder).getTenancyId(); | ||
|
||
return builder; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.