main.go

The main function in then main.go is the entry point for your plugin. This function must call plugin.Serve from the plugin sdk to instantiate your plugin gRPC server. You will pass the plugin function that you will create in the plugin.go file.

package main
import (
"github.com/turbot/steampipe-plugin-sdk/v5/plugin"
"github.com/turbot/steampipe-plugin-zendesk/zendesk"
)
func main() {
plugin.Serve(&plugin.ServeOpts{PluginFunc: zendesk.Plugin})
}

plugin.go

The plugin.go file should implement a single Plugin Definition (Plugin() function) that returns a pointer to a Plugin to be loaded by the gRPC server.

By convention, the package name for your plugin should be the same name as your plugin, and go files for your plugin (except main.go) should reside in a folder with the same name.

Plugin Definition

ArgumentDescription
NameThe name of the plugin (steampipe-plugin-{plugin name}).
TableMapA map of table names to Table definitions.
DefaultTransformA default Transform Function to be used when one is not specified. While not required, this may save quite a bit of repeated code.
DefaultGetConfigProvides an optional mechanism for providing plugin-level defaults to a get config. This is merged with the GetConfig defined in the table and/or columns. Typically, this is used to standardize error handling with ShouldIgnoreError.
SchemaModeSpecifies if the schema should be checked and re-imported if changed every time Steampipe starts. This can be set to dynamic or static. Defaults to static.
RequiredColumnsAn optional list of columns that ALL tables in this plugin MUST implement.

Example Plugin Definition

Here's the definition of the Zendesk plugin.

package zendesk
import (
"context"
"github.com/turbot/steampipe-plugin-sdk/plugin"
"github.com/turbot/steampipe-plugin-sdk/plugin/transform"
)
func Plugin(ctx context.Context) *plugin.Plugin {
p := &plugin.Plugin{
Name: "steampipe-plugin-zendesk",
DefaultTransform: transform.FromGo().NullIfZero(),
TableMap: map[string]*plugin.Table{
"zendesk_brand": tableZendeskBrand(),
"zendesk_group": tableZendeskGroup(),
"zendesk_organization": tableZendeskOrganization(),
"zendesk_search": tableZendeskSearch(),
"zendesk_ticket": tableZendeskTicket(),
"zendesk_ticket_audit": tableZendeskTicketAudit(),
"zendesk_trigger": tableZendeskTrigger(),
"zendesk_user": tableZendeskUser(),
},
}
return p
}

Table Definition

The plugin.Table may specify:

ArgumentDescription
NameThe name of the table.
DescriptionA short description, added as a comment on the table and used in help commands and documentation.
ColumnsAn array of column definitions.
ListA List Config definition, used to fetch the data items used to build all rows of a table.
GetA Get Config definition, used to fetch a single item.
DefaultTransformA default transform function to be used when one is not specified. If set, this will override the default set in the plugin definition.

Example Table Definition

Here's how the zendesk_user table is defined.

