Tenant Clusters
Overview
Tenant Clusters provide a way to organize and group tenants into logical collections. This enables administrators to manage and filter tenants more effectively, especially in environments with many tenants. Each cluster can have a designated "Parent Tenant", which is responsible for managing the group.
Implementation
Tenant Clusters are implemented as a one-to-many relationship with an additional reference for the managing tenant:
- A Cluster can have many Tenants
- A Tenant belongs to one Cluster (or none)
- A Cluster can have one parent Tenant
The system uses a tenant_cluster_id foreign key in the tenants table and a parent_tenant_id foreign key in the tenant_clusters table to establish these relationships.
Database Schema
The implementation involves two database tables:
-
tenant_clusterstable:id: Primary keyname: Name of the clusterslug: URL-friendly version of the name (auto-generated)description: Optional description of the clusterparent_tenant_id: Foreign key to thetenantstable (nullable), indicating the parent tenant for this cluster.- Standard timestamp fields
-
tenantstable now includes:tenant_cluster_id: Foreign key to the tenant_clusters table (nullable)
Models
TenantCluster Model
The TenantCluster model provides a way to create and manage clusters:
class TenantCluster extends Model
{
use HasFactory;
protected $guarded = [];
public function tenants()
{
return $this->hasMany(Tenant::class, 'tenant_cluster_id');
}
public function parentTenant()
{
return $this->belongsTo(Tenant::class, 'parent_tenant_id');
}
}
The TenantCluster model uses an observer (TenantClusterObserver) which ensures that a cluster with existing tenants cannot be updated to have no parent_tenant_id. This is how we enforce that Cluster with tenants must have a Parent Tenant.
Tenant Model
The Tenant model has been updated to include a relationship to clusters:
// Relationship to cluster
public function cluster()
{
return $this->belongsTo(TenantCluster::class, 'tenant_cluster_id');
}
// Scope to filter tenants by cluster
public function scopeOfTenantCluster($query, $clusterId)
{
return $query->where('tenant_cluster_id', $clusterId);
}
// Check if this tenant is the parent tenant of its cluster
public function isClusterManager()
{
return $this->cluster && $this->cluster->parent_tenant_id == $this->id;
}
User Interface
Tenant Clusters can be managed in the Landlord admin area, specifically within the "Tenant Groups" section. Access to this area is controlled by the manage_tenant_groups permission.
- Creating Clusters: Administrators can create clusters with a name and description
- Managing Clusters: Administrators can edit or delete existing clusters
- Assigning Tenants: Tenants can be assigned to clusters either:
- When creating/editing a tenant through the Tenant form
- From the Cluster management interface by attaching existing tenants
- Setting the Parent Tenant:
- When the first tenant is added to a cluster, it is automatically set as the Parent Tenant.
- The Parent Tenant can be changed from the Cluster management interface, in the "Tenants" tab for that cluster, by using the "Parent Tenant" toggle.
- A tenant cannot be detached if it's the Parent Tenant and other tenants exist in the cluster. Another tenant must be designated as the Parent Tenant first.
Usage
Creating a Tenant Cluster
- Navigate to the Tenant Clusters page in the Multitenancy section
- Click "New Tenant Cluster"
- Provide a name and optional description
- Save the cluster
Assigning Tenants to a Cluster
- From the Tenant Clusters page, click on a cluster
- In the Tenants tab, click "Attach Existing"
- Select one or more tenants to add to the cluster
- Alternatively, edit a tenant directly and select a cluster from the dropdown
- If the cluster has no tenants, the first tenant added will automatically become the Parent Tenant.
Setting/Changing the Parent Tenant
- Navigate to the Tenant Clusters page (within the "Tenant Groups" admin area).
- Click on the cluster you wish to manage.
- Go to the "Tenants" tab.
- You will see a list of tenants in the cluster. A toggle column labeled "Parent Tenant" indicates the current parent and allows you to change it.
- Enable the toggle for the tenant you wish to set as the new Parent Tenant. The system will automatically update the cluster and notify you.
- Note: A cluster that has tenants must always have a Parent Tenant. If the current Parent Tenant is detached, a new one must be assigned if other tenants remain.
Filtering Tenants by Cluster
In code, you can filter tenants by cluster using the scope:
// Get all tenants in a specific cluster
$tenants = Tenant::ofTenantCluster($clusterId)->get();
Best Practices
- Naming Conventions: Use clear, descriptive names for clusters that reflect their purpose
- Parent Tenant Selection: Choose a Parent Tenant that is genuinely responsible for the group of tenants within the cluster.
- Cluster Organization: Consider organizing clusters by:
- Geographic regions
- Business divisions
- Client categories
- Deployment environments
- Maintenance: Regularly review and update cluster assignments to ensure they remain relevant