We provide connectivity services and would like to use grafana to provide our external clients with one or more relatively simple dashboards to show equipment status and bandwidth utilization and so on.
Since these are external clients, we do not want any access to settings to be available to them, and clients should be completely isolated from each other.
Since there are also a few hundred of them, we would like to keep any manual updates or other tasks to organizations, user accounts and dashboards to an absolute minimum.
Our planned approach to do this is now as follows, any feedback and suggestions for improvements are very much welcome.
Our grafana is running an unlicensed Enterprise version, on latest stable repo installed yesterday (5/29/20). OS is CentOS 8.
Looking at https://grafana.com/docs/grafana/latest/administration/provisioning/ it seems that provisioning of organizations is not possible.
As an alternative we now plan to create the organizations directly in the mysql database. (we do not use the default sqlite session database.)
INSERT INTO org (version, name, created, updated) VALUES ('1', '*$ClientName*', curdate(), curdate())
The Organization ID is auto-increment so we don’t need to worry about this. Most other columns are not mandatory, except for version (set to 1 here) and created and updated timestamps (here set to the current system date/time).
Because we want to reuse the credentials supplied to the client for other applications (e.g. ticketing), we have created client records in LDAP. Each client-company has its own OU and Security Group, and individual user accounts for each client are created in their respective OU and added to their Security Group.
To allow these accounts to then successfully log in to Grafana I believe this needs to be added in /etc/grafana/ldap.toml
We could create some scripting solution to insert multiple [[servers.group_mappings]] blocks looking something like this:
[[servers.group_mappings]] group_dn = "CN=$ClientNameGroup1,OU=$ClientName1,DC=domain,DC=tld" org_role = "Viewer" org_id ="$ClientOrgID" [[servers.group_mappings]] group_dn = "CN=$ClientNameGroup2,OU=$ClientName2,DC=domain,DC=tld" org_role = "Viewer" org_id ="$ClientOrgID"
and so on and so on.
To retrieve the org ID from the MySQL DB it’s possible to use a command like this:
mysql -ugrafanauser -ppassword -sN grafana -e "select id from org where name='$ClientName';"
The output (because of -sN) is only the number (e.g. ‘2’), so this can be directly stored in a script variable.
To avoid any potential issues with assigning the org ID I’ll keep the default org ID empty without any datasource and with a text panel on the home dashboard asking the user to contact support.
It looks like that we have to create separate entries for each organization in /etc/grafana/provisioning/datasources/datasource.yaml, even if it points to the same datasource.
apiVersion: 1 datasources: - name: Graphite type: graphite access: proxy orgid: 2 uid: $ClientName-DS url: http://graphitehost.domain.tld:8080
and so on and so on
For the dashboard providers it is not yet clear to me what the best approach will be. The example provided in the provisioning page in the docs does not provide a file name, but just the directory path.So it seems to me that I might have to create a separate dashboard directory for each client, which will then have their own dashboard json files in them with each their own version numbering.
Of course these dashboard JSON files will be mostly identical.
I am currently in the process of setting this system up, but would very much like to hear experiences and advice from people with similar setups or plans.
If there is any interest I can convert this into a How-To when I have everything working and cleared up all unknowns.