func tableZendeskUser() *plugin.Table {
return &plugin.Table{
Name: "zendesk_user",
Description: "Zendesk Support has three types of users: end users (your customers), agents, and administrators.",
List: &plugin.ListConfig{
Hydrate: listUser,
},
Get: &plugin.GetConfig{
KeyColumns: plugin.SingleColumn("id"),
Hydrate: getUser,
},
Columns: []*plugin.Column{
{Name: "active", Type: proto.ColumnType_BOOL, Description: "False if the user has been deleted"},
{Name: "alias", Type: proto.ColumnType_STRING, Description: "An alias displayed to end users"},
{Name: "chat_only", Type: proto.ColumnType_BOOL, Description: "Whether or not the user is a chat-only agent"},
{Name: "created_at", Type: proto.ColumnType_TIMESTAMP, Description: "The time the user was created"},
{Name: "custom_role_id", Type: proto.ColumnType_INT, Description: "A custom role if the user is an agent on the Enterprise plan"},
{Name: "default_group_id", Type: proto.ColumnType_INT, Description: "The id of the user's default group"},
{Name: "details", Type: proto.ColumnType_STRING, Description: "Any details you want to store about the user, such as an address"},
{Name: "email", Type: proto.ColumnType_STRING, Description: "The user's primary email address. *Writeable on create only. On update, a secondary email is added."},
{Name: "external_id", Type: proto.ColumnType_STRING, Description: "A unique identifier from another system. The API treats the id as case insensitive. Example: \"ian1\" and \"Ian1\" are the same user"},
{Name: "id", Type: proto.ColumnType_INT, Description: "Automatically assigned when the user is created"},
{Name: "last_login_at", Type: proto.ColumnType_TIMESTAMP, Description: "The last time the user signed in to Zendesk Support"},
{Name: "locale", Type: proto.ColumnType_STRING, Description: "The user's locale. A BCP-47 compliant tag for the locale. If both \"locale\" and \"locale_id\" are present on create or update, \"locale_id\" is ignored and only \"locale\" is used."},
{Name: "locale_id", Type: proto.ColumnType_INT, Description: "The user's language identifier"},
{Name: "moderator", Type: proto.ColumnType_BOOL, Description: "Designates whether the user has forum moderation capabilities"},
{Name: "name", Type: proto.ColumnType_STRING, Description: "The user's name"},
{Name: "notes", Type: proto.ColumnType_STRING, Description: "Any notes you want to store about the user"},
{Name: "only_private_comments", Type: proto.ColumnType_BOOL, Description: "true if the user can only create private comments"},
{Name: "organization_id", Type: proto.ColumnType_INT, Description: "The id of the user's organization. If the user has more than one organization memberships, the id of the user's default organization"},
{Name: "phone", Type: proto.ColumnType_STRING, Description: "The user's primary phone number."},
{Name: "photo_content_type", Type: proto.ColumnType_STRING, Description: "The content type of the image. Example value: \"image/png\""},
{Name: "photo_content_url", Type: proto.ColumnType_STRING, Description: "A full URL where the attachment image file can be downloaded"},
{Name: "photo_deleted", Type: proto.ColumnType_STRING, Description: "If true, the attachment has been deleted"},
{Name: "photo_file_name", Type: proto.ColumnType_STRING, Description: "The name of the image file"},
{Name: "photo_id", Type: proto.ColumnType_INT, Description: "Automatically assigned when created"},
{Name: "photo_inline", Type: proto.ColumnType_BOOL, Description: "If true, the attachment is excluded from the attachment list and the attachment's URL can be referenced within the comment of a ticket. Default is false"},
{Name: "photo_size", Type: proto.ColumnType_INT, Description: "The size of the image file in bytes"},
{Name: "photo_thumbnails", Type: proto.ColumnType_JSON, Description: "An array of attachment objects. Note that photo thumbnails do not have thumbnails"},
{Name: "report_csv", Type: proto.ColumnType_BOOL, Description: "Whether or not the user can access the CSV report on the Search tab of the Reporting page in the Support admin interface."},
{Name: "restricted_agent", Type: proto.ColumnType_BOOL, Description: "If the agent has any restrictions; false for admins and unrestricted agents, true for other agents"},
{Name: "role", Type: proto.ColumnType_STRING, Description: "The user's role. Possible values are \"end-user\", \"agent\", or \"admin\""},
{Name: "role_type", Type: proto.ColumnType_INT, Description: "The user's role id. 0 for custom agents, 1 for light agent, 2 for chat agent, and 3 for chat agent added to the Support account as a contributor (Chat Phase 4)"},
{Name: "shared", Type: proto.ColumnType_BOOL, Description: "If the user is shared from a different Zendesk Support instance. Ticket sharing accounts only"},
{Name: "shared_agent", Type: proto.ColumnType_BOOL, Description: "If the user is a shared agent from a different Zendesk Support instance. Ticket sharing accounts only"},
{Name: "shared_phone_number", Type: proto.ColumnType_BOOL, Description: "Whether the phone number is shared or not."},
{Name: "signature", Type: proto.ColumnType_STRING, Description: "The user's signature. Only agents and admins can have signatures"},
{Name: "suspended", Type: proto.ColumnType_BOOL, Description: "If the agent is suspended. Tickets from suspended users are also suspended, and these users cannot sign in to the end user portal"},
{Name: "tags", Type: proto.ColumnType_JSON, Description: "The user's tags. Only present if your account has user tagging enabled"},
{Name: "ticket_restriction", Type: proto.ColumnType_STRING, Description: "Specifies which tickets the user has access to. Possible values are: \"organization\", \"groups\", \"assigned\", \"requested\", null"},
{Name: "timezone", Type: proto.ColumnType_STRING, Description: "The user's time zone."},
{Name: "two_factor_auth_enabled", Type: proto.ColumnType_BOOL, Description: "If two factor authentication is enabled"},
{Name: "updated_at", Type: proto.ColumnType_TIMESTAMP, Description: "The time the user was last updated"},
{Name: "url", Type: proto.ColumnType_STRING, Description: "The user's API url"},
{Name: "user_fields", Type: proto.ColumnType_JSON, Description: "Values of custom fields in the user's profile."},
{Name: "verified", Type: proto.ColumnType_BOOL, Description: "Any of the user's identities is verified."},
},
}
}

List Config

A ListConfig definition defines how to list all rows of a table.

ArgumentDescription
KeyColumnsAn optional list of columns that require a qualifier in order to list data for this table.
HydrateA hydrate function which is called first when performing a 'list' call.
ParentHydrateAn optional parent list function - if you list items with a parent-child relationship, this will list the parent items.

Get Config

A GetConfig definition defines how to get a single row of a table.

ArgumentDescription
KeyColumnsA list of keys which are used to uniquely identify rows - used to determine whether a query is a 'get' call.
ItemFromKey [DEPRECATED]]This property is deprecated.
HydrateA hydrate function which is called first when performing a 'get' call. If this returns 'not found', no further hydrate functions are called.
ShouldIgnoreErrorA function which will return whether to ignore a given error.

Column Definition

A column definition definition specifies the name and description of the column, its data type, and the functions to call to hydrate the column (if the list call does not) and transform it (if the default transformation is not sufficient).

ArgumentDescription
NameThe column name.
TypeThe data type for this column.
DescriptionThe column description, added as a comment and used in help commands and documentation.
HydrateYou can explicitly specify the hydrate function function to populate this column. This is only needed if neither the default hydrate functions nor the List function return data for this column.
DefaultAn optional default column value.
TransformAn optional chain of transform functions to generate the column value.

Column Data Types

Currently supported data types are:

NameType
ColumnType_BOOLBoolean
ColumnType_INTInteger
ColumnType_DOUBLEDouble precision floating point
ColumnType_STRINGString
ColumnType_JSONJSON
ColumnType_DATETIMEDate/Time (Deprecated - use ColumnType_TIMESTAMP)
ColumnType_TIMESTAMPDate/Time
ColumnType_IPADDRIP Address
ColumnType_CIDRIP network CIDR
ColumnType_UNKNOWNUnknown
ColumnType_INETEither an IP Address or an IP network CIDR
ColumnType_LTREELtree