Reorganize infrastructure as code and implement versioning schema

This commit is contained in:
Alphaeus Mote
2025-05-21 19:40:57 -04:00
parent 8d1a6dd188
commit 2db108aa6b
34 changed files with 4870 additions and 870 deletions
+319
View File
@@ -0,0 +1,319 @@
# API Examples
This document provides examples of using the Active Directory Management API, including the new password reset and account management endpoints.
## Table of Contents
- [Authentication](#authentication)
- [User Management](#user-management)
- [Password Management](#password-management)
- [Account Status Management](#account-status-management)
- [Group Management](#group-management)
- [Bulk Operations](#bulk-operations)
- [Error Handling](#error-handling)
## Authentication
### Login
```bash
curl -X POST http://localhost:5000/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"username": "admin",
"password": "your-password"
}'
```
Response:
```json
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": 1,
"username": "admin",
"email": "admin@example.com",
"fullName": "System Administrator",
"role": "admin"
}
}
```
### Using the Token
For all subsequent requests, include the token in the Authorization header:
```bash
curl -X GET http://localhost:5000/api/users \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
```
## User Management
### Get All Users
```bash
curl -X GET http://localhost:5000/api/connections/1/ad-users \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
```
### Get User by ObjectGUID
```bash
curl -X GET http://localhost:5000/api/connections/1/ad-users/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
```
### Create User
```bash
curl -X POST http://localhost:5000/api/connections/1/ad-users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-d '{
"sAMAccountName": "jdoe",
"givenName": "John",
"sn": "Doe",
"displayName": "John Doe",
"mail": "jdoe@example.com",
"userPrincipalName": "jdoe@example.com",
"parentOU": "OU=Users,DC=example,DC=com",
"password": "SecurePassword123!",
"enabled": true
}'
```
### Update User
```bash
curl -X PATCH http://localhost:5000/api/connections/1/ad-users/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-d '{
"displayName": "John A. Doe",
"mail": "john.doe@example.com",
"telephoneNumber": "+1 (555) 123-4567"
}'
```
### Delete User
```bash
curl -X DELETE http://localhost:5000/api/connections/1/ad-users/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
```
## Password Management
### Reset User Password
```bash
curl -X POST http://localhost:5000/api/connections/1/reset-password \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-d '{
"userObjectGUID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"newPassword": "NewSecurePassword456!",
"skipValidation": false,
"requirePasswordChangeAtNextLogon": true
}'
```
Response:
```json
{
"success": true,
"message": "Password reset successful for user with GUID a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
```
### Reset Password with Skip Validation
For scenarios where you need to bypass password policy validation:
```bash
curl -X POST http://localhost:5000/api/connections/1/reset-password \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-d '{
"userObjectGUID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"newPassword": "TempPass123",
"skipValidation": true,
"requirePasswordChangeAtNextLogon": true
}'
```
### Reset Password Without Requiring Change at Next Logon
```bash
curl -X POST http://localhost:5000/api/connections/1/reset-password \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-d '{
"userObjectGUID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"newPassword": "NewSecurePassword456!",
"requirePasswordChangeAtNextLogon": false
}'
```
## Account Status Management
### Enable User Account
```bash
curl -X POST http://localhost:5000/api/connections/1/enable-user-account \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-d '{
"userObjectGUID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"enabled": true
}'
```
Response:
```json
{
"success": true,
"message": "User account enabled successfully for user with GUID a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
```
### Disable User Account
```bash
curl -X POST http://localhost:5000/api/connections/1/enable-user-account \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-d '{
"userObjectGUID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"enabled": false
}'
```
Response:
```json
{
"success": true,
"message": "User account disabled successfully for user with GUID a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
```
### Bulk Enable User Accounts
```bash
curl -X POST http://localhost:5000/api/connections/1/bulk-enable-user-accounts \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-d '{
"userDNs": [
"CN=John Doe,OU=Users,DC=example,DC=com",
"CN=Jane Smith,OU=Users,DC=example,DC=com",
"CN=Bob Johnson,OU=Users,DC=example,DC=com"
],
"enabled": true
}'
```
Response:
```json
{
"success": [
"CN=John Doe,OU=Users,DC=example,DC=com",
"CN=Jane Smith,OU=Users,DC=example,DC=com",
"CN=Bob Johnson,OU=Users,DC=example,DC=com"
],
"failed": []
}
```
### Bulk Disable User Accounts
```bash
curl -X POST http://localhost:5000/api/connections/1/bulk-enable-user-accounts \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-d '{
"userDNs": [
"CN=John Doe,OU=Users,DC=example,DC=com",
"CN=Jane Smith,OU=Users,DC=example,DC=com",
"CN=Bob Johnson,OU=Users,DC=example,DC=com"
],
"enabled": false
}'
```
## Group Management
### Add User to Group
```bash
curl -X POST http://localhost:5000/api/connections/1/add-to-group \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-d '{
"objectGUID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"groupObjectGUID": "g1h2i3j4-k5l6-7890-mnop-qr1234567890",
"objectType": "user"
}'
```
### Remove User from Group
```bash
curl -X POST http://localhost:5000/api/connections/1/remove-from-group \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-d '{
"objectGUID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"groupObjectGUID": "g1h2i3j4-k5l6-7890-mnop-qr1234567890",
"objectType": "user"
}'
```
## Error Handling
### Invalid Request
```json
{
"errors": [
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": ["userObjectGUID"],
"message": "User ObjectGUID is required"
}
]
}
```
### User Not Found
```json
{
"message": "User not found"
}
```
### Permission Denied
```json
{
"message": "You do not have permission to perform this action"
}
```
### LDAP Operation Failed
```json
{
"message": "Failed to reset password",
"error": "LDAP operation failed: Constraint violation"
}
```
+316
View File
@@ -0,0 +1,316 @@
# Deployment Guide
This guide provides instructions for deploying the Active Directory Management application using Docker, Docker Compose, and Kubernetes.
## Table of Contents
- [Docker Deployment](#docker-deployment)
- [Building the Docker Image](#building-the-docker-image)
- [Running with Docker](#running-with-docker)
- [Environment Variables](#environment-variables)
- [Docker Compose Deployment](#docker-compose-deployment)
- [Configuration](#configuration)
- [Starting the Services](#starting-the-services)
- [Stopping the Services](#stopping-the-services)
- [Kubernetes Deployment](#kubernetes-deployment)
- [Prerequisites](#prerequisites)
- [Configuration](#kubernetes-configuration)
- [Deployment](#deployment)
- [Accessing the Application](#accessing-the-application)
- [Scaling](#scaling)
- [Updating](#updating)
- [Monitoring](#monitoring)
- [Production Considerations](#production-considerations)
- [Security](#security)
- [Backups](#backups)
- [High Availability](#high-availability)
## Docker Deployment
### Building the Docker Image
To build the Docker image using the provided build scripts:
#### Linux/macOS:
```bash
# Navigate to the iac/docker directory
cd iac/docker
# Make the script executable
chmod +x build.sh
# Build the image with default settings
./build.sh
# Build with custom tag
./build.sh --tag v1.0.0
# Build and push to a registry
./build.sh --registry your-registry.com --tag v1.0.0 --push
```
#### Windows:
```powershell
# Navigate to the iac/docker directory
cd iac\docker
# Build the image with default settings
.\build.ps1
# Build with custom tag
.\build.ps1 -tag v1.0.0
# Build and push to a registry
.\build.ps1 -registry your-registry.com -tag v1.0.0 -push
```
#### Manually:
```bash
# Navigate to the project root
cd /path/to/project
# Build the image
docker build -t ad-management:latest -f iac/docker/Dockerfile .
```
### Running with Docker
To run the application with Docker:
```bash
docker run -d --name ad-management \
-p 5000:5000 \
-e NODE_ENV=production \
-e POSTGRES_HOST=your-postgres-host \
-e POSTGRES_PORT=5432 \
-e POSTGRES_DB=admgr \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=your-password \
-e REDIS_HOST=your-redis-host \
-e REDIS_PORT=6379 \
-e JWT_SECRET=your-jwt-secret \
-e SESSION_SECRET=your-session-secret \
ad-management:latest
```
### Environment Variables
The application uses the following environment variables:
| Variable | Description | Default |
|----------|-------------|---------|
| `NODE_ENV` | Environment mode | `development` |
| `PORT` | Port to run the server on | `5000` |
| `BASE_URL` | Base URL for the application | `http://localhost:5000` |
| `POSTGRES_HOST` | PostgreSQL host | `localhost` |
| `POSTGRES_PORT` | PostgreSQL port | `5432` |
| `POSTGRES_DB` | PostgreSQL database name | `admgr` |
| `POSTGRES_USER` | PostgreSQL username | `postgres` |
| `POSTGRES_PASSWORD` | PostgreSQL password | - |
| `REDIS_HOST` | Redis host | `localhost` |
| `REDIS_PORT` | Redis port | `6379` |
| `JWT_SECRET` | Secret for JWT tokens | - |
| `SESSION_SECRET` | Secret for session cookies | - |
| `DEFAULT_ADMIN_USERNAME` | Default admin username | `admin` |
| `DEFAULT_ADMIN_PASSWORD` | Default admin password | - |
| `DEFAULT_ADMIN_EMAIL` | Default admin email | - |
| `DEFAULT_ADMIN_FULLNAME` | Default admin full name | `System Administrator` |
| `DISABLE_REGISTRATION` | Disable user registration | `false` |
## Docker Compose Deployment
### Configuration
The application includes a `docker-compose.yml` file for easy deployment. You can customize the environment variables by creating or modifying the `.env` file in the `iac/docker` directory.
Example `.env` file:
```
NODE_ENV=production
PORT=5000
BASE_URL=http://localhost:5000
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_DB=admgr
POSTGRES_USER=postgres
POSTGRES_PASSWORD=your-postgres-password
REDIS_HOST=redis
REDIS_PORT=6379
JWT_SECRET=your-jwt-secret
SESSION_SECRET=your-session-secret
DEFAULT_ADMIN_USERNAME=admin
DEFAULT_ADMIN_PASSWORD=your-admin-password
DEFAULT_ADMIN_EMAIL=admin@example.com
DEFAULT_ADMIN_FULLNAME=System Administrator
DISABLE_REGISTRATION=false
```
### Starting the Services
To start all services:
```bash
# Navigate to the iac/docker directory
cd iac/docker
# Start the application stack
docker-compose up -d
```
This will start the application, PostgreSQL, and Redis containers.
### Stopping the Services
To stop all services:
```bash
# Navigate to the iac/docker directory
cd iac/docker
# Stop the application stack
docker-compose down
```
To stop and remove all data volumes:
```bash
# Navigate to the iac/docker directory
cd iac/docker
# Stop the application stack and remove volumes
docker-compose down -v
```
## Kubernetes Deployment
### Prerequisites
- Kubernetes cluster (v1.19+)
- kubectl configured to communicate with your cluster
- [Kustomize](https://kustomize.io/) (v4.0+) or kubectl v1.14+ which includes kustomize
- Optional: Ingress controller (e.g., NGINX Ingress Controller)
- Optional: cert-manager for TLS certificates
### Kubernetes Configuration
The Kubernetes manifests are located in the `iac/kubernetes/` directory. Before deploying, you should customize the following files:
1. `iac/kubernetes/configmap.yaml`: Update environment variables
2. `iac/kubernetes/secrets.yaml`: Update secrets (use base64-encoded values)
3. `iac/kubernetes/deployment.yaml`: Update resource limits if needed
4. `iac/kubernetes/ingress.yaml`: Update host name and TLS configuration
### Deployment
To deploy the application to Kubernetes:
```bash
# Navigate to the iac/kubernetes directory
cd iac/kubernetes
# Apply all resources
kubectl apply -k .
# Or from anywhere in the project
kubectl apply -k iac/kubernetes
```
This will create:
- A namespace called `ad-management`
- ConfigMap and Secret for environment variables
- PostgreSQL StatefulSet with persistent storage
- Redis StatefulSet with persistent storage
- Application Deployment with 2 replicas
- Services for all components
- Ingress for external access
### Accessing the Application
If you've configured the Ingress, the application will be available at the hostname specified in `kubernetes/ingress.yaml`.
Without Ingress, you can use port-forwarding to access the application:
```bash
kubectl port-forward -n ad-management svc/ad-management 5000:80
```
Then access the application at http://localhost:5000.
### Scaling
To scale the application:
```bash
kubectl scale -n ad-management deployment/ad-management --replicas=3
```
### Updating
To update the application to a new version:
1. Build and push the new Docker image
2. Update the image tag in `kubernetes/deployment.yaml`
3. Apply the changes:
```bash
kubectl apply -k kubernetes/
```
Or use kubectl set image:
```bash
kubectl set image -n ad-management deployment/ad-management ad-management=ad-management:new-tag
```
### Monitoring
You can monitor the application using:
```bash
# Check pod status
kubectl get pods -n ad-management
# View logs
kubectl logs -n ad-management deployment/ad-management
# Describe deployment
kubectl describe deployment -n ad-management ad-management
```
## Production Considerations
### Security
For production deployments:
1. Use strong, unique passwords for all secrets
2. Enable TLS for all connections
3. Use network policies to restrict traffic between components
4. Set up proper RBAC for Kubernetes resources
5. Regularly update all components and dependencies
6. Consider using a secrets management solution like HashiCorp Vault
### Backups
Set up regular backups for:
1. PostgreSQL database
2. Redis data (if persistence is enabled)
3. Application configuration
Example PostgreSQL backup:
```bash
kubectl exec -n ad-management postgres-0 -- pg_dump -U postgres admgr > backup.sql
```
### High Availability
For high availability:
1. Run multiple replicas of the application
2. Use a PostgreSQL cluster with replication
3. Configure Redis with replication or cluster mode
4. Deploy across multiple availability zones
5. Use a load balancer or ingress controller with multiple backends
6. Implement proper health checks and readiness probes
+324
View File
@@ -0,0 +1,324 @@
# Kubernetes Deployment Guide
This guide provides detailed instructions for deploying the Active Directory Management application on Kubernetes.
## Prerequisites
- Kubernetes cluster (v1.19+)
- kubectl configured to communicate with your cluster
- [Kustomize](https://kustomize.io/) (v4.0+) or kubectl v1.14+ which includes kustomize
- Optional: Ingress controller (e.g., NGINX Ingress Controller)
- Optional: cert-manager for TLS certificates
## Deployment Architecture
The Kubernetes deployment consists of:
- **Application Deployment**: The main application with multiple replicas
- **PostgreSQL StatefulSet**: Database with persistent storage
- **Redis StatefulSet**: Cache and session storage with persistent storage
- **Services**: For internal communication between components
- **Ingress**: For external access to the application
- **ConfigMap and Secrets**: For configuration and sensitive data
All Kubernetes manifests are located in the `iac/kubernetes/` directory.
## Step-by-Step Deployment
### 1. Customize Configuration
Before deploying, customize the configuration files in the `iac/kubernetes/` directory:
#### ConfigMap (`iac/kubernetes/configmap.yaml`)
Update environment variables according to your environment:
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: ad-management-config
namespace: ad-management
data:
NODE_ENV: "production"
PORT: "5000"
BASE_URL: "https://your-domain.com" # Update this
DEFAULT_ADMIN_USERNAME: "admin"
DEFAULT_ADMIN_FULLNAME: "System Administrator"
DISABLE_REGISTRATION: "false"
POSTGRES_DB: "admgr"
POSTGRES_USER: "postgres"
```
#### Secrets (`kubernetes/secrets.yaml`)
Update the secrets with your own base64-encoded values:
```bash
# Generate base64-encoded secrets
echo -n "your-jwt-secret" | base64
echo -n "your-session-secret" | base64
echo -n "your-admin-password" | base64
echo -n "admin@your-domain.com" | base64
echo -n "your-postgres-password" | base64
```
Then update `iac/kubernetes/secrets.yaml`:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: ad-management-secrets
namespace: ad-management
type: Opaque
data:
JWT_SECRET: "base64-encoded-jwt-secret"
SESSION_SECRET: "base64-encoded-session-secret"
DEFAULT_ADMIN_PASSWORD: "base64-encoded-admin-password"
DEFAULT_ADMIN_EMAIL: "base64-encoded-admin-email"
POSTGRES_PASSWORD: "base64-encoded-postgres-password"
```
#### Ingress (`iac/kubernetes/ingress.yaml`)
Update the hostname and TLS configuration:
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ad-management-ingress
namespace: ad-management
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
tls:
- hosts:
- your-domain.com # Update this
secretName: ad-management-tls
rules:
- host: your-domain.com # Update this
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ad-management
port:
name: http
```
### 2. Deploy the Application
Deploy all resources using Kustomize:
```bash
# Navigate to the iac/kubernetes directory
cd iac/kubernetes
# Apply all resources
kubectl apply -k .
# Or from anywhere in the project
kubectl apply -k iac/kubernetes
```
### 3. Verify Deployment
Check that all resources are created and running:
```bash
# Check namespace
kubectl get namespace ad-management
# Check pods
kubectl get pods -n ad-management
# Check services
kubectl get services -n ad-management
# Check deployments and statefulsets
kubectl get deployment,statefulset -n ad-management
# Check ingress
kubectl get ingress -n ad-management
```
### 4. Access the Application
If you've configured the Ingress, the application will be available at your specified domain.
Without Ingress, use port-forwarding:
```bash
kubectl port-forward -n ad-management svc/ad-management 5000:80
```
Then access the application at http://localhost:5000.
## Common Operations
### Scaling the Application
To scale the application horizontally:
```bash
kubectl scale -n ad-management deployment/ad-management --replicas=3
```
### Updating the Application
To update the application to a new version:
```bash
# Update the image
kubectl set image -n ad-management deployment/ad-management ad-management=ad-management:new-tag
# Check rollout status
kubectl rollout status -n ad-management deployment/ad-management
```
### Viewing Logs
To view application logs:
```bash
# View logs from all pods
kubectl logs -n ad-management -l app=ad-management
# View logs from a specific pod
kubectl logs -n ad-management pod/ad-management-xxxx-yyyy
```
### Restarting Components
To restart the application:
```bash
kubectl rollout restart -n ad-management deployment/ad-management
```
To restart PostgreSQL or Redis:
```bash
kubectl rollout restart -n ad-management statefulset/postgres
kubectl rollout restart -n ad-management statefulset/redis
```
## Troubleshooting
### Pod Startup Issues
If pods are not starting:
```bash
# Check pod status
kubectl get pods -n ad-management
# Describe the pod for more details
kubectl describe pod -n ad-management pod/ad-management-xxxx-yyyy
# Check container logs
kubectl logs -n ad-management pod/ad-management-xxxx-yyyy
```
### Database Connection Issues
If the application can't connect to the database:
1. Check if the PostgreSQL pod is running:
```bash
kubectl get pods -n ad-management -l app=postgres
```
2. Check PostgreSQL logs:
```bash
kubectl logs -n ad-management pod/postgres-0
```
3. Verify the connection from the application pod:
```bash
kubectl exec -it -n ad-management pod/ad-management-xxxx-yyyy -- nc -zv postgres 5432
```
### Ingress Issues
If the Ingress is not working:
1. Check the Ingress status:
```bash
kubectl describe ingress -n ad-management ad-management-ingress
```
2. Check the Ingress controller logs:
```bash
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller
```
## Examples
### Example: Setting Up TLS with cert-manager
1. Install cert-manager:
```bash
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.yaml
```
2. Create a ClusterIssuer for Let's Encrypt:
```yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: your-email@example.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
```
3. Apply the ClusterIssuer:
```bash
kubectl apply -f cluster-issuer.yaml
```
### Example: Setting Up Monitoring with Prometheus and Grafana
1. Install Prometheus Operator:
```bash
kubectl apply -f https://github.com/prometheus-operator/kube-prometheus/releases/download/v0.10.0/manifests-0.10.0.tar.gz
```
2. Create a ServiceMonitor for the application:
```yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: ad-management
namespace: monitoring
spec:
selector:
matchLabels:
app: ad-management
namespaceSelector:
matchNames:
- ad-management
endpoints:
- port: http
path: /metrics
interval: 15s
```
3. Apply the ServiceMonitor:
```bash
kubectl apply -f service-monitor.yaml
```