> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/allegro/ralph/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration

> Configure Ralph for LDAP authentication, OpenStack synchronization, and advanced features

This guide covers advanced configuration options for Ralph, including LDAP/Active Directory authentication and OpenStack cloud synchronization.

## Configuration Structure

### Ubuntu Package Installation

Configuration files are located in `/etc/ralph/`:

* **`/etc/ralph/ralph.conf`** - Main configuration
* **`/etc/ralph/conf.d/database.conf`** - Database settings
* **`/etc/ralph/conf.d/redis.conf`** - Redis cache settings
* **`/etc/ralph/conf.d/gunicorn.conf`** - Gunicorn server settings
* **`/etc/ralph/conf.d/cache.conf`** - Cache configuration

Settings are environment variables that Django reads on startup.

### Docker Installation

Set environment variables in your `docker-compose.yml` file under the `environment` section.

## LDAP Authentication

Ralph supports authentication via LDAP and Active Directory systems.

### Installation

<Steps>
  <Step title="Install LDAP Requirements">
    **Ubuntu:**

    ```bash theme={null}
    pip install python-ldap django-auth-ldap
    ```

    **Docker:**
    LDAP dependencies are included in the base image.
  </Step>

  <Step title="Configure LDAP Backend">
    Add LDAP as an authentication backend in your local settings file.

    Create `/etc/ralph/conf.d/ldap.conf` (Ubuntu) or add to environment:

    ```python theme={null}
    AUTHENTICATION_BACKENDS = (
        'django_auth_ldap.backend.LDAPBackend',
        'django.contrib.auth.backends.ModelBackend',
    )

    LOGGING['loggers']['django_auth_ldap'] = {
        'handlers': ['file'],
        'propagate': True,
        'level': 'DEBUG',
    }
    ```
  </Step>
</Steps>

### Active Directory Configuration

Example configuration for Active Directory:

```python theme={null}
import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType

# Server settings
AUTH_LDAP_SERVER_URI = "ldap://activedirectory.domain:389"
AUTH_LDAP_BIND_DN = "CN=ralph_service,OU=ServiceAccounts,DC=domain,DC=com"
AUTH_LDAP_BIND_PASSWORD = "your_secure_password"
AUTH_LDAP_PROTOCOL_VERSION = 3

# User search settings
AUTH_LDAP_USER_USERNAME_ATTR = "sAMAccountName"
AUTH_LDAP_USER_SEARCH_BASE = "DC=domain,DC=internal"
AUTH_LDAP_USER_SEARCH_FILTER = '(&(objectClass=user)({0}=%(user)s))'.format(
    AUTH_LDAP_USER_USERNAME_ATTR
)
AUTH_LDAP_USER_SEARCH = LDAPSearch(
    AUTH_LDAP_USER_SEARCH_BASE,
    ldap.SCOPE_SUBTREE,
    AUTH_LDAP_USER_SEARCH_FILTER
)

# User attribute mapping
AUTH_LDAP_USER_ATTR_MAP = {
    "first_name": "givenName",
    "last_name": "sn",
    "email": "mail",
    "company": "company",
    "manager": "manager",
    "department": "department",
    "employee_id": "employeeID",
    "location": "officeName",
    "country": "ISO-country-code",
}
```

### OpenDJ Configuration

For OpenDJ LDAP servers, use `uid` for username:

```python theme={null}
AUTH_LDAP_USER_USERNAME_ATTR = "uid"

from django_auth_ldap.config import GroupOfUniqueNamesType

AUTH_LDAP_GROUP_TYPE = GroupOfUniqueNamesType()
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
    "DC=organization,DC=internal",
    ldap.SCOPE_SUBTREE,
    '(structuralObjectClass=groupOfUniqueNames)'
)
```

### LDAP Group Mapping

Map LDAP groups to Ralph permissions:

```python theme={null}
from ralph.account.ldap import MappedGroupOfNamesType

AUTH_LDAP_GROUP_MAPPING = {
    'CN=_gr_ralph,OU=Groups,DC=domain,DC=com': "staff",
    'CN=_gr_ralph_assets_buyer,OU=Groups,DC=domain,DC=com': "assets-buyer",
    'CN=_gr_ralph_assets_staff,OU=Groups,DC=domain,DC=com': "assets-staff",
    'CN=_gr_ralph_admin,OU=Groups,DC=domain,DC=com': "superuser",
}

AUTH_LDAP_MIRROR_GROUPS = True
AUTH_LDAP_GROUP_TYPE = MappedGroupOfNamesType(name_attr="cn")
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
    "DC=organization,DC=internal",
    ldap.SCOPE_SUBTREE,
    '(objectClass=group)'
)
```

