mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-08-28 10:56:02 +00:00
Add ingestionIpInfoEnabled configuration (#10870)
* Add ingestionIpInfoEnabled configuration * Format * hide ip address if api response if not 200 * removing dependancy on ip-modal and checking default state * updated status code for ip to 204 to check default state * fixed failing cypress --------- Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com> Co-authored-by: Shailesh Parmar <shailesh.parmar.webdev@gmail.com>
This commit is contained in:
parent
942649f3b6
commit
cdd473c3b7
@ -244,6 +244,7 @@ pipelineServiceClientConfiguration:
|
|||||||
className: ${PIPELINE_SERVICE_CLIENT_CLASS_NAME:-"org.openmetadata.service.clients.pipeline.airflow.AirflowRESTClient"}
|
className: ${PIPELINE_SERVICE_CLIENT_CLASS_NAME:-"org.openmetadata.service.clients.pipeline.airflow.AirflowRESTClient"}
|
||||||
apiEndpoint: ${PIPELINE_SERVICE_CLIENT_ENDPOINT:-http://localhost:8080}
|
apiEndpoint: ${PIPELINE_SERVICE_CLIENT_ENDPOINT:-http://localhost:8080}
|
||||||
metadataApiEndpoint: ${SERVER_HOST_API_URL:-http://localhost:8585/api}
|
metadataApiEndpoint: ${SERVER_HOST_API_URL:-http://localhost:8585/api}
|
||||||
|
ingestionIpInfoEnabled: ${PIPELINE_SERVICE_IP_INFO_ENABLED:-false}
|
||||||
hostIp: ${PIPELINE_SERVICE_CLIENT_HOST_IP:-""}
|
hostIp: ${PIPELINE_SERVICE_CLIENT_HOST_IP:-""}
|
||||||
verifySSL: ${PIPELINE_SERVICE_CLIENT_VERIFY_SSL:-"no-ssl"} # Possible values are "no-ssl", "ignore", "validate"
|
verifySSL: ${PIPELINE_SERVICE_CLIENT_VERIFY_SSL:-"no-ssl"} # Possible values are "no-ssl", "ignore", "validate"
|
||||||
sslConfig:
|
sslConfig:
|
||||||
|
@ -526,8 +526,7 @@ public class IngestionPipelineResource extends EntityResource<IngestionPipeline,
|
|||||||
content = @Content(mediaType = "application/json"))
|
content = @Content(mediaType = "application/json"))
|
||||||
})
|
})
|
||||||
public Response getHostIp(@Context UriInfo uriInfo, @Context SecurityContext securityContext) {
|
public Response getHostIp(@Context UriInfo uriInfo, @Context SecurityContext securityContext) {
|
||||||
Map<String, String> hostIp = pipelineServiceClient.getHostIp();
|
return pipelineServiceClient.getHostIp();
|
||||||
return Response.ok(hostIp, MediaType.APPLICATION_JSON_TYPE).build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
@ -22,6 +22,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.openmetadata.common.utils.CommonUtil;
|
import org.openmetadata.common.utils.CommonUtil;
|
||||||
@ -50,6 +51,8 @@ import org.openmetadata.sdk.exception.PipelineServiceVersionException;
|
|||||||
public abstract class PipelineServiceClient {
|
public abstract class PipelineServiceClient {
|
||||||
protected final String hostIp;
|
protected final String hostIp;
|
||||||
|
|
||||||
|
protected final boolean ingestionIpInfoEnabled;
|
||||||
|
|
||||||
protected static final String AUTH_HEADER = "Authorization";
|
protected static final String AUTH_HEADER = "Authorization";
|
||||||
protected static final String CONTENT_HEADER = "Content-Type";
|
protected static final String CONTENT_HEADER = "Content-Type";
|
||||||
protected static final String CONTENT_TYPE = "application/json";
|
protected static final String CONTENT_TYPE = "application/json";
|
||||||
@ -87,6 +90,7 @@ public abstract class PipelineServiceClient {
|
|||||||
|
|
||||||
public PipelineServiceClient(PipelineServiceClientConfiguration pipelineServiceClientConfiguration) {
|
public PipelineServiceClient(PipelineServiceClientConfiguration pipelineServiceClientConfiguration) {
|
||||||
this.hostIp = pipelineServiceClientConfiguration.getHostIp();
|
this.hostIp = pipelineServiceClientConfiguration.getHostIp();
|
||||||
|
this.ingestionIpInfoEnabled = pipelineServiceClientConfiguration.getIngestionIpInfoEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final URL validateServiceURL(String serviceURL) {
|
public final URL validateServiceURL(String serviceURL) {
|
||||||
@ -128,15 +132,28 @@ public abstract class PipelineServiceClient {
|
|||||||
return getVersionFromString(clientVersion).equals(getVersionFromString(SERVER_VERSION));
|
return getVersionFromString(clientVersion).equals(getVersionFromString(SERVER_VERSION));
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Map<String, String> getHostIp() {
|
public final Response getHostIp() {
|
||||||
|
|
||||||
|
if (this.ingestionIpInfoEnabled) {
|
||||||
|
return getHostIpInternal();
|
||||||
|
}
|
||||||
|
return Response.status(Response.Status.NO_CONTENT).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Response getHostIpInternal() {
|
||||||
|
Map<String, String> body;
|
||||||
try {
|
try {
|
||||||
return CommonUtil.nullOrEmpty(this.hostIp) ? requestGetHostIp() : Map.of("ip", this.hostIp);
|
body = CommonUtil.nullOrEmpty(this.hostIp) ? requestGetHostIp() : Map.of("ip", this.hostIp);
|
||||||
|
return Response.ok(body, MediaType.APPLICATION_JSON_TYPE).build();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.error("Failed to get Pipeline Service host IP. {}", e.getMessage());
|
LOG.error("Failed to get Pipeline Service host IP. {}", e.getMessage());
|
||||||
return Map.of(
|
// We don't want the request to fail for an informative ping
|
||||||
"ip",
|
body =
|
||||||
"Failed to find the IP of Airflow Container. Please make sure https://api.ipify.org, "
|
Map.of(
|
||||||
+ "https://api.my-ip.io/ip reachable from your network or that the `hostIp` setting is configured.");
|
"ip",
|
||||||
|
"Failed to find the IP of Airflow Container. Please make sure https://api.ipify.org, "
|
||||||
|
+ "https://api.my-ip.io/ip reachable from your network or that the `hostIp` setting is configured.");
|
||||||
|
return Response.ok(body, MediaType.APPLICATION_JSON_TYPE).build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,11 @@
|
|||||||
"description": "Pipeline Service Client host IP that will be used to connect to the sources.",
|
"description": "Pipeline Service Client host IP that will be used to connect to the sources.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"ingestionIpInfoEnabled": {
|
||||||
|
"description": "Enable or disable the API that fetches the public IP running the ingestion process.",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
"metadataApiEndpoint": {
|
"metadataApiEndpoint": {
|
||||||
"description": "Metadata api endpoint, e.g., `http://localhost:8585/api`",
|
"description": "Metadata api endpoint, e.g., `http://localhost:8585/api`",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
@ -181,13 +181,15 @@ export const testServiceCreationAndIngestion = (
|
|||||||
|
|
||||||
// Enter service name in step 3
|
// Enter service name in step 3
|
||||||
cy.get('[data-testid="service-name"]').should('exist').type(serviceName);
|
cy.get('[data-testid="service-name"]').should('exist').type(serviceName);
|
||||||
|
interceptURL('GET', '/api/v1/services/ingestionPipelines/ip', 'ipApi');
|
||||||
interceptURL(
|
interceptURL(
|
||||||
'GET',
|
'GET',
|
||||||
'api/v1/services/ingestionPipelines/*',
|
'api/v1/services/ingestionPipelines/*',
|
||||||
'getIngestionPipelineStatus'
|
'ingestionPipelineStatus'
|
||||||
);
|
);
|
||||||
cy.get('[data-testid="next-button"]').should('exist').click();
|
cy.get('[data-testid="next-button"]').should('exist').click();
|
||||||
verifyResponseStatusCode('@getIngestionPipelineStatus', 200);
|
verifyResponseStatusCode('@ingestionPipelineStatus', 200);
|
||||||
|
verifyResponseStatusCode('@ipApi', 204);
|
||||||
|
|
||||||
// Connection Details in step 4
|
// Connection Details in step 4
|
||||||
cy.get('[data-testid="add-new-service-container"]')
|
cy.get('[data-testid="add-new-service-container"]')
|
||||||
@ -200,9 +202,6 @@ export const testServiceCreationAndIngestion = (
|
|||||||
|
|
||||||
connectionInput();
|
connectionInput();
|
||||||
|
|
||||||
// check for the ip-address widget
|
|
||||||
cy.get('[data-testid="ip-address"]').should('exist');
|
|
||||||
|
|
||||||
// Test the connection
|
// Test the connection
|
||||||
interceptURL(
|
interceptURL(
|
||||||
'GET',
|
'GET',
|
||||||
|
@ -67,12 +67,16 @@ const FormBuilder: FunctionComponent<Props> = ({
|
|||||||
formatFormDataForRender(formData ?? {})
|
formatFormDataForRender(formData ?? {})
|
||||||
);
|
);
|
||||||
|
|
||||||
const [hostIp, setHostIp] = useState<string>('[fetching]');
|
const [hostIp, setHostIp] = useState<string>();
|
||||||
|
|
||||||
const fetchHostIp = async () => {
|
const fetchHostIp = async () => {
|
||||||
try {
|
try {
|
||||||
const data = await getPipelineServiceHostIp();
|
const { status, data } = await getPipelineServiceHostIp();
|
||||||
setHostIp(data?.ip || '[unknown]');
|
if (status === 200) {
|
||||||
|
setHostIp(data?.ip || '[unknown]');
|
||||||
|
} else {
|
||||||
|
setHostIp(undefined);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setHostIp('[error - unknown]');
|
setHostIp('[error - unknown]');
|
||||||
}
|
}
|
||||||
@ -136,7 +140,7 @@ const FormBuilder: FunctionComponent<Props> = ({
|
|||||||
{t('message.no-config-available')}
|
{t('message.no-config-available')}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{!isEmpty(schema) && isAirflowAvailable && (
|
{!isEmpty(schema) && isAirflowAvailable && hostIp && (
|
||||||
<div
|
<div
|
||||||
className="tw-flex tw-justify-between tw-bg-white tw-border tw-border-main tw-shadow tw-rounded tw-p-3 tw-mt-4"
|
className="tw-flex tw-justify-between tw-bg-white tw-border tw-border-main tw-shadow tw-rounded tw-p-3 tw-mt-4"
|
||||||
data-testid="ip-address">
|
data-testid="ip-address">
|
||||||
|
@ -153,7 +153,7 @@ export const getPipelineServiceHostIp = async () => {
|
|||||||
'/services/ingestionPipelines/ip'
|
'/services/ingestionPipelines/ip'
|
||||||
);
|
);
|
||||||
|
|
||||||
return response.data;
|
return response;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getIngestionPipelineLogById = (id: string, after?: string) => {
|
export const getIngestionPipelineLogById = (id: string, after?: string) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user