diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index cc605356..04076438 100755 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -65,7 +65,7 @@ jobs: id: docker_meta uses: docker/metadata-action@v4 with: - images: opensrp/fhir-access-proxy + images: opensrp/fhir-gateway - name: Login to DockerHub uses: docker/login-action@v2 diff --git a/Dockerfile b/Dockerfile index f61c4bd6..400c1255 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,7 @@ # # Image for building and running tests against the source code of -# the FHIR Access Proxy. +# the FHIR Gateway. FROM maven:3.8.5-openjdk-11 as build RUN apt-get update && apt-get install -y nodejs npm @@ -37,7 +37,7 @@ RUN mvn spotless:check RUN mvn --batch-mode package -Pstandalone-app -Dlicense.skip=true -# Image for FHIR Access Proxy binary with configuration knobs as environment vars. +# Image for FHIR Gateway binary with configuration knobs as environment vars. FROM eclipse-temurin:11-jdk-focal as main COPY --from=build /app/exec/target/exec-0.1.1.jar / diff --git a/README.md b/README.md index 90ad6d36..971363cb 100644 --- a/README.md +++ b/README.md @@ -164,7 +164,7 @@ The proxy is also available as a [docker image](Dockerfile): ```shell $ docker run -p 8081:8080 -e TOKEN_ISSUER=[token_issuer_url] \ -e PROXY_TO=[fhir_server_url] -e ACCESS_CHECKER=list \ - us-docker.pkg.dev/fhir-proxy-build/stable/fhir-access-proxy:latest + us-docker.pkg.dev/fhir-proxy-build/stable/fhir-gateway:latest ``` Note if the `TOKEN_ISSUER` is on the `localhost` you may need to bypass proxy's diff --git a/build.sh b/build.sh index 8b3bbc3b..268c10b8 100755 --- a/build.sh +++ b/build.sh @@ -28,4 +28,4 @@ set -e export BUILD_ID=${KOKORO_BUILD_ID:-local} gcloud auth configure-docker us-docker.pkg.dev ./e2e-test/e2e.sh -docker push us-docker.pkg.dev/fhir-proxy-build/stable/fhir-access-proxy:${BUILD_ID} +docker push us-docker.pkg.dev/fhir-proxy-build/stable/fhir-gateway:${BUILD_ID} diff --git a/charts/fhir-access-proxy/.helmignore b/charts/fhir-gateway/.helmignore similarity index 100% rename from charts/fhir-access-proxy/.helmignore rename to charts/fhir-gateway/.helmignore diff --git a/charts/fhir-access-proxy/Chart.yaml b/charts/fhir-gateway/Chart.yaml similarity index 98% rename from charts/fhir-access-proxy/Chart.yaml rename to charts/fhir-gateway/Chart.yaml index 287276ff..29e5beec 100644 --- a/charts/fhir-access-proxy/Chart.yaml +++ b/charts/fhir-gateway/Chart.yaml @@ -15,7 +15,7 @@ # apiVersion: v2 -name: fhir-access-proxy +name: fhir-gateway description: | This is a simple access-control proxy that sits in front of a [FHIR](https://www.hl7.org/fhir/) store (e.g., a diff --git a/charts/fhir-access-proxy/README.md b/charts/fhir-gateway/README.md similarity index 93% rename from charts/fhir-access-proxy/README.md rename to charts/fhir-gateway/README.md index d4f3c9d4..487aff6a 100644 --- a/charts/fhir-access-proxy/README.md +++ b/charts/fhir-gateway/README.md @@ -1,18 +1,18 @@ -# FHIR Access Proxy +# FHIR Gateway -[FHIR Access Proxy](../../README.md) is a simple access-control proxy that sits -in front of FHIR store and server and controls access to FHIR resources. +[FHIR Gateway](../../README.md) is a simple access-control proxy that sits in +front of FHIR store and server and controls access to FHIR resources. ## TL;DR ```bash -helm repo add opensrp-fhir-access-proxy https://fhir-access-proxy.helm.smartregister.org && -helm install fhir-access-proxy opensrp-fhir-access-proxy/fhir-access-proxy +helm repo add opensrp-fhir-gateway https://fhir-gateway.helm.smartregister.org && +helm install fhir-gateway opensrp-fhir-gateway/fhir-gateway ``` ## Introduction -This chart bootstraps [fhir access proxy](../../README.md) deployment on a +This chart bootstraps [FHIR Gateway](../../README.md) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. @@ -23,19 +23,19 @@ package manager. ## Installing the Chart -To install the chart with the release name `fhir-access-proxy`: +To install the chart with the release name `fhir-gateway`: ```shell -helm repo add opensrp-fhir-access-proxy https://fhir-access-proxy.helm.smartregister.org && -helm install fhir-access-proxy opensrp-fhir-access-proxy/fhir-access-proxy +helm repo add opensrp-fhir-gateway https://fhir-gateway.helm.smartregister.org && +helm install fhir-gateway opensrp-fhir-gateway/fhir-gateway ``` ## Uninstalling the Chart -To uninstall/delete the `fhir-access-proxy` deployment: +To uninstall/delete the `fhir-gateway` deployment: ```shell -helm delete fhir-access-proxy +helm delete fhir-gateway ``` The command removes all the Kubernetes components associated with the chart and @@ -43,15 +43,15 @@ deletes the release. ## Parameters -The following table lists the configurable parameters of the fhir access proxy -chart and their default values. +The following table lists the configurable parameters of the FHIR Gateway chart +and their default values. ## Common Parameters | Parameter | Description | Default | | -------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `replicaCount` | | `1` | -| `image.repository` | | `"opensrp/fhir-access-proxy"` | +| `image.repository` | | `"opensrp/fhir-gateway"` | | `image.pullPolicy` | | `"IfNotPresent"` | | `image.tag` | | `"latest"` | | `imagePullSecrets` | | `[]` | @@ -68,7 +68,7 @@ chart and their default values. | `ingress.enabled` | | `false` | | `ingress.className` | | `""` | | `ingress.annotations` | | `{}` | -| `ingress.hosts` | | `[{"host": "fhir-access-proxy.local", "paths": [{"path": "/", "pathType": "ImplementationSpecific"}]}]` | +| `ingress.hosts` | | `[{"host": "fhir-gateway.local", "paths": [{"path": "/", "pathType": "ImplementationSpecific"}]}]` | | `ingress.tls` | | `[]` | | `resources` | | `{}` | | `autoscaling.enabled` | | `false` | @@ -130,15 +130,14 @@ file). 2. Create a configmap volume type: - The name of the configMap resemble the ConfigMap manifest metadata.name - i.e. `fhir-access-proxy` but we obtain the generated name from the - function `'{{ include "fhir-access-proxy.fullname" . }}'` using tpl - function. + i.e. `fhir-gateway` but we obtain the generated name from the function + `'{{ include "fhir-gateway.fullname" . }}'` using tpl function. ```yaml volumes: - name: hapi-page-url-allowed-queries configMap: - name: '{{ include "fhir-access-proxy.fullname" . }}' + name: '{{ include "fhir-gateway.fullname" . }}' ``` 3. Mount the Configmap volume: diff --git a/charts/fhir-access-proxy/templates/NOTES.txt b/charts/fhir-gateway/templates/NOTES.txt similarity index 75% rename from charts/fhir-access-proxy/templates/NOTES.txt rename to charts/fhir-gateway/templates/NOTES.txt index 1ddb7f19..56934576 100644 --- a/charts/fhir-access-proxy/templates/NOTES.txt +++ b/charts/fhir-gateway/templates/NOTES.txt @@ -6,16 +6,16 @@ {{- end }} {{- end }} {{- else if contains "NodePort" .Values.service.type }} - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "fhir-access-proxy.fullname" . }}) + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "fhir-gateway.fullname" . }}) export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") echo http://$NODE_IP:$NODE_PORT {{- else if contains "LoadBalancer" .Values.service.type }} NOTE: It may take a few minutes for the LoadBalancer IP to be available. - You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "fhir-access-proxy.fullname" . }}' - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "fhir-access-proxy.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "fhir-gateway.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "fhir-gateway.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") echo http://$SERVICE_IP:{{ .Values.service.port }} {{- else if contains "ClusterIP" .Values.service.type }} - export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "fhir-access-proxy.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "fhir-gateway.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") echo "Visit http://127.0.0.1:8080 to use your application" kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT diff --git a/charts/fhir-access-proxy/templates/_helpers.tpl b/charts/fhir-gateway/templates/_helpers.tpl similarity index 74% rename from charts/fhir-access-proxy/templates/_helpers.tpl rename to charts/fhir-gateway/templates/_helpers.tpl index 1f36d648..99e93ac2 100644 --- a/charts/fhir-access-proxy/templates/_helpers.tpl +++ b/charts/fhir-gateway/templates/_helpers.tpl @@ -1,7 +1,7 @@ {{/* Expand the name of the chart. */}} -{{- define "fhir-access-proxy.name" -}} +{{- define "fhir-gateway.name" -}} {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} {{- end }} @@ -10,7 +10,7 @@ Create a default fully qualified app name. We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). If release name contains chart name it will be used as a full name. */}} -{{- define "fhir-access-proxy.fullname" -}} +{{- define "fhir-gateway.fullname" -}} {{- if .Values.fullnameOverride }} {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} {{- else }} @@ -26,16 +26,16 @@ If release name contains chart name it will be used as a full name. {{/* Create chart name and version as used by the chart label. */}} -{{- define "fhir-access-proxy.chart" -}} +{{- define "fhir-gateway.chart" -}} {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} {{- end }} {{/* Common labels */}} -{{- define "fhir-access-proxy.labels" -}} -helm.sh/chart: {{ include "fhir-access-proxy.chart" . }} -{{ include "fhir-access-proxy.selectorLabels" . }} +{{- define "fhir-gateway.labels" -}} +helm.sh/chart: {{ include "fhir-gateway.chart" . }} +{{ include "fhir-gateway.selectorLabels" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} @@ -45,17 +45,17 @@ app.kubernetes.io/managed-by: {{ .Release.Service }} {{/* Selector labels */}} -{{- define "fhir-access-proxy.selectorLabels" -}} -app.kubernetes.io/name: {{ include "fhir-access-proxy.name" . }} +{{- define "fhir-gateway.selectorLabels" -}} +app.kubernetes.io/name: {{ include "fhir-gateway.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }} {{/* Create the name of the service account to use */}} -{{- define "fhir-access-proxy.serviceAccountName" -}} +{{- define "fhir-gateway.serviceAccountName" -}} {{- if .Values.serviceAccount.create }} -{{- default (include "fhir-access-proxy.fullname" .) .Values.serviceAccount.name }} +{{- default (include "fhir-gateway.fullname" .) .Values.serviceAccount.name }} {{- else }} {{- default "default" .Values.serviceAccount.name }} {{- end }} @@ -64,7 +64,7 @@ Create the name of the service account to use {{/* Populate the pod annotations */}} -{{- define "fhir-access-proxy.podAnnotations" -}} +{{- define "fhir-gateway.podAnnotations" -}} {{- range $index, $element:=.Values.podAnnotations }} {{ $index }}: {{ $element | quote }} {{- end }} diff --git a/charts/fhir-access-proxy/templates/configmap.yaml b/charts/fhir-gateway/templates/configmap.yaml similarity index 87% rename from charts/fhir-access-proxy/templates/configmap.yaml rename to charts/fhir-gateway/templates/configmap.yaml index b1338c44..563cc7cc 100644 --- a/charts/fhir-access-proxy/templates/configmap.yaml +++ b/charts/fhir-gateway/templates/configmap.yaml @@ -18,9 +18,9 @@ apiVersion: v1 kind: ConfigMap metadata: - name: {{ include "fhir-access-proxy.fullname" . }} + name: {{ include "fhir-gateway.fullname" . }} labels: - {{- include "fhir-access-proxy.labels" . | nindent 4 }} + {{- include "fhir-gateway.labels" . | nindent 4 }} data: {{ range $value := .Values.configMaps -}} {{ $value.name }}: | diff --git a/charts/fhir-access-proxy/templates/deployment.yaml b/charts/fhir-gateway/templates/deployment.yaml similarity index 86% rename from charts/fhir-access-proxy/templates/deployment.yaml rename to charts/fhir-gateway/templates/deployment.yaml index 792b64b0..74221419 100644 --- a/charts/fhir-access-proxy/templates/deployment.yaml +++ b/charts/fhir-gateway/templates/deployment.yaml @@ -17,28 +17,28 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: {{ include "fhir-access-proxy.fullname" . }} + name: {{ include "fhir-gateway.fullname" . }} labels: - {{- include "fhir-access-proxy.labels" . | nindent 4 }} + {{- include "fhir-gateway.labels" . | nindent 4 }} spec: {{- if not .Values.autoscaling.enabled }} replicas: {{ .Values.replicaCount }} {{- end }} selector: matchLabels: - {{- include "fhir-access-proxy.selectorLabels" . | nindent 6 }} + {{- include "fhir-gateway.selectorLabels" . | nindent 6 }} template: metadata: annotations: - {{- include "fhir-access-proxy.podAnnotations" . | indent 8 }} + {{- include "fhir-gateway.podAnnotations" . | indent 8 }} labels: - {{- include "fhir-access-proxy.selectorLabels" . | nindent 8 }} + {{- include "fhir-gateway.selectorLabels" . | nindent 8 }} spec: {{- with .Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} - serviceAccountName: {{ include "fhir-access-proxy.serviceAccountName" . }} + serviceAccountName: {{ include "fhir-gateway.serviceAccountName" . }} securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} volumes: diff --git a/charts/fhir-access-proxy/templates/hpa.yaml b/charts/fhir-gateway/templates/hpa.yaml similarity index 89% rename from charts/fhir-access-proxy/templates/hpa.yaml rename to charts/fhir-gateway/templates/hpa.yaml index 6033e944..5c2b58c8 100644 --- a/charts/fhir-access-proxy/templates/hpa.yaml +++ b/charts/fhir-gateway/templates/hpa.yaml @@ -18,14 +18,14 @@ apiVersion: autoscaling/v2beta1 kind: HorizontalPodAutoscaler metadata: - name: {{ include "fhir-access-proxy.fullname" . }} + name: {{ include "fhir-gateway.fullname" . }} labels: - {{- include "fhir-access-proxy.labels" . | nindent 4 }} + {{- include "fhir-gateway.labels" . | nindent 4 }} spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment - name: {{ include "fhir-access-proxy.fullname" . }} + name: {{ include "fhir-gateway.fullname" . }} minReplicas: {{ .Values.autoscaling.minReplicas }} maxReplicas: {{ .Values.autoscaling.maxReplicas }} metrics: diff --git a/charts/fhir-access-proxy/templates/ingress.yaml b/charts/fhir-gateway/templates/ingress.yaml similarity index 95% rename from charts/fhir-access-proxy/templates/ingress.yaml rename to charts/fhir-gateway/templates/ingress.yaml index dd266a8b..a30bcc93 100644 --- a/charts/fhir-access-proxy/templates/ingress.yaml +++ b/charts/fhir-gateway/templates/ingress.yaml @@ -16,7 +16,7 @@ {{ if .Values.ingress.enabled -}} -{{- $fullName := include "fhir-access-proxy.fullname" . -}} +{{- $fullName := include "fhir-gateway.fullname" . -}} {{- $svcPort := .Values.service.port -}} {{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} @@ -34,7 +34,7 @@ kind: Ingress metadata: name: {{ $fullName }} labels: - {{- include "fhir-access-proxy.labels" . | nindent 4 }} + {{- include "fhir-gateway.labels" . | nindent 4 }} {{- with .Values.ingress.annotations }} annotations: {{- toYaml . | nindent 4 }} diff --git a/charts/fhir-access-proxy/templates/pdb.yaml b/charts/fhir-gateway/templates/pdb.yaml similarity index 85% rename from charts/fhir-access-proxy/templates/pdb.yaml rename to charts/fhir-gateway/templates/pdb.yaml index 704c0fa8..17504f2d 100644 --- a/charts/fhir-access-proxy/templates/pdb.yaml +++ b/charts/fhir-gateway/templates/pdb.yaml @@ -22,9 +22,9 @@ apiVersion: "policy/v1" {{- end }} kind: PodDisruptionBudget metadata: - name: {{ include "fhir-access-proxy.fullname" . }} + name: {{ include "fhir-gateway.fullname" . }} labels: - {{- include "fhir-access-proxy.labels" . | nindent 4 }} + {{- include "fhir-gateway.labels" . | nindent 4 }} spec: {{- if .Values.pdb.minAvailable }} minAvailable: {{ .Values.pdb.minAvailable }} @@ -34,5 +34,5 @@ spec: {{- end }} selector: matchLabels: - {{- include "fhir-access-proxy.selectorLabels" . | nindent 6 }} + {{- include "fhir-gateway.selectorLabels" . | nindent 6 }} {{- end }} diff --git a/charts/fhir-access-proxy/templates/service.yaml b/charts/fhir-gateway/templates/service.yaml similarity index 81% rename from charts/fhir-access-proxy/templates/service.yaml rename to charts/fhir-gateway/templates/service.yaml index e05420ad..f367b062 100644 --- a/charts/fhir-access-proxy/templates/service.yaml +++ b/charts/fhir-gateway/templates/service.yaml @@ -17,9 +17,9 @@ apiVersion: v1 kind: Service metadata: - name: {{ include "fhir-access-proxy.fullname" . }} + name: {{ include "fhir-gateway.fullname" . }} labels: - {{- include "fhir-access-proxy.labels" . | nindent 4 }} + {{- include "fhir-gateway.labels" . | nindent 4 }} spec: type: {{ .Values.service.type }} ports: @@ -28,4 +28,4 @@ spec: protocol: TCP name: http selector: - {{- include "fhir-access-proxy.selectorLabels" . | nindent 4 }} + {{- include "fhir-gateway.selectorLabels" . | nindent 4 }} diff --git a/charts/fhir-access-proxy/templates/serviceaccount.yaml b/charts/fhir-gateway/templates/serviceaccount.yaml similarity index 86% rename from charts/fhir-access-proxy/templates/serviceaccount.yaml rename to charts/fhir-gateway/templates/serviceaccount.yaml index f89bec66..c0fdd270 100644 --- a/charts/fhir-access-proxy/templates/serviceaccount.yaml +++ b/charts/fhir-gateway/templates/serviceaccount.yaml @@ -18,9 +18,9 @@ apiVersion: v1 kind: ServiceAccount metadata: - name: {{ include "fhir-access-proxy.serviceAccountName" . }} + name: {{ include "fhir-gateway.serviceAccountName" . }} labels: - {{- include "fhir-access-proxy.labels" . | nindent 4 }} + {{- include "fhir-gateway.labels" . | nindent 4 }} {{- with .Values.serviceAccount.annotations }} annotations: {{- toYaml . | nindent 4 }} diff --git a/charts/fhir-access-proxy/templates/tests/test-connection.yaml b/charts/fhir-gateway/templates/tests/test-connection.yaml similarity index 77% rename from charts/fhir-access-proxy/templates/tests/test-connection.yaml rename to charts/fhir-gateway/templates/tests/test-connection.yaml index 9c4373b8..022c4230 100644 --- a/charts/fhir-access-proxy/templates/tests/test-connection.yaml +++ b/charts/fhir-gateway/templates/tests/test-connection.yaml @@ -17,9 +17,9 @@ apiVersion: v1 kind: Pod metadata: - name: "{{ include "fhir-access-proxy.fullname" . }}-test-connection" + name: "{{ include "fhir-gateway.fullname" . }}-test-connection" labels: - {{- include "fhir-access-proxy.labels" . | nindent 4 }} + {{- include "fhir-gateway.labels" . | nindent 4 }} annotations: "helm.sh/hook": test spec: @@ -27,5 +27,5 @@ spec: - name: wget image: busybox command: ['wget'] - args: ['{{ include "fhir-access-proxy.fullname" . }}:{{ .Values.service.port }}'] + args: ['{{ include "fhir-gateway.fullname" . }}:{{ .Values.service.port }}'] restartPolicy: Never diff --git a/charts/fhir-access-proxy/templates/vpa.yaml b/charts/fhir-gateway/templates/vpa.yaml similarity index 85% rename from charts/fhir-access-proxy/templates/vpa.yaml rename to charts/fhir-gateway/templates/vpa.yaml index 015aa103..7dd1c0fa 100644 --- a/charts/fhir-access-proxy/templates/vpa.yaml +++ b/charts/fhir-gateway/templates/vpa.yaml @@ -18,14 +18,14 @@ apiVersion: "autoscaling.k8s.io/v1" kind: VerticalPodAutoscaler metadata: - name: {{ include "fhir-access-proxy.fullname" . }} + name: {{ include "fhir-gateway.fullname" . }} labels: - {{- include "fhir-access-proxy.labels" . | nindent 4 }} + {{- include "fhir-gateway.labels" . | nindent 4 }} spec: targetRef: apiVersion: "apps/v1" kind: Deployment - name: {{ include "fhir-access-proxy.fullname" . }} + name: {{ include "fhir-gateway.fullname" . }} updatePolicy: {{- toYaml .Values.vpa.updatePolicy | nindent 4 }} {{- if .Values.vpa.resourcePolicy }} diff --git a/charts/fhir-access-proxy/values.yaml b/charts/fhir-gateway/values.yaml similarity index 95% rename from charts/fhir-access-proxy/values.yaml rename to charts/fhir-gateway/values.yaml index 2f45fdab..0572283c 100644 --- a/charts/fhir-access-proxy/values.yaml +++ b/charts/fhir-gateway/values.yaml @@ -14,14 +14,14 @@ # limitations under the License. # -# Default values for fhir-access-proxy. +# Default values for fhir-gateway. # This is a YAML-formatted file. # Declare variables to be passed into your templates. replicaCount: 1 image: - repository: opensrp/fhir-access-proxy + repository: opensrp/fhir-gateway pullPolicy: IfNotPresent # Overrides the image tag whose default is the chart appVersion. tag: "latest" @@ -63,7 +63,7 @@ ingress: # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" hosts: - - host: fhir-access-proxy.local + - host: fhir-gateway.local paths: - path: / pathType: ImplementationSpecific @@ -114,7 +114,7 @@ initContainers: volumes: # - name: hapi-page-url-allowed-queries # configMap: -# name: '{{ include "fhir-access-proxy.fullname" . }}' +# name: '{{ include "fhir-gateway.fullname" . }}' volumeMounts: diff --git a/doc/design.md b/doc/design.md index 6a5b18ad..a8e3913b 100644 --- a/doc/design.md +++ b/doc/design.md @@ -320,35 +320,35 @@ varies by context. Each of these approaches are described in the following sections. In each case, we briefly describe what is supported in the first release of the access gateway. The "first release" is when we open-sourced the project in June 2022 in -[this GitHub repository](https://github.com/google/fhir-access-proxy). Let's -first look at the architecture of the gateway. There are two main components: +[this GitHub repository](https://github.com/google/fhir-gateway). Let's first +look at the architecture of the gateway. There are two main components: -**[Server](https://github.com/google/fhir-access-proxy/tree/main/server/src/main/java/com/google/fhir/gateway)**: +**[Server](https://github.com/google/fhir-gateway/tree/main/server/src/main/java/com/google/fhir/gateway)**: The core of the access gateway is the "server" which provides a -[servlet](https://github.com/google/fhir-access-proxy/blob/main/server/src/main/java/com/google/fhir/gateway/FhirProxyServer.java) +[servlet](https://github.com/google/fhir-gateway/blob/main/server/src/main/java/com/google/fhir/gateway/FhirProxyServer.java) that processes FHIR queries and an -[authorization interceptor](https://github.com/google/fhir-access-proxy/blob/main/server/src/main/java/com/google/fhir/gateway/BearerAuthorizationInterceptor.java) +[authorization interceptor](https://github.com/google/fhir-gateway/blob/main/server/src/main/java/com/google/fhir/gateway/BearerAuthorizationInterceptor.java) that inspects those. The interceptor decodes and validates the JWT access-token and makes a call to an -[AccessChecker](https://github.com/google/fhir-access-proxy/blob/main/server/src/main/java/com/google/fhir/gateway/interfaces/AccessChecker.java) +[AccessChecker](https://github.com/google/fhir-gateway/blob/main/server/src/main/java/com/google/fhir/gateway/interfaces/AccessChecker.java) plugin to decide whether access should be granted or not. The server also provides common FHIR query/resource processing, e.g., -[PatientFinder](https://github.com/google/fhir-access-proxy/blob/main/server/src/main/java/com/google/fhir/gateway/interfaces/PatientFinder.java) +[PatientFinder](https://github.com/google/fhir-gateway/blob/main/server/src/main/java/com/google/fhir/gateway/interfaces/PatientFinder.java) for finding patient context. These libraries are meant to be used in the plugin implementations. -**[AccessChecker plugin](https://github.com/google/fhir-access-proxy/tree/main/plugins)**: +**[AccessChecker plugin](https://github.com/google/fhir-gateway/tree/main/plugins)**: Each access gateway needs at least one AccessChecker plugin. Gateway implementers can provide their customized access-check logic in this plugin. The server code's initialization finds plugins by looking for -[AccessCheckerFactory](https://github.com/google/fhir-access-proxy/blob/main/server/src/main/java/com/google/fhir/gateway/interfaces/AccessCheckerFactory.java) +[AccessCheckerFactory](https://github.com/google/fhir-gateway/blob/main/server/src/main/java/com/google/fhir/gateway/interfaces/AccessCheckerFactory.java) implementations that are [@Named](https://docs.oracle.com/javaee/7/api/javax/inject/Named.html). The specified name is used to select that plugin at runtime. Example implementations are -[ListAccessChecker](https://github.com/google/fhir-access-proxy/blob/main/plugins/src/main/java/com/google/fhir/gateway/plugin/ListAccessChecker.java) +[ListAccessChecker](https://github.com/google/fhir-gateway/blob/main/plugins/src/main/java/com/google/fhir/gateway/plugin/ListAccessChecker.java) and -[PatientAccessChecker](https://github.com/google/fhir-access-proxy/blob/main/plugins/src/main/java/com/google/fhir/gateway/plugin/PatientAccessChecker.java). +[PatientAccessChecker](https://github.com/google/fhir-gateway/blob/main/plugins/src/main/java/com/google/fhir/gateway/plugin/PatientAccessChecker.java). AccessChecker plugins can send RPCs to other backends if they need to collect extra information. In our examples, the plugins consult with the same FHIR store that resources are pulled from, but you could imagine consulting more hardened @@ -374,7 +374,7 @@ This approach helps support both the **flexible-access-control** and **untrusted-app** items from the [constraints](#scenarios-and-constraints) section. Note to use this approach for access-control, the patient context should be inferred from the FHIR query. The server provides -[a library](https://github.com/google/fhir-access-proxy/blob/main/server/src/main/java/com/google/fhir/gateway/PatientFinderImp.java) +[a library](https://github.com/google/fhir-gateway/blob/main/server/src/main/java/com/google/fhir/gateway/PatientFinderImp.java) for doing this. ### Query templates allowed/blocked list @@ -394,7 +394,7 @@ search results of a previous query. Just from these queries, we cannot decide what the patient context is, so we should let those queries go through (there is a security risk here but since `_getpages` param values are ephemeral UUIDs, this is probably ok). Here is a -[sample config](https://github.com/google/fhir-access-proxy/blob/main/resources/hapi_page_url_allowed_queries.json) +[sample config](https://github.com/google/fhir-gateway/blob/main/resources/hapi_page_url_allowed_queries.json) for this. We note that we want our core "server" to be _stateless_ (for easy scalability); therefore cannot store next/prev URLs from previous query results. @@ -424,11 +424,11 @@ structure of FHIR queries that the gateway accepts). So we still need some restrictions on the permitted queries as mentioned above. Among gateway interfaces, there is -[AccessDecision](https://github.com/google/fhir-access-proxy/blob/main/server/src/main/java/com/google/fhir/gateway/interfaces/AccessDecision.java) +[AccessDecision](https://github.com/google/fhir-gateway/blob/main/server/src/main/java/com/google/fhir/gateway/interfaces/AccessDecision.java) which is returned from a -[checkAccess](https://github.com/google/fhir-access-proxy/blob/85f7c87a26494d4efba5d01904c8c27074eb26a9/server/src/main/java/com/google/fhir/gateway/interfaces/AccessChecker.java#L31). +[checkAccess](https://github.com/google/fhir-gateway/blob/85f7c87a26494d4efba5d01904c8c27074eb26a9/server/src/main/java/com/google/fhir/gateway/interfaces/AccessChecker.java#L31). This interface has a -[postProcess](https://github.com/google/fhir-access-proxy/blob/85f7c87a26494d4efba5d01904c8c27074eb26a9/server/src/main/java/com/google/fhir/gateway/interfaces/AccessDecision.java#L39) +[postProcess](https://github.com/google/fhir-gateway/blob/85f7c87a26494d4efba5d01904c8c27074eb26a9/server/src/main/java/com/google/fhir/gateway/interfaces/AccessDecision.java#L39) method which can be used for post-processing of resources returned from the FHIR server. diff --git a/docker/hapi-proxy-compose.yaml b/docker/hapi-proxy-compose.yaml index bbcbf53e..9e511c38 100644 --- a/docker/hapi-proxy-compose.yaml +++ b/docker/hapi-proxy-compose.yaml @@ -35,7 +35,7 @@ version: "3.0" services: fhir-proxy: - image: us-docker.pkg.dev/fhir-proxy-build/stable/fhir-access-proxy:${BUILD_ID:-latest} + image: us-docker.pkg.dev/fhir-proxy-build/stable/fhir-gateway:${BUILD_ID:-latest} environment: - TOKEN_ISSUER - PROXY_TO diff --git a/e2e-test/e2e.sh b/e2e-test/e2e.sh index 5f4d1b66..724b6a28 100755 --- a/e2e-test/e2e.sh +++ b/e2e-test/e2e.sh @@ -21,7 +21,7 @@ set -e export BUILD_ID=${KOKORO_BUILD_ID:-local} function setup() { - docker build -t us-docker.pkg.dev/fhir-proxy-build/stable/fhir-access-proxy:${BUILD_ID} . + docker build -t us-docker.pkg.dev/fhir-proxy-build/stable/fhir-gateway:${BUILD_ID} . docker-compose -f docker/keycloak/config-compose.yaml \ up --force-recreate --remove-orphans -d --quiet-pull # TODO find a way to expose docker container logs in the output; currently diff --git a/plugins/src/main/java/com/google/fhir/gateway/plugin/AccessGrantedAndUpdateList.java b/plugins/src/main/java/com/google/fhir/gateway/plugin/AccessGrantedAndUpdateList.java index 036dab1f..99cc9fa4 100644 --- a/plugins/src/main/java/com/google/fhir/gateway/plugin/AccessGrantedAndUpdateList.java +++ b/plugins/src/main/java/com/google/fhir/gateway/plugin/AccessGrantedAndUpdateList.java @@ -91,7 +91,7 @@ public String postProcess(HttpResponse response) throws IOException { if (FhirUtil.isSameResourceType(resource.fhirType(), ResourceType.Bundle)) { // TODO Response potentially too large to be loaded into memory; see: - // https://github.com/google/fhir-access-proxy/issues/64 + // https://github.com/google/fhir-gateway/issues/64 Bundle bundle = (Bundle) parser.parseResource(content); Set patientIdsInResponse = Sets.newHashSet(); @@ -114,7 +114,7 @@ public String postProcess(HttpResponse response) throws IOException { private void addPatientToList(String newPatient) throws IOException { Preconditions.checkNotNull(newPatient); // TODO create this with HAPI client instead of handcrafting; see: - // https://github.com/google/fhir-access-proxy/issues/65 + // https://github.com/google/fhir-gateway/issues/65 String jsonPatch = String.format( "[{" @@ -130,7 +130,7 @@ private void addPatientToList(String newPatient) throws IOException { newPatient); logger.info("Updating access list {} with patch {}", patientListId, jsonPatch); // TODO decide how to handle failures in access list updates; see: - // https://github.com/google/fhir-access-proxy/issues/66 + // https://github.com/google/fhir-gateway/issues/66 httpFhirClient.patchResource( String.format("List/%s", PARAM_ESCAPER.escape(patientListId)), jsonPatch); } diff --git a/plugins/src/main/java/com/google/fhir/gateway/plugin/ListAccessChecker.java b/plugins/src/main/java/com/google/fhir/gateway/plugin/ListAccessChecker.java index d42f3337..eda44287 100644 --- a/plugins/src/main/java/com/google/fhir/gateway/plugin/ListAccessChecker.java +++ b/plugins/src/main/java/com/google/fhir/gateway/plugin/ListAccessChecker.java @@ -113,7 +113,7 @@ private boolean serverListIncludesAnyPatient(Set patientIds) { return false; } // TODO consider using the HAPI FHIR client instead; see: - // https://github.com/google/fhir-access-proxy/issues/65. + // https://github.com/google/fhir-gateway/issues/65. String patientParam = queryBuilder(patientIds, PARAM_ESCAPER.escape("Patient/"), PARAM_ESCAPER.escape(",")); return listIncludesItems("item=" + patientParam); @@ -132,7 +132,7 @@ private boolean serverListIncludesAllPatients(Set patientIds) { private boolean patientsExist(String patientId) throws IOException { // TODO consider using the HAPI FHIR client instead; see: - // https://github.com/google/fhir-access-proxy/issues/65 + // https://github.com/google/fhir-gateway/issues/65 String searchQuery = String.format("/Patient?_id=%s&_elements=id", PARAM_ESCAPER.escape(patientId)); HttpResponse response = httpFhirClient.getResource(searchQuery); @@ -235,7 +235,7 @@ private AccessDecision processDelete(RequestDetailsReader requestDetails) { return NoOpAccessDecision.accessDenied(); } - // TODO(https://github.com/google/fhir-access-proxy/issues/63):Support direct resource deletion. + // TODO(https://github.com/google/fhir-gateway/issues/63):Support direct resource deletion. // There should be a patient id in search params; the param name is based on the resource. String patientId = patientFinder.findPatientFromParams(requestDetails); diff --git a/plugins/src/main/java/com/google/fhir/gateway/plugin/PatientAccessChecker.java b/plugins/src/main/java/com/google/fhir/gateway/plugin/PatientAccessChecker.java index 9db77003..d2fc96f8 100644 --- a/plugins/src/main/java/com/google/fhir/gateway/plugin/PatientAccessChecker.java +++ b/plugins/src/main/java/com/google/fhir/gateway/plugin/PatientAccessChecker.java @@ -158,7 +158,7 @@ private AccessDecision processDelete(RequestDetailsReader requestDetails) { if (FhirUtil.isSameResourceType(requestDetails.getResourceName(), ResourceType.Patient)) { return NoOpAccessDecision.accessDenied(); } - // TODO(https://github.com/google/fhir-access-proxy/issues/63):Support direct resource deletion. + // TODO(https://github.com/google/fhir-gateway/issues/63):Support direct resource deletion. String patientId = patientFinder.findPatientFromParams(requestDetails); return new NoOpAccessDecision( authorizedPatientId.equals(patientId) diff --git a/plugins/src/main/java/com/google/fhir/proxy/plugin/PatientAccessChecker.java b/plugins/src/main/java/com/google/fhir/proxy/plugin/PatientAccessChecker.java deleted file mode 100644 index 450cb12f..00000000 --- a/plugins/src/main/java/com/google/fhir/proxy/plugin/PatientAccessChecker.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2021-2023 Google LLC - * - * 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.google.fhir.proxy.plugin; - -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.rest.api.RequestTypeEnum; -import com.auth0.jwt.interfaces.DecodedJWT; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; -import com.google.fhir.gateway.BundlePatients; -import com.google.fhir.gateway.FhirUtil; -import com.google.fhir.gateway.HttpFhirClient; -import com.google.fhir.gateway.JwtUtil; -import com.google.fhir.gateway.interfaces.*; -import java.util.Set; -import javax.inject.Named; -import org.hl7.fhir.r4.model.Bundle.HTTPVerb; -import org.hl7.fhir.r4.model.ResourceType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This access-checker uses the `patient_id` claim in the access token to decide whether access to a - * request should be granted or not. - */ -public class PatientAccessChecker implements AccessChecker { - private static final Logger logger = LoggerFactory.getLogger(PatientAccessChecker.class); - - private final String authorizedPatientId; - private final PatientFinder patientFinder; - - protected PatientAccessChecker(String authorizedPatientId, PatientFinder patientFinder) { - Preconditions.checkNotNull(authorizedPatientId); - Preconditions.checkNotNull(patientFinder); - this.authorizedPatientId = authorizedPatientId; - this.patientFinder = patientFinder; - } - - @Override - public AccessDecision checkAccess(RequestDetailsReader requestDetails) { - - // For a Bundle requestDetails.getResourceName() returns null - if (requestDetails.getRequestType() == RequestTypeEnum.POST - && requestDetails.getResourceName() == null) { - return processBundle(requestDetails); - } - - switch (requestDetails.getRequestType()) { - case GET: - return processGet(requestDetails); - case POST: - return processPost(requestDetails); - case PUT: - return processPut(requestDetails); - case PATCH: - return processPatch(requestDetails); - default: - // TODO handle other cases like DELETE - return NoOpAccessDecision.accessDenied(); - } - } - - private AccessDecision processGet(RequestDetailsReader requestDetails) { - String patientId = patientFinder.findPatientFromParams(requestDetails); - return new NoOpAccessDecision(authorizedPatientId.equals(patientId)); - } - - private AccessDecision processPost(RequestDetailsReader requestDetails) { - // This AccessChecker does not accept new patients. - if (FhirUtil.isSameResourceType(requestDetails.getResourceName(), ResourceType.Patient)) { - return NoOpAccessDecision.accessDenied(); - } - Set patientIds = patientFinder.findPatientsInResource(requestDetails); - return new NoOpAccessDecision(patientIds.contains(authorizedPatientId)); - } - - private AccessDecision processPut(RequestDetailsReader requestDetails) { - if (FhirUtil.isSameResourceType(requestDetails.getResourceName(), ResourceType.Patient)) { - return checkPatientAccessInUpdate(requestDetails); - } - return checkNonPatientAccessInUpdate(requestDetails, HTTPVerb.PUT); - } - - private AccessDecision processPatch(RequestDetailsReader requestDetails) { - if (FhirUtil.isSameResourceType(requestDetails.getResourceName(), ResourceType.Patient)) { - return checkPatientAccessInUpdate(requestDetails); - } - return checkNonPatientAccessInUpdate(requestDetails, HTTPVerb.PATCH); - } - - private AccessDecision checkNonPatientAccessInUpdate( - RequestDetailsReader requestDetails, HTTPVerb updateMethod) { - // We do not allow direct resource PUT/PATCH, so Patient ID must be returned - String patientId = patientFinder.findPatientFromParams(requestDetails); - if (!patientId.equals(authorizedPatientId)) { - return NoOpAccessDecision.accessDenied(); - } - - Set patientIds = Sets.newHashSet(); - if (updateMethod == HTTPVerb.PATCH) { - patientIds = - patientFinder.findPatientsInPatch(requestDetails, requestDetails.getResourceName()); - if (patientIds.isEmpty()) { - return NoOpAccessDecision.accessGranted(); - } - } - if (updateMethod == HTTPVerb.PUT) { - patientIds = patientFinder.findPatientsInResource(requestDetails); - } - return new NoOpAccessDecision(patientIds.contains(authorizedPatientId)); - } - - private AccessDecision checkPatientAccessInUpdate(RequestDetailsReader requestDetails) { - String patientId = FhirUtil.getIdOrNull(requestDetails); - if (patientId == null) { - // This is an invalid PUT request; note we are not supporting "conditional updates". - logger.error("The provided Patient resource has no ID; denying access!"); - return NoOpAccessDecision.accessDenied(); - } - return new NoOpAccessDecision(authorizedPatientId.equals(patientId)); - } - - private AccessDecision processBundle(RequestDetailsReader requestDetails) { - BundlePatients patientsInBundle = patientFinder.findPatientsInBundle(requestDetails); - - if (patientsInBundle == null || patientsInBundle.areTherePatientToCreate()) { - return NoOpAccessDecision.accessDenied(); - } - - if (!patientsInBundle.getUpdatedPatients().isEmpty() - && !patientsInBundle.getUpdatedPatients().equals(ImmutableSet.of(authorizedPatientId))) { - return NoOpAccessDecision.accessDenied(); - } - - for (Set refSet : patientsInBundle.getReferencedPatients()) { - if (!refSet.contains(authorizedPatientId)) { - return NoOpAccessDecision.accessDenied(); - } - } - return NoOpAccessDecision.accessGranted(); - } - - @Named(value = "patient") - static class Factory implements AccessCheckerFactory { - - @VisibleForTesting static final String PATIENT_CLAIM = "patient_id"; - - private String getPatientId(DecodedJWT jwt) { - return FhirUtil.checkIdOrFail(JwtUtil.getClaimOrDie(jwt, PATIENT_CLAIM)); - } - - public AccessChecker create( - DecodedJWT jwt, - HttpFhirClient httpFhirClient, - FhirContext fhirContext, - PatientFinder patientFinder) { - return new PatientAccessChecker(getPatientId(jwt), patientFinder); - } - } -} diff --git a/server/src/main/java/com/google/fhir/gateway/BearerAuthorizationInterceptor.java b/server/src/main/java/com/google/fhir/gateway/BearerAuthorizationInterceptor.java index 3668825c..8a9e5daa 100644 --- a/server/src/main/java/com/google/fhir/gateway/BearerAuthorizationInterceptor.java +++ b/server/src/main/java/com/google/fhir/gateway/BearerAuthorizationInterceptor.java @@ -279,7 +279,7 @@ public boolean authorizeRequest(RequestDetails requestDetails) { HttpResponse response = fhirClient.handleRequest(servletDetails); HttpUtil.validateResponseEntityExistsOrFail(response, requestPath); // TODO communicate post-processing failures to the client; see: - // https://github.com/google/fhir-access-proxy/issues/66 + // https://github.com/google/fhir-gateway/issues/66 String content = null; if (HttpUtil.isResponseValid(response)) { diff --git a/server/src/main/java/com/google/fhir/gateway/HttpFhirClient.java b/server/src/main/java/com/google/fhir/gateway/HttpFhirClient.java index f7c2ba18..4891079f 100644 --- a/server/src/main/java/com/google/fhir/gateway/HttpFhirClient.java +++ b/server/src/main/java/com/google/fhir/gateway/HttpFhirClient.java @@ -63,7 +63,7 @@ public abstract class HttpFhirClient { // https://www.hl7.org/fhir/async.html // We should NOT copy Content-Length as this is automatically set by the RequestBuilder when // setting content Entity; otherwise we will get a ClientProtocolException. - // TODO(https://github.com/google/fhir-access-proxy/issues/60): Allow Accept header + // TODO(https://github.com/google/fhir-gateway/issues/60): Allow Accept header static final Set REQUEST_HEADERS_TO_KEEP = Sets.newHashSet( "content-type", diff --git a/server/src/main/java/com/google/fhir/gateway/PatientFinderImp.java b/server/src/main/java/com/google/fhir/gateway/PatientFinderImp.java index 64423844..13f297a7 100644 --- a/server/src/main/java/com/google/fhir/gateway/PatientFinderImp.java +++ b/server/src/main/java/com/google/fhir/gateway/PatientFinderImp.java @@ -245,7 +245,7 @@ private Set parseReferencesForPatientIds(IBaseResource resource) { public BundlePatients findPatientsInBundle(Bundle bundle) { if (bundle.getType() != BundleType.TRANSACTION) { // Currently, support only for transaction bundles; see: - // https://github.com/google/fhir-access-proxy/issues/67 + // https://github.com/google/fhir-gateway/issues/67 ExceptionUtil.throwRuntimeExceptionAndLog( logger, "Bundle type needs to be transaction!", InvalidRequestException.class); }