### Nested LDAP Groups

For nested group support:

```python theme={null}
AUTH_LDAP_NESTED_GROUPS = {
    'CN=_gr_ralph_users,OU=Groups,DC=domain,DC=com': "staff",
}
AUTH_LDAP_QUERY_PAGE_SIZE = 500  # LDAP default page limit is 1000
```

### User Filtering

Restrict which LDAP users can access Ralph:

```python theme={null}
AUTH_LDAP_USER_FILTER = '(|(memberOf=CN=_gr_ralph_group1,OU=IT,' \
    'DC=domain,DC=com)(memberOf=CN=_gr_ralph_group2,OU=IT,' \
    'DC=domain,DC=com))'
```

<Note>
  For OpenDJ, use `isMemberOf` instead of `memberOf`.
</Note>

### Synchronize Users

Sync LDAP users to Ralph database:

```bash theme={null}
# Ubuntu
sudo ralphctl ldap_sync

# Docker
docker-compose exec web ralph ldap_sync
```

The script reports progress every 100 items.

### ObjectClass Values by LDAP Implementation

* **Active Directory**: `objectClass=user`
* **Novell eDirectory**: `objectClass=inetOrgPerson`
* **OpenLDAP**: `objectClass=posixAccount`

## OpenStack Synchronization

Ralph supports one-way synchronization with OpenStack clouds, importing projects and instances in read-only mode.

### Installation

<Steps>
  <Step title="Install OpenStack Requirements">
    **Ubuntu:**

    ```bash theme={null}
    pip install openstacksdk python-keystoneclient python-novaclient
    ```

    **Docker:**
    OpenStack dependencies are included in the base Ralph image.
  </Step>

  <Step title="Configure OpenStack Instances">
    Add OpenStack configuration to your settings file.

    Create `/etc/ralph/conf.d/openstack.conf` or add to your local settings:

    ```python theme={null}
    OPENSTACK_INSTANCES = [
        {
            'username':     'ralph_service',
            'password':     'secure_password',
            'tenant_name':  'admin',
            'version':      '2.0',
            'auth_url':     'http://openstack.example.com:35357/v2.0/',
            'tag':          'production'
        },
        {
            'username':     'ralph_service',
            'password':     'secure_password',
            'tenant_name':  'admin',
            'version':      '2.0',
            'auth_url':     'http://openstack-dev.example.com:35357/v2.0/',
            'tag':          'development'
        },
    ]
    ```

    **Configuration Parameters:**

    * **username**: OpenStack user with permissions to list all projects and instances
    * **tenant\_name**: Project/tenant for authentication
    * **version**: OpenStack API version (currently only 2.x supported)
    * **auth\_url**: OpenStack Keystone API endpoint
    * **tag**: Tag added to all imported Cloud Projects and Cloud Hosts
  </Step>
</Steps>

### Run Synchronization

Execute OpenStack sync manually:

```bash theme={null}
# Ubuntu
sudo ralphctl openstack_sync

# Docker
docker-compose exec web ralph openstack_sync
```

### Automated Synchronization

Schedule regular syncs using cron (Ubuntu):

```bash theme={null}
# Edit crontab
sudo crontab -e

# Add sync every hour
0 * * * * /usr/bin/ralphctl openstack_sync >> /var/log/ralph/openstack_sync.log 2>&1
```

For Docker, use a scheduler container or external cron job:

```bash theme={null}
0 * * * * docker-compose -f /path/to/docker-compose.yml exec -T web ralph openstack_sync
```

### How It Works

1. **First Run**: Imports all Cloud Projects, Cloud Hosts, and Cloud Flavors from OpenStack
2. **Subsequent Runs**: Updates existing objects and deletes those no longer in OpenStack
3. **Read-Only Import**: Most fields are read-only; only Service Environment, Tags, and Remarks can be modified
4. **Inheritance**: Cloud Host service environments inherit from their parent Cloud Project

## Database Configuration

### MySQL Configuration

**Ubuntu** (`/etc/ralph/conf.d/database.conf`):

```bash theme={null}
DATABASE_ENGINE=mysql
DATABASE_NAME=ralph_ng
DATABASE_USER=ralph_ng
DATABASE_PASSWORD=secure_password
DATABASE_HOST=localhost
DATABASE_PORT=3306
```

**Docker** (docker-compose.yml):

```yaml theme={null}
services:
  web:
    environment:
      DATABASE_ENGINE: mysql
      DATABASE_NAME: ralph_ng
      DATABASE_USER: ralph_ng
      DATABASE_PASSWORD: secure_password
      DATABASE_HOST: db
      DATABASE_PORT: 3306
```

### PostgreSQL Configuration

**Ubuntu:**

```bash theme={null}
DATABASE_ENGINE=postgresql
DATABASE_NAME=ralph_ng
DATABASE_USER=ralph_ng
DATABASE_PASSWORD=secure_password
DATABASE_HOST=localhost
DATABASE_PORT=5432
```

## Redis Configuration

**Ubuntu** (`/etc/ralph/conf.d/redis.conf`):

```bash theme={null}
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_DB=0
REDIS_PASSWORD=""
REDIS_TIMEOUT=10.0
REDIS_CONNECT_TIMEOUT=1.0
```

### Redis Sentinel (High Availability)

```bash theme={null}
REDIS_SENTINEL_ENABLED=1
REDIS_SENTINEL_HOSTS="sentinel1:26379,sentinel2:26379,sentinel3:26379"
REDIS_CLUSTER_NAME="ralph-master"
REDIS_SENTINEL_SOCKET_TIMEOUT=0.2
```

## Gunicorn Configuration

**Ubuntu** (`/etc/ralph/conf.d/gunicorn.conf`):

```bash theme={null}
GUNICORN_BIND=0.0.0.0:8000
GUNICORN_WORKERS=4
GUNICORN_ACCESSLOG=/var/log/ralph/gunicorn.access.log
GUNICORN_ERRORLOG=/var/log/ralph/gunicorn.error.log
GUNICORN_LOGLEVEL=info
GUNICORN_USER=ralphsrv
GUNICORN_GROUP=ralphsrv
GUNICORN_TIMEOUT=30
```

<Tip>
  Set `GUNICORN_WORKERS` to `(2 * CPU_cores) + 1` for optimal performance.
</Tip>

## Cache Configuration

Enable Redis caching for improved performance:

**Ubuntu** (`/etc/ralph/conf.d/cache.conf`):

```bash theme={null}
# Store sessions in Redis
STORE_SESSIONS_IN_REDIS=1

# Use Redis for Django cache
USE_REDIS_CACHE=1

# Optional: Use different Redis DB for cache
REDIS_CACHE_DB=1
REDIS_CACHE_PASSWORD=""
```

## Logging Configuration

**Ubuntu** (`/etc/ralph/ralph.conf`):

```bash theme={null}
LOG_FILEPATH=/var/log/ralph/ralph.log
LOG_LEVEL=INFO  # DEBUG, INFO, WARNING, ERROR, CRITICAL
```

## Static Files and Media

```bash theme={null}
STATIC_ROOT=/usr/share/ralph/static
MEDIA_ROOT=/var/local/ralph/media
```

After changing static file settings, collect static files:

```bash theme={null}
# Ubuntu
sudo ralphctl collectstatic --noinput

# Docker
docker-compose exec web ralph collectstatic --noinput
```

## Security Settings

### Debug Mode

<Warning>
  **Never enable debug mode in production!**
</Warning>

```bash theme={null}
# Development only
RALPH_DEBUG=1

# Production
RALPH_DEBUG=0
```

### Allowed Hosts

For production, specify allowed hostnames:

```python theme={null}
ALLOWED_HOSTS = ['ralph.example.com', 'ralph-internal.example.com']
```

### Secret Key

Generate a unique secret key for your installation:

```bash theme={null}
python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())'
```

Add to configuration:

```bash theme={null}
SECRET_KEY='your-generated-secret-key-here'
```

## Applying Configuration Changes

After modifying configuration:

**Ubuntu:**

```bash theme={null}
sudo systemctl restart ralph.service
```

**Docker:**

```bash theme={null}
docker-compose restart web
```

## Next Steps

<Card title="Data Migration" icon="database" href="/installation/migration">
  Learn how to import data from Ralph 2 or other sources
</Card>
