NATS is an infrastructure platform for building message-based services.
This Django app integrates NAT's multi-tenant account paradigm with Django Organizations.
The NATS nsc
tool is used to manage operator, account, and user JWTs.
-
pip install django-nats-nkeys[drf]
-
Add to your INSTALLED_APPS settings:
INSTALLED_APPS = [ ... "organizations", "django_extensions", "django_nats_nkey", ]
-
Run
python manage.py migrate
to create the NATS organizationals models -
Run
python manage.py nsc-init
(optional) Initialize a new NATS operator. You are responsible for copying the generated.conf
file to your NATS server. If you choose to use an existing operator, you are responsible for runningnsc pull
as a pre-deployment step.
-
Create a development environment (requires docker & docker-compose):
make docker-up make nsc-init
-
Run tests and generate a coverage report:
make pytest
-
Run
black
linter:make lint
NATS_NSC_DATA_DIR
(default: "/var/lib/nats/nsc/stores"
or $NSC_STORE
environment var)
NATS_NSC_CONFIG_DIR
(default: "/var/lib/nats/nsc/config"
or $NSC_HOME
environment var)
NATS_NSC_KEYSTORE_DIR
(default: "/var/lib/nats/nsc/keys"
or $NKEYS_PATH
environment var)
NATS_SERVER_URI
(default: "nats://nats:4222"
)
NATS_NKEYS_IMPORT_DIR
(default: ".nats/"
, )
NATS_NKEYS_EXPORT_DIR
(default: ".nats/"
)
NATS_NKEYS_OPERATOR_NAME
(default: "DjangoOperator"
)
NATS_NSC_RETRY_MODE
(default "STRICT", allowed values: "STRICT" or "IDEMPOTENT")
In STRICT
mode, django_nats_nkey.errors.NscConflict
will be raised if nsc add ...
command returns an "already exists" error. You are responsible for implementing a separate process to handle eventual consistency between Django models and nsc environment.
In IDEMPOTENT
mode, conflict is logged at the WARNING level but no Exception
is raised. In this mode, nsc add
command may be retried many times and will be a no-op if resource already exists.
- Based on Django organizations
- An
Organization
represents anaccount
in NATS multi-tenant account model - An
App
represents auser
in NATS multi-tenant account model
NATS_ORGANIZATION_MODEL
(default: "django_nats_nkeys.NatsOrganization"
)
- Must subclass
django_nats_nkeys.models.NatsOrganization
NATS_ORGANIZATION_OWNER_MODEL
(default: "django_nats_nkeys.NatsOrganizationOwner"
)
- Must subclass
django_nats_nkey.models.NatsOrganizationOwner
NATS_ORGANIZATION_APP_MODEL
(default: "django_nats_nkey.NatsOrganizationApp"
)
- Must subclass
django_nats_nkey.models.AbstractNatsApp
NATS_ORGANIZATION_USER_MODEL
(default: "django_nats_nkeys.models.NatsOrganizationUser"
)
- Must subclass
django_nats_nkeys.models.NatsOrganizationUser
NATS_ROBOT_APP_MODEL
(default: "django_nats_nkeys.NatsRobotApp"
)
NATS_ROBOT_ACCOUNT_MODEL
(default: "django_nats_nkeys.NatsRobotAccount"
)
NATS_APP_MODELS
(default: [ "django_nats_nkey.NatsOrganizationApp" , "django_nats_nkeys.NatsRobotApp" ]
)