-
Notifications
You must be signed in to change notification settings - Fork 19
Introducing Transparent Proxy Builder #851
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
7f3c14b
to
b4355df
Compare
.chainVarSubjectToken("chainVarSubjectToken") | ||
.chainVarSubjectTokenType("chainVarSubjectTokenType") | ||
.chainVarSamlProviderDestinationName("chainVarSamlProviderDestName") | ||
.property(DestinationProperty.URI, "https://example.com") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Question)
I don't understand this. I thought destinations referenced via "Transparent Proxy" would rely on relative URIs not absolute addresses.
It is confusing to me that the following parameters are not required by API design:
- destination name
- namespace
- (relative) URI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe from transparent proxy point of view only destination name is required. The url is designed to be defaulted and the namespace is embedded into the url.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For further review purpose please find the official documentation on Transparent Proxy
https://help.sap.com/docs/connectivity/sap-btp-connectivity-cf/using-transparent-proxy
Please find our current explanation in SAP Cloud SDK
https://sap.github.io/cloud-sdk/docs/java/environments/kubernetes-kyma#executing-requests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the contribution!
Overall, the approach makes sense to me. I noted some open questions that require discussions. I'll create a meeting to go over them together.
private static final String REDIRECT_URI_HEADER_KEY = "x-redirect-uri"; | ||
private static final String CODE_VERIFIER_HEADER_KEY = "x-code-verifier"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some of these headers I'm not sure what exactly they do and if or how they fit into Cloud SDK
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All those headers give different possibilities for consuming destinations using the transparent proxy.
@Override | ||
public Collection<Header> getHeaders( @Nonnull URI requestUri ) | ||
{ | ||
return customHeaders; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have to evaluate how this should interact with static header providers. Probably, those need to be loaded and evaluated.
this.customHeaders = | ||
customHeaders != null ? ImmutableList.<Header> builder().addAll(customHeaders).build() : ImmutableList.of(); | ||
|
||
cachedProxyConfiguration = destinationPropertyFactory.getProxyConfiguration(baseProperties); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if we should set the transparent proxy as a proxy in the HTTP client, or if we should leave it empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
public Option<KeyStore> getKeyStore() | ||
{ | ||
return null; | ||
} | ||
|
||
@Nullable | ||
@Override | ||
public Option<String> getKeyStorePassword() | ||
{ | ||
return null; | ||
} | ||
|
||
@Override | ||
public boolean isTrustingAllCertificates() | ||
{ | ||
return false; | ||
} | ||
|
||
@Nullable | ||
@Override | ||
public Option<BasicCredentials> getBasicCredentials() | ||
{ | ||
return null; | ||
} | ||
|
||
@Nullable | ||
@Override | ||
public AuthenticationType getAuthenticationType() | ||
{ | ||
return null; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These values will likely depend on how connections to the transparent proxy will be secured, and thus might need to be implemented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The transparent proxy is currently deployed as trusted component in trusted environment only and therefore requires no authentication/certificates. Because of this I don't think implementing those methods is needed/necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's up to the user how to authenticate the connection to TP. Currently, TP is only running in K8S, where this is typically done with sidecars. So in that case, users are unlikely to need this functionality. However, TP is also coming to CF, and users may decide to authenticate differently, or want to use some of these methods for other purposes.
For now, I think it's okay to not implement actual logic, leaving these cases unsupported until users request it.
However, returning null
when the method is declared Option<..>
should never be done, so instead, please return Option.none()
and change to @Nonnull
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed all the methods in question to return Option.none()
and be annotated with @Nonnull
.
* Builder class to allow for easy creation of an immutable {@code TransparentProxyDestination} instance. | ||
*/ | ||
@Accessors( fluent = true, chain = true ) | ||
public static class Builder |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As Alex pointed out, the builder should enforce required properties
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe from transparent proxy point of view only destination name is required. The url is designed to be defaulted and the namespace is embedded into the url. I have added enforcement of the destination name.
this.property(DestinationProperty.URI, TRANSPARENT_PROXY_GATEWAY); | ||
} | ||
|
||
TenantAccessor.tryGetCurrentTenant().onSuccess(tenant -> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we have two options on how to handle tenancy:
- Determine the tenant upon building the destination
- Determine the tenant when using the destination
Currently, strategy (1) is applied, but I think (2) better fits the Cloud SDK APIs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the context of the transparent proxy all other header parameters make sense only if the tenant can be determined and basically all transparent proxy operations require tenant. So in this case constructing a TransparentProxyDestination without known tenant seems illogical to me.
.../src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/TransparentProxyDestination.java
Outdated
Show resolved
Hide resolved
@@ -0,0 +1,604 @@ | |||
package com.sap.cloud.sdk.cloudplatform.connectivity; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this functionality is still specific to the destination service, I think this would be more suitable under connectivity-destination-service
module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it more appropriate for the class to reside inside com.sap.cloud.sdk.cloudplatform.connectivity because TransparentProxyDestination implements HttpDestination and is similar to class DefaultHttpDestination, both of which reside inside com.sap.cloud.sdk.cloudplatform.connectivity?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not quite, the modules are split based on generic API vs. destination service specific logic. Since TP conceptually only works with a destination service, it should be in the destination service module
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, moved all the logic into connectivity-destination-service
module.
9b14007
to
06cb15c
Compare
59e0a6a
to
54726e2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks really good! I added some minor suggestions, mostly on test code. But I think we've covered most of the challenging bits 😉
One thing we have to keep in mind: One destination will use one HTTP client. If the tenant is added dynamically per request, the same client will be shared across all tenants.
This is important also for any endpoints that set tenant- or user-specific cookies. For such cases users should build a destination object per request and manually set auth tokens. That way, separate HTTP clients will be used.
.../src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/TransparentProxyDestination.java
Outdated
Show resolved
Hide resolved
.../src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/TransparentProxyDestination.java
Outdated
Show resolved
Hide resolved
.../src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/TransparentProxyDestination.java
Outdated
Show resolved
Hide resolved
.../src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/TransparentProxyDestination.java
Show resolved
Hide resolved
.../src/main/java/com/sap/cloud/sdk/cloudplatform/connectivity/TransparentProxyDestination.java
Outdated
Show resolved
Hide resolved
.../test/java/com/sap/cloud/sdk/cloudplatform/connectivity/TransparentProxyDestinationTest.java
Outdated
Show resolved
Hide resolved
.../test/java/com/sap/cloud/sdk/cloudplatform/connectivity/TransparentProxyDestinationTest.java
Outdated
Show resolved
Hide resolved
.../test/java/com/sap/cloud/sdk/cloudplatform/connectivity/TransparentProxyDestinationTest.java
Show resolved
Hide resolved
.../test/java/com/sap/cloud/sdk/cloudplatform/connectivity/TransparentProxyDestinationTest.java
Outdated
Show resolved
Hide resolved
.../test/java/com/sap/cloud/sdk/cloudplatform/connectivity/TransparentProxyDestinationTest.java
Show resolved
Hide resolved
3477825
to
ea07c40
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes LGTM!
Can you please add a release note entry here: https://github.com/SAP/cloud-sdk-java/blob/main/release_notes.md?plain=1#L13
it should briefly state the new feature and link to the docs page (even if the docs page doesn't exist yet, please put the expected URL)
ea07c40
to
121f01f
Compare
Context
This PR adds support for consuming systems in Cloud SDK applications leveraging the Transparent Proxy for new destination features and on-premise connectivity.
Feature scope:
Definition of Done
Error handling created / updated & covered by the tests aboveDocumentation updatedRelease notes updated