.devcontainer | ||
.sonarqube | ||
.vscode | ||
Auth | ||
Configuration | ||
docker/odbc | ||
drivers | ||
Endpoints | ||
Infrastructure | ||
k8s | ||
scripts | ||
.dockerignore | ||
.gitignore | ||
appsettings.json | ||
AS400API.csproj | ||
AS400API.sln | ||
docker-compose.yml | ||
Dockerfile | ||
Jenkinsfile | ||
Program.cs | ||
README.md |
AS400API (.NET 9 + ODBC + Dev Container)
Quick start
- Put IBM i Access ODBC RPM into
drivers/
and rename it to end with.rpm.disabled
(e.g.ibm-iaccess-1.1.x.x86_64.rpm.disabled
). The build converts it back to.rpm
but the suffix prevents Apple Silicon devcontainer scaffolding from trying to install the amd64-only driver. - Build & run:
docker compose up --build
VS Code / F5
- Launch profile
AS400API
runsdotnet run
with hot reload-ready JWT setup.
Environment
- Uses
System.Data.Odbc
- Driver name:
IBM i Access ODBC Driver
(from ACS). AdjustAS400_DRIVER_NAME
if your driver name differs. - Credentials are passed via env vars in
docker-compose.yml
.
Authentication & Authorization
POST /api/auth/login
(anonymous) → request body{ "username": "admin", "password": "Pass@123" }
.- Demo identities live in-memory so you can plug in real IdP/Keycloak later.
- Default accounts:
admin
/Pass@123
→ roles:Admin
,Operator
operator
/Pass@123
→ role:Operator
- Copy the
accessToken
from the response and send it as:Authorization: Bearer <token>
. - Override JWT issuer/audience/secret via
appsettings.json
or environment variables (Jwt__Key
, etc.).
Endpoints (role scoped)
GET /api/v1/health
→ anonymous AS/400 ping viaSYSIBM.SYSDUMMY1
GET /api/v1/users/me
→ requires any authenticated user; echoes claimsGET /api/v1/as400/databases
→ requiresOperator
orAdmin
GET /api/v1/as400/query?sql=...
→ requiresAdmin
GET /api/v1/as400/tables?libraryName=LIB
→ requiresOperator
orAdmin
GET /api/v1/as400/table-structure?libraryName=LIB&tableName=TBL
→ requiresOperator
orAdmin
Logging
- Serilog writes rolling files by default to
Logs/as400-api-.log
(configurable inappsettings.json:Serilog:WriteTo:0:Args:path
). - Override at runtime with environment variables, e.g.
Serilog__WriteTo__0__Args__path=/var/log/as400/api-.log
. - Request logging middleware is enabled; application-specific events (query counts, failures, etc.) are captured with structured properties to aid analysis.
SonarQube analysis
- Install or provision a SonarQube/SonarCloud server and generate a project token.
- Set environment variables (
SONAR_HOST_URL
,SONAR_TOKEN
, optionallySONAR_PROJECT_KEY
,SONAR_PROJECT_NAME
; defaults areas400api
/AS400API
, plusSONAR_ORGANIZATION
for SonarCloud). - Run
scripts/run-sonar.sh
; the script builds the solution, runs tests with Coverlet coverage (when*Tests.csproj
projects exist), and publishes results. - Provide branch and pull request details with
SONAR_BRANCH_NAME
,SONAR_PULL_REQUEST_KEY
,SONAR_PULL_REQUEST_BRANCH
, andSONAR_PULL_REQUEST_BASE
when needed.
Notes
- On first build, if no RPM exists in
drivers/
, the image will build but ODBC won't work until you add the RPM and rebuild.
Kubernetes deployment
Use the manifests in k8s/
when running the API on Kubernetes.
- Create a secret with the AS/400 password (and optional JWT key) so it stays separate from the rest of the configuration:
Alternatively create the secret imperatively:cp k8s/secret-example.yaml k8s/secret.yaml # edit k8s/secret.yaml and set real values kubectl apply -f k8s/secret.yaml
kubectl create secret generic as400api-secrets --from-literal=AS400_PASSWORD=... --from-literal=JWT__KEY=...
. - Apply the non-sensitive settings:
kubectl apply -f k8s/configmap.yaml
- Deploy the workload and service:
kubectl apply -f k8s/deployment.yaml kubectl apply -f k8s/service.yaml
The deployment imports the configuration via envFrom
so the password is sourced from the secret while everything else comes from the config map. Update image names, probes, and resource requests to fit your environment.