Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .github/workflows/.build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
on:
workflow_call:
inputs:
name:
required: true
type: string
context:
required: true
type: string
default: '.'

jobs:
build-image:
runs-on: ubuntu-latest
env:
GITHUB_TOKEN: ${{ github.token }}
steps:
- uses: actions/checkout@v7

- name: Image meta
id: meta
uses: docker/metadata-action@v6
with:
images: ghcr.io/${{ github.repository }}/${{ inputs.name }}

- name: Set DEPLOY_ID
run: |
echo "DEPLOY_ID=${{ steps.meta.outputs.version }}" >> "$GITHUB_OUTPUT"
echo "APP_VERSION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }}" >> "$GITHUB_OUTPUT"
echo "APP_REVISION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }}" >> "$GITHUB_OUTPUT"
id: set-deploy-id

- name: Get deploy ID
run: echo "The DEPLOY_ID is ${{ steps.set-deploy-id.outputs.DEPLOY_ID }}"

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4

- name: Set up QEMU
uses: docker/setup-qemu-action@v4

- name: Log in to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
logout: false

- name: Create image
uses: docker/build-push-action@v7
with:
context: ${{ inputs.context }}
file: ${{ inputs.context }}/Dockerfile
push: true
platforms: linux/amd64,linux/arm64
build-args: |
APP_VERSION=${{ steps.set-deploy-id.outputs.APP_VERSION }}
APP_REVISION=${{ steps.set-deploy-id.outputs.APP_REVISION }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
42 changes: 42 additions & 0 deletions .github/workflows/ape.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: All APE Functions

on:
push:
branches: [feature/*]

jobs:
build-opal-pip-catalog:
uses: ./.github/workflows/.build.yml
permissions:
contents: read
packages: write # 🚀 Crucial permission needed to push to ghcr.io
with:
name: opal-pip-catalog
context: ./sdx/ape/functions/opal-pip-catalog

build-opal-policies:
uses: ./.github/workflows/.build.yml
permissions:
contents: read
packages: write # 🚀 Crucial permission needed to push to ghcr.io
with:
name: opal-policies
context: ./sdx/ape/functions/opal-policies

build-pubsub-kafka:
uses: ./.github/workflows/.build.yml
permissions:
contents: read
packages: write # 🚀 Crucial permission needed to push to ghcr.io
with:
name: pubsub-kafka
context: ./sdx/ape/functions/pubsub-kafka

build-pubsub-webhook:
uses: ./.github/workflows/.build.yml
permissions:
contents: read
packages: write # 🚀 Crucial permission needed to push to ghcr.io
with:
name: pubsub-webhook
context: ./sdx/ape/functions/pubsub-webhook
15 changes: 15 additions & 0 deletions .github/workflows/sdx-brochure-ui.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: SDX Brochure UI

on:
push:
branches: [feature/*]

jobs:
build-brochure-ui:
uses: ./.github/workflows/.build.yml
permissions:
contents: read
packages: write # 🚀 Crucial permission needed to push to ghcr.io
with:
name: sdx-ui
context: ./sdx/brochure-ui
5 changes: 5 additions & 0 deletions sdx/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
*.ca-bundle
LOCAL.md
*.tgz
.claude
.values-*.yaml
**/public/app.js*
**/public/assets/**
**/public/fonts/**
.terraform*
.claude
terraform.tfvars
Expand Down
103 changes: 103 additions & 0 deletions sdx/ape/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Policy and Event Management

Extending APS API Management solution to include a Policy Engine and Event Management.

## Installation

Steps for OPAL:

- deploy opal-server
- publish opal-api-gateway configuration
- deploy opal-client
- deploy opal-policies
- deploy opal-pip-catalog

Steps for Events:

- deploy pubsub-webhook
- deploy pubsub-kafka

## Usage

### Event Publish

Resources created:

- `GatewayService for sdx-events.api.gov.bc.ca`

> TODO: sdx-events by default is DENY
> TODO: upgrade jwt-keycloak (issuer, aud) - RS needs a token

> WF: `/sdx/0/<workflow_service_id>/forward/<system>`
> Create an endpoint that external shared services (like WF) can call to
> pass to the RS client, where it can get its own token
> WF Client - issue creds to get a client to call the RS
> WF gets a RS token, and then a RS token to get an Amina token

```json
{
"pattern": "events-publisher.r1",
"parameters": {
"service_id": "LAB.USR.ACOPE.HELLO-WORLD-APPLICATION.v0"
}
}
```

### Event Webhook

Resources created:

- `Webhook`

```json
{
"pattern": "events-webhook.r1",
"parameters": {
"conn_id": "42",
"client_id": "LAB.MIN.CITZ.SDG-FE",
"service_id": "LAB.USR.ACOPE.HELLO-WORLD-APPLICATION.v0",
"webhook_url": "https://bright-island-08.webhook.cool"
}
}
```

### OPAL Policy

Resources created:

- `RegoPolicy`

> TODO: For "playground" have sample data for inputs

```json
{
"pattern": "opal-policy.r1",
"parameters": {
"subsystem_id": "LAB.USR.ACOPE.APS-KAFKA",
"name": "authz",
"policy": "package LAB_USR_ACOPE_APS_KAFKA.authz\n\nimport rego.v1\n\n# Default deny everything\ndefault allow := false\n\n# Allow GET requests\nallow if {\n input.method == \"GET\"\n}"
}
}
```

### OPAL Data Source

Resources created:

- `PolicyDataSource`

> TODO: Create a gateway route for the PDPs to access (subsystem edge server)
> TODO: Use "internal" url
> TODO: Update PolicyDataSource to use the internal url
> TODO: Deploy opal-client to edge-server optionally (and cleanup bootstrap)

```json
{
"pattern": "opal-data-source.r1",
"parameters": {
"subsystem_id": "LAB.USR.ACOPE.APS-KAFKA",
"name": "user-gateways",
"upstream_url": "https://httpbun.com/any"
}
}
```
1 change: 1 addition & 0 deletions sdx/ape/functions/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
data/
11 changes: 11 additions & 0 deletions sdx/ape/functions/opal-pip-catalog/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM denoland/deno:2.7.10

WORKDIR /app

COPY main.ts .

RUN deno cache main.ts

EXPOSE 8000

CMD ["deno", "run", "--allow-net", "--allow-read", "--allow-write", "--allow-env", "main.ts"]
79 changes: 79 additions & 0 deletions sdx/ape/functions/opal-pip-catalog/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# opal-pip-catalog

## AI Prompt

- Look for files in current directory only
- All code in single `main.ts` TypeScript file
- Use Deno runtime
- Use SQLite database (`https://deno.land/x/sqlite`)
- Use `jsr:@std/yaml` for YAML handling
- Create database if it doesn't exist
- No environment variables
- Serve on port 8000
- Database location: `./data/sqlite.db`
- Build REST API endpoints with database interactions

## Requirements

- want an endpoint that returns a static list of entries
- the entries can be empty by default

## Running the API

```sh
deno run --allow-net --allow-read --allow-write --allow-env main.ts
```

```sh
restish PUT http://localhost:8000/entries \
'name: abc, dst_path: /abc, topics[]: tenant_data, url: "https://httpbun.com"'
```

## Deployment

```sh
helm upgrade --install opal-pip-catalog \
--set fullnameOverride=opal-pip-catalog \
-f chart.yaml \
--set-file "config[0].contents=main.ts" \
bcgov/generic-api
```

### Test a PIP

#### Register a PIP

```sh
restish PUT https://opal-pip-catalog-api-gov-bc-ca.dev.api.gov.bc.ca/entries \
url: https://httpbun.com, \
"topics: tenant_data", \
dst_path: "/abc"
```

#### Troubleshoot

```sh
-- get all entries
restish GET https://opal-pip-catalog-api-gov-bc-ca.dev.api.gov.bc.ca/entries

-- get entry
restish GET https://opal-pip-catalog-api-gov-bc-ca.dev.api.gov.bc.ca/entries/1

-- add policy
restish PUT https://opal-pip-catalog-api-gov-bc-ca.dev.api.gov.bc.ca/entries \
'name: abc, dst_path: /abc, topics[]: tenant_data, url: "https://httpbun.com"'

-- change notification

-- get a token
restish POST https://opal-api-gov-bc-ca.dev.api.gov.bc.ca/token \
-H "Authorization: Bearer $MASTER_TOKEN" \
'type: datasource, email: "aidan.cope@gov.bc.ca"'

restish POST https://opal-api-gov-bc-ca.dev.api.gov.bc.ca/data/config \
-H "Authorization: Bearer $CLIENT_TOKEN" \
'reason: just because, entries[]: {url: "https://httpbun.com/any", topics[]: tenant_data, dst_path: /abc}'

restish GET https://opal-client-api-gov-bc-ca.dev.api.gov.bc.ca/v1/data/abc/headers

```
38 changes: 38 additions & 0 deletions sdx/ape/functions/opal-pip-catalog/chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
replicaCount: 1

rollingUpdate:
maxUnavailable: 100%
maxSurge: 100%

image:
repository: denoland/deno
tag: 2.7.10
pullPolicy: IfNotPresent

persistence:
deno-dir:
mountPath: /deno-dir
data:
size: 5Mi
mountPath: /data
storageAccessMode: ReadWriteOnce
storageClassName: netapp-file-standard

config:
- filename: main.ts
mountPath: /app/main.ts

command:
- deno

args:
- run
- --allow-net=:8000,deno.land,opal-api-gov-bc-ca.dev.api.gov.bc.ca
- --allow-read
- --allow-write
- --allow-env=OPAL_SERVER_URL
- /app/main.ts

env:
OPAL_SERVER_URL:
value: "https://opal-api-gov-bc-ca.dev.api.gov.bc.ca"
Loading