Support Packet Generation Tech Spec

OVERVIEW

Support Packet Generation tool will allow users to grab information about their Mattermost instance to provide to the support team to save the trouble for support asking manually for this information. It is in the hopes of increasing productivity and making the process of getting information from a customer faster and easier.

After a meeting with product manager and UX designer, it was decided that the code will be directly implemented in the codebase without a plugin. The people who will have access to it is anyone who access to the system console (or any Admin roles).

The reason it was decided that putting it directly in the code base rather than a plugin makes more sense is because

  1. We wanted it somewhere in the system console. After brief discussion with the integrations team, it was mentioned that plugins currently can render a custom React component for a plugin’s settings but that is as much modifying they can do in the system console. There is currently no structured way to do any more modifying and would require “creative thinking” as mentioned by integrations.

  2. We noticed that we already have a commercial support link in the dropdown in the hamburger menu of the system console which leads you the a generic Mattermost support webpage. It was decided that we like to improve upon this even further by adding a modal for licensed customers (customers with E10 and E20 licenses) which allows them to download the support packet.

GOALS

  1. Make it easier for support to gather the information they need by providing an downloadable zip file that includes 5 files which will allow support to trouble shoot users problems easier.

SCOPE

Out:

High-level Architecture

A GET request will be made to an endpoint which then returns a zip file with one support_packet.yaml file outlining information regarding their server, a plugins.json file which will outline all the plugins they have installed on their server, a mattermost.log and notifications.log which has all the server activity in it, and finally a sanitized_config.json which has their active sanitized config settings.


Permissions

Anyone who has access to system console (any admin role) should be allowed to do this.

Schema

No database changes required

REST API

GET /api4/system/generate_support_packet

Once the above API endpoint is hit, a ZIP file namedmattermost_support_packet_YYYY-MM-DD-HH-MM.zip

Within this ZIP file will include 5 files.

support_packet.yaml

server_os: {os} database_type: {type} database_version: {version} ldap_vendor_name: {name} ldap_vendor_version: {version} elastic_server_version: {elastic_version} elastic_server_plugins: {plugins}

The possible GO struct to marshal to the above format may look something like this

type SupportPacket struct { ServerOS string `yaml:"server_os"` DatabaseType string `yaml:"database_type"` DatabaseVersion string `yaml:"database_version"` LdapVendorName string `yaml:"ldap_vendor_name,omitempty"` LdapVendorVersion string `yaml:"ldap_vendor_version,omitempty"` ElasticServerVersion string `yaml:"elastic_server_version,omitempty"` ElasticServerPlugins string[] `yaml:"elastic_server_plugins,omitempty"` }

More information on the Go YAML library we use today can be found here gopkg.in/yaml.v2

plugins.json

{ "active": [ ], "inactive": [{ "id": "antivirus", "name": "Antivirus", "description": "Antivirus plugin for scanning uploaded files.", "version": "0.1.2", "server": { "executables": { "linux-amd64": "server/dist/plugin-linux-amd64", "darwin-amd64": "server/dist/plugin-darwin-amd64", "windows-amd64": "server/dist/plugin-windows-amd64.exe" }, "executable": "" }, "settings_schema": { "header": "Antivirus plugin for scanning uploaded files to Mattermost, uses ClamAV to scan files. See [documentation here](https://github.com/mattermost/mattermost-plugin-antivirus)", "footer": "", "settings": [{ "key": "ClamavHostPort", "display_name": "ClamAV - Host and Port", "type": "text", "help_text": "The hostname and port to connect to clamd", "placeholder": "localhost:3310", "default": "localhost:3310" }, { "key": "ScanTimeoutSeconds", "display_name": "Scan Timeout (seconds)", "type": "number", "help_text": "How long the virus scan can take before giving up.", "placeholder": "10", "default": 10 } ] } }] }

mattermost.log

notifications.log

sanitized_config.json (A truncated example)


Here, I will be discussing how we will retrieve the information seen in the support_packet.yaml

Server OS:

In golang, we can use runtime.GOOS to get the operating system which the server is running on.

Although not mentioned in the MVP, we can use runtime.GOARCH to get the architecture of the server. (ex. amd64)

Database Type:

In the store, we have a function available called DriverName() which returns either mysql or postgres. This is what we use elsewhere to determine if our database is either mysql or postgres.

(*SqlChannelStore).DriverName()

Database Version:

In the database, we have a table called Systems which we can query to get the version.

SELECT systems WHERE name == Version

Possibly looking to use GetByName in System SQL store.

List plugins installed (including versions) (Included as a separate file called plugins.json):

We can do a

which we can then marshal into a JSON file as shown above.

LDAP Vendor & LDAP Version:

Due to the limited support for retrieving these and complexities that arise when dealing with different vendors and their specific implementation, the best we can do is query for vendorName and vendorVersion and provide those if anything return.

Elastic Search Server Version:

In elasticsearch.go in enterprise, in the Start() function, we are already getting the version and storing it in a variable called version. It would be a matter of storing that in a new field called fullVersion and writing a function which returns that since currently version field is only storing the major version instead of the full version.

Elastic Search Plugins:

The library we are using for Elastic Search (https://github.com/olivere/elastic )

already has this implemented (https://github.com/olivere/elastic/blob/v6.2.35/plugins.go#L24)

Log File (mattermost.log + notifications.log):

The below code snippet is a example of how the mattermost.log will be retrieved and then it will be taken and attached to the .zip.

Active Config Setting (This will be included as a separate file called sanitized_config.json)

A matter of calling c.App.GetSanitizedConfig() as it already seems to scrub out all confidential information


-Designs can be found at https://www.figma.com/file/ck3EfTynW7nrRlkJGCYKRL/Support-Packet-Request .

Regarding debug level, check to see if their out logs to file is enabled and if the file log levels is set to debug. If not, then let’s show the message

Before downloading the support packet, set Output Logs to File to true and set File Log Level to DEBUG [here]. Afterwards, please recreate the issue with these settings before submitting.

as seen in the design to encourage them to enable it and set it to debug and try to recreate their issue to provide us with the most amount of information.

This will be a simple modal with translated text and button to download your support packet.

CLI

ZIP file creation not accessible via CLI in any of the current phases.

Mobile and Webapp

Mobile does not have anything because this feature is only accessible through the system console

Performance

No performance impact expected as this is simple/request response that is retrieving information.

CREDITS

Big thanks to the following for their support and help:

@Scott Bishel

@Martin Kraft (Deactivated)

@Katie Wiersgalla

@Paul Rothrock (Deactivated)

@Sven Hüster

@Michael Gamble (Deactivated)