Coding your own Module

Bell scripts are placed in the same directory on the root level. In the examples below we use ext for an extension of a script, for Powershell it is ps1 (and in the examples below, we use Powershell cripts as examples). There are 2 required scripts: login.ext, audit.ext, all other scripts are optional.

login.ext processes the login request:

The login logic is completely encapsulated inside the script. It can use predefined hardcoded logins, it can have it'w own database or users/logins, or, which is better, it can use Active Directory. The framework is unaware of what method is used.

When login is successful (second example), the script should output 2 lines. The first line is semicolon-separated list of security "groups". That list is passed to every other script, so any script can decide if an operation should be denied or not. 

You can put AD group names as is, but usually such group names are long and might change, so it makes sense to 'translate' them with some short names. In the example above AD groups are translated into "RO" (those who can read everything), and "RW" (those who can do more dangerous things. Download any module to check the example with AD.

The second line in the cortege for the root element. Corteges are explained below, they are used to define tree's contents. 

A cortege consists of 4 |-separated fields: name, which is a name you can see in GUI, element class, element type, and tags

In this example there are 2 scripts, but quite often there is just one. Why do we need more than one script? This is useful because you can 'plug' additional functionality to an existing module, you can add tree elements (properties) without modifying the existing script. All you need to know is the class name. What happens if we run the script?

All scripts have 4 parameters: user, group (list of groups created once for the session by login.ext), name of the caller element and tags.

So we can see that both scripts had returned the corteges. Name is displayed in a tree, class in used to identify, what script(s) to run. Type defines a type of element: folder for a tree, and leaves elements are text, html, file and chart. Tags are used to pass the context from one script to another. Tags typically are key=value pairs, where multiple key=values are separated with ~. Values can contain a sign '=', the first = is interpreted as key/value separator, while all successive equal signs are interpreted as parts of the value. 

When a 'leaf' element is executed, the bell framework searches for the script called <classname>.ext, so only one script is executed. This is because a report is 'atomic' and there is nothing to merge. Nice reports are typically produced by the elements of the type 'html'. 

Note how context is passed thru tags. Formatting to HTML is easily achieved in Powershell. lets check how that script works step by step. 

param ([string]$usr, [string]$grp, [string]$name, [string]$tags) 
. $PSScriptRoot/MSSQLquery.ps1 
parse $tags 

$conn = $tagval.Conn 
$dbname = $tagval.dbname 

In the beginning, we add the common MSSQL module. Function 'parse' parses tags into a hash table $tagval. Demo SQL module doesn't have any security, so $grp is ignored. Next, we populate $Header as the table header and $q as the SQL query to get the biggest tables. Finally, we do:

'text' scripts return plain text as is:

$d = MSSQLquery $conn $q | Select-Object -Property * -ExcludeProperty "ItemArray", "RowError", "RowState", "Table", "HasErrors"
$d | ConvertTo-HTML -Title "Rows" -Head $Header -body '<h2>Top 30 tables, by row count, desc</h2>' 

And finally, 'chart' returns chart data in the following format:
Line 1 - chart type: word Line or Bar, optionally followed by ,startAtzero -  this fixed Ymin=0
Line 2 - title
Line 3 - X axis name
Line 4 - Y axis name
Line 5 - Column names, comma separated. 
Next - values, comma separated. Values must be int or float, first column must be datetime (format with 'T'), scale is auto-calculated.

Code sample (query is in $q):

Instant SQL server cpu for the last seconds
X - time
Y - CPU pct
MSSQLchart $conn $q

audit.ext is executed after every operation. Bell framework passes the following information to a script: all 4 parameters, like for any other script, followed by status code (0 - success). Audit script must be present, it can be empty if you don't need it. Typically, it logs all information into a file or a database. You can find working examples in the modules.

Finally, you can force download of a file (useful for the bug files). Specify type='file'. Script shoudl output full path to a file