The essential configurations to bootstrap Honeydipper
Include the following section in your init.yaml under repos section
- repo: https://github.com/honeydipper/honeydipper-config-essentials
This repo provides following drivers
This driver enables Honeydipper to interact with kubernetes clusters including finding and recycling deployments, running jobs and getting job logs, etc. There a few wrapper workflows around the driver and system functions, see the workflow composing guide for detail. This section provides information on how to configure the driver and what the driver offers as rawActions, the information may be helpful for understanding how the kubernetes workflow works.
Start a run-to-complete job in the specified cluster. Although you can, it is not recommended to use this rawAction directly. Use the wrapper workflows instead.
Parameters
- type
The type of the kubernetes cluster, basically a driver that provides a RPC call for fetching the kubeconfig from. currently only gcloud-gke and local is supported, more types to be added in the future.
- source
A list of k/v pair as parameters used for making the RPC call to fetch the kubeconfig. For local, no value is required, the driver will try to use in-cluster configurations. For gcloud-gke clusters, the k/v pair should have keys including service_account, project, zone and cluster.
- namespace
The namespace for the job
- job
the job object following the kubernetes API schema
Returns
- metadata
The metadata for the created kubernetes job
- status
The status for the created kuberntes job
See below for a simple example
---
workflows:
call_driver: kubernetes.createJob
with:
type: local
namespace: test
job:
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
recycle a deployment by deleting the replicaset and let it re-spawn.
Parameters
- type
The type of the kubernetes cluster, see createJob rawAction for detail
- source
A list of k/v pair as parameters used for getting kubeconfig, see createJob rawAction for detail
- namespace
The namespace for the deployment to be recycled, default if not specified
- deployment
a label selector for identifying the deployment, e.g. run=my-app, app=nginx
See below for a simple example
---
rules:
- when:
source:
system: alerting
trigger: fired
do:
call_driver: kubernetes.recycleDeployment
with:
type: gcloud-gke
source:
service_account: ENC[gcloud-kms, ...masked... ]
zone: us-central1-a
project: foo
cluster: bar
deployment: run=my-app
Given a kubernetes job metadata name, fetch and return all the logs for this job. Again, it is not recommended to use createJob, waitForJob or getJobLog directly. Use the helper workflows instead.
Parameters
- type
The type of the kubernetes cluster, see createJob rawAction for detail
- source
A list of k/v pair as parameters used for getting kubeconfig, see createJob rawAction for detail
- namespace
The namespace for the job
- job
The metadata name of the kubernetes job
Returns
- log
mapping from pod name to a map from container name to the logs
- output
with all logs concatinated
See below for a simple example
---
workflows:
run_job:
steps:
- call_driver: kubernetes.createJob
with:
type: local
job:
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
- call_driver: kubernetes.waitForJob
with:
type: local
job: $data.metadta.name
- call_driver: kubernetes.getJobLog
with:
type: local
job: $data.metadta.name
Given a kubernetes job metadata name, use watch API to watch the job until it reaches a terminal state. This action usually follows a createJob call and uses the previous call's output as input. Again, it is not recommended to use createJob, waitForJob or getJobLog directly. Use the helper workflows instead.
Parameters
- type
The type of the kubernetes cluster, see createJob rawAction for detail
- source
A list of k/v pair as parameters used for getting kubeconfig, see createJob rawAction for detail
- namespace
The namespace for the job
- job
The metadata name of the kubernetes job
- timeout
The timeout in seconds
Returns
- status
The status for the created kuberntes job
See below for a simple example
---
workflows:
run_job:
steps:
- call_driver: kubernetes.createJob
with:
type: local
job:
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
- call_driver: kubernetes.waitForJob
with:
type: local
job: $data.metadta.name
redispubsub driver is used internally to facilitate communications between different components of Honeydipper system.
Configurations
- connection
The parameters used for connecting to the redis including Addr, Password and DB.
See below for an example
---
drivers:
redispubsub:
connection:
Addr: 192.168.2.10:6379
DB: 2
Password: ENC[gcloud-kms,...masked]
broadcasting a dipper message to all Honeydipper services. This is used in triggering configuration reloading and waking up a suspended workflow. The payload of rawAction call will used as broadcasting dipper message paylod.
Parameters
- broadcastSubject
the subject field of the dipper message to be sent
Below is an example of using the driver to trigger a configuration reload
---
workflows:
reload:
call_driver: redispubsub.send
with:
broadcastSubject: reload
force: $?ctx.force
Below is another example of using the driver to wake up a suspended workflow
---
workflows:
resume_workflow:
call_driver: redispubsub.send
with:
broadcastSubject: resume_session
key: $ctx.resume_token
labels:
status: $ctx.labels_status
reason: $?ctx.labels_reason
payload: $?ctx.resume_payload
redisqueue driver is used internally to facilitate communications between different components of Honeydipper system. It doesn't offer rawActions or rawEvents for workflow composing.
Configurations
- connection
The parameters used for connecting to the redis including Addr, Password and DB.
See below for an example
---
drivers:
redisqueue:
connection:
Addr: 192.168.2.10:6379
DB: 2
Password: ENC[gcloud-kms,...masked]
This driver enables Honeydipper to make outbound web requests
making an outbound web request
Parameters
- URL
The target url for the outbound web request
- header
A list of k/v pair as headers for the web request
- method
The method for the web request
- content
Form data, post data or the data structure encoded as json for application/json content-type
Returns
- status_code
HTTP status code
- cookies
A list of k/v pair as cookies received from the web server
- headers
A list of k/v pair as headers received from the web server
- body
a string contains all response body
- json
if the return is json content type, this will be parsed json data blob
See below for a simple example
workflows:
sending_request:
call_driver: web.request
with:
URL: https://ifconfig.co
Below is an example of specifying header for the outbound request defined through a system function
systems:
my_api_server:
data:
token: ENC[gcloud-kms,...masked...]
url: https://foo.bar/api
function:
secured_api:
driver: web
parameters:
URL: $sysData.url
header:
Authorization: Bearer {{ .sysData.token }}
content-type: application.json
rawAction: request
This driver enables Honeydipper to receive incoming webhooks to trigger workflows
Configurations
- Addr
the address and port the webhook server is listening to
for example
---
drivers:
webhook:
Addr: :8080 # listening on all IPs at port 8080
receiving an incoming webhook
Returns
- url
the path portion of the url for the incoming webhook request
- method
The method for the web request
- form
a list of k/v pair as query parameters from url parameter or posted form
- headers
A list of k/v pair as headers received from the request
- host
The host part of the url or the Host header
- remoteAddr
The client IP address and port in the form of xx.xx.xx.xx:xxxx
- json
if the content type is application/json, it will be parsed and stored in here
The returns can also be used in matching conditions
See below for a simple example
rules:
- do:
call_workflow: foobar
when:
driver: webhook
if_match:
form:
s: hello
headers:
content-type: application/x-www-form-urlencoded
method: POST
url: /foo/bar
Below is an example of defining and using a system trigger with webhook driver
systems:
internal:
data:
token: ENC[gcloud-kms,...masked...]
trigger:
webhook:
driver: webhook
if_match:
headers:
Authorization: Bearer {{ .sysData.token }}
remoteAddr: :regex:^10\.
rules:
- when:
source:
system: internal
trigger: webhook
if_match:
url: /foo/bar
do:
call_workflow: do_something
This system enables Honeydipper to integrate with github, so Honeydipper can react to github events and take actions on github.
Configurations
- oauth_token
The token or API ID used for making API calls to github
- token
A token used for authenticate incoming webhook requests, every webhook request must carry a form field Token in the post body or url query that matches the value
- path
The path portion of the webhook url, by default
/github/push
For example
---
systems:
github:
data:
oauth_token: ENC[gcloud-kms,...masked...]
token: ENC[gcloud-kms,...masked...]
path: "/webhook/github"
Assuming the domain name for the webhook server is :code:`myhoneydipper.com', you should configure the webhook in your repo with url like below
https://myhoneydipper.com/webhook/github?token=...masked...
This is a catch all event for github webhook requests. It is not to be used directly, instead should be used as source for defining other triggers.
This is triggered when a comment is added to a pull request.
Matching Parameters
- .json.repository.full_name
This field is to match only the pull requests from certain repo
- .json.comment.user.login
This is to match only the comments from certain username
- .json.comment.author_association
This is to match only the comments from certain type of user. See github API reference here for detail.
- .json.comment.body
This field contains the comment message, you can use regular express pattern to match the content of the message.
Export Contexts
- git_repo
This context variable will be set to the name of the repo, e.g.
myorg/myrepo
- git_user
This context variable will be set to the user object who made the comment
- git_issue
This context variable will be set to the issue number of the PR
- git_message
This context variable will be set to the comment message
See below snippet for example
---
rules:
- when:
source:
system: github
trigger: pr_commented
if_match:
json:
repository:
full_name: myorg/myrepo # .json.repository.full_name
comment:
autho_association: CONTRIBUTOR
body: ':regex:^\s*terraform\s+plan\s*$'
do:
call_workflow: do_terraform_plan
# following context variables are available
# git_repo
# git_issue
# git_message
# git_user
#
This is triggered when a new pull request is created
Matching Parameters
- .json.repository.full_name
This field is to match only the pull requests from certain repo
- .json.pull_request.base.ref
This field is to match only the pull requests made to certain base branch, note that the ref value here does not have the
ref/heads/
prefix (different from push event). So to match master branch, just usemaster
instead ofref/heads/master
.- .json.pull_request.user.login
This field is to match only the pull requests made by certain user
Export Contexts
- git_repo
This context variable will be set to the name of the repo, e.g.
myorg/myrepo
- git_ref
This context variable will be set to the name of the branch, e.g.
mybrach
, noref/heads/
prefix- git_commit
This context variable will be set to the short (7 characters) commit hash of the head commit of the PR
- git_user
This context variable will be set to the user object who created the PR
- git_issue
This context variable will be set to the issue number of the PR
- git_title
This context variable will be set to the title of the PR
See below snippet for example
---
rules:
- when:
source:
system: github
trigger: pull_request
if_match:
json:
repository:
full_name: myorg/myrepo # .json.repository.full_name
pull_request:
base:
ref: master # .json.pull_request.base.ref
do:
call_workflow: do_something
# following context variables are available
# git_repo
# git_ref
# git_commit
# git_issue
# git_title
# git_user
#
This is triggered when github receives a push.
Matching Parameters
- .json.repository.full_name
Specify this in the
when
section of the rule usingif_match
, to filter the push events for the repo- .json.ref
This field is to match only the push events happened on certain branch
Export Contexts
- git_repo
This context variable will be set to the name of the repo, e.g.
myorg/myrepo
- git_ref
This context variable will be set to the name of the branch, e.g.
ref/heads/mybrach
- git_commit
This context variable will be set to the short (7 characters) commit hash of the head commit of the push
See below snippet for example
---
rules:
- when:
source:
system: github
trigger: push
if_match:
json:
repository:
full_name: myorg/myrepo # .json.repository.full_name
ref: ref/heads/mybranch # .json.ref
do:
call_workflow: do_something
# following context variables are available
# git_repo
# git_ref
# git_commit
#
Or, you can match the conditions in workflow using exported context variables instead of in the rules
---
rules:
- when:
source:
system: github
trigger: push
do:
if_match:
- git_repo: mycompany/myrepo
git_ref: ref/heads/master
- git_repo: myorg/myfork
git_ref: ref/heads/mybranch
call_workflow: do_something
This is a generic function to make a github API call with the configured oauth_token. This function is meant to be used for defining other functions.
Input Contexts
- resource_path
This field is used as the path portion of the API call url
This function will create a comment on the given PR
Input Contexts
- git_repo
The repo that commit is for, e.g.
myorg/myrepo
- git_issue
The issue number of the PR
- message
The content of the comment to be posted to the PR
See below for example
---
rules:
- when:
source:
system: github
trigger: pull_request
do:
if_match:
git_repo: myorg/myrepo
git_ref: master
call_function: github.createComment
with:
# the git_repo is available from event export
# the git_issue is available from event export
message: type `honeydipper help` to see a list of available commands
This function will create a commit status on the given commit.
Input Contexts
- git_repo
The repo that commit is for, e.g.
myorg/myrepo
- git_commit
The short commit hash for the commit the status is for
- context
the status context, a name for the status message, by default
Honeydipper
- status
the status data structure according github API here
See below for example
---
rules:
- when:
source:
system: github
trigger: push
do:
if_match:
git_repo: myorg/myrepo
git_ref: ref/heads/testbranch
call_workflow: post_status
workflows:
post_status:
call_function: github.createStatus
with:
# the git_repo is available from event export
# the git_commit is available from event export
status:
state: pending
description: Honeydipper is scanning your commit ...
This function will fetch a file from the specified repo and branch.
Input Contexts
- git_repo
The repo from where to download the file, e.g.
myorg/myrepo
- git_ref
The branch from where to download the file, no
ref/heads/
prefix, e.g.master
- path
The path for fetching the file, no slash in the front, e.g.
conf/nginx.conf
Export Contexts
- file_content
The file content as a string
See below for example
---
workflows:
fetch_circle:
call_function: github.getContent
with:
git_repo: myorg/mybranch
git_ref: master
path: .circleci/config.yml
export:
circleci_conf: :yaml:{{ .ctx.file_content }}
This system enables Honeydipper to integrate with jira, so Honeydipper can react to jira events and take actions on jira.
Configurations
- jira_credential
The credential used for making API calls to jira
- token
A token used for authenticate incoming webhook requests, every webhook request must carry a form field Token in the post body or url query that matches the value
- path
The path portion of the webhook url, by default
/jira
- jira_domain
Specify the jira domain, e.g.
mycompany
formycompany.atlassian.net
For example
---
systems:
github:
data:
jira_credential: ENC[gcloud-kms,...masked...]
jira_domain: mycompany
token: ENC[gcloud-kms,...masked...]
path: "/webhook/jira"
Assuming the domain name for the webhook server is :code:`myhoneydipper.com', you should configure the webhook in your repo with url like below
https://myhoneydipper.com/webhook/jira?token=...masked...
This is a generic trigger for jira webhook events.
This function will add a comment to the jira ticket
Input Contexts
- jira_ticket
The ticket number that the comment is for
- comment_body
Detailed description of the comment
See below for example
---
workflows:
post_comments:
call_function: jira.addComment
with:
jira_ticket: $ctx.jira_ticket
comment_body: |
Ticket has been created by Honeydipper.
This function will create a jira ticket with given information
Input Contexts
- jira_project
The name of the jira project the ticket is created in
- ticket_title
A summary of the ticket
- ticket_desc
Detailed description of the work for this ticket
- ticket_type
The ticket type, by default
Task
Export Contexts
- jira_ticket
The ticket number of the newly created ticket
See below for example
---
workflows:
create_jira_ticket:
call_function: jira.createTicket
with:
jira_project: devlops
ticket_title: upgrading kubernetes
ticket_desc: |
Upgrade the test cluster to kubernetes 1.16
This system enables Honeydipper to interact with kubernetes clusters. This system is intended to be extended to create systems represent actual kubernetes clusters, instead of being used directly.
Configurations
- source
The parameters used for fetching kubeconfig for accessing the cluster, should at least contain a
type
field. Currently, onlylocal
orgcloud-gke
are supported. Forgcloud-gke
type, this should also includeservice_account
,project
,zone
, andcluster
.- namespace
The namespace of the resources when operating on the resources within the cluster, e.g. deployments. By default,
default
namespace is used.
For example
---
systems:
my_gke_cluster:
extends:
- kubernetes
data:
source:
type: gcloud-gke
service_account: ENC[gcloud-kms,...masked...]
zone: us-central1-a
project: foo
cluster: bar
namespace: mynamespace
This function creates a k8s run-to-completion job with given job spec data structure. It is a wrapper for the kubernetes driver createJob rawAction. It leverages the pre-configured system data to access the kubernetes cluster. It is recommmended to use the helper workflows instead of using the job handling functions directly.
Input Contexts
- job
The job data structure following the specification for a run-to-completion job manifest yaml file.
Export Contexts
- jobid
The job ID of the created job
See below for example
---
workflow:
create_job:
call_function: my-k8s-cluster.createJob
with:
job:
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
This function fetch all the logs for a k8s job with the given jobid. It is a wrapper for the kubernetes driver getJobLog rawAction. It leverages the pre-configured system data to access the kubernetes cluster. It is recommmended to use the helper workflows instead of using the job handling functions directly.
Input Contexts
- job
The ID of the job to fetch logs for
Export Contexts
- log
The logs organized in a map of pod name to a map of container name to logs.
- output
The logs all concatinated into a single string
See below for example
---
workflow:
run_simple_job:
steps:
- call_function: my-k8s-cluster.createJob
with:
job: $ctx.job
- call_function: my-k8s-cluster.waitForJob
with:
job: $ctx.jobid
- call_workflow: my-k8s-cluster.getJobLog
with:
job: $ctx.jobid
This function is a wrapper to the kubernetes driver recycleDeployment rawAction. It leverages the pre-configured system data to access the kubernetes cluster.
Input Contexts
- deployment
The selector for identify the deployment to restart, e.g.
app=nginx
See below for example
---
rules:
- when:
source:
system: opsgenie
trigger: alert
do:
steps:
- if_match:
alert_message: :regex:foo-deployment
call_function: my-k8s-cluster.recycleDeployment
with:
deployment: app=foo
- if_match:
alert_message: :regex:bar-deployment
call_function: my-k8s-cluster.recycleDeployment
with:
deployment: app=bar
This function blocks and waiting for a k8s run-to-completion job to finish. It is a wrapper for the kubernetes driver waitForJob rawAction. It leverages the pre-configured system data to access the kubernetes cluster. It is recommmended to use the helper workflows instead of using the job handling functions directly.
Input Contexts
- job
The job id that the function will wait for to reach terminated states
Export Contexts
- job_status
The status of the job, either
success
orfailure
See below for example
---
workflow:
run_simple_job:
steps:
- call_function: my-k8s-cluster.createJob
with:
job: $ctx.job
- call_function: my-k8s-cluster.waitForJob
with:
job: $ctx.jobid
- call_workflow: notify
with:
message: the job status is {{ .job_status }}
This system enables Honeydipper to integrate with opsgenie, so Honeydipper can react to opsgenie alerts and take actions through opsgenie API.
Configurations
- API_KEY
The API key used for making API calls to opsgenie
- token
A token used for authenticate incoming webhook requests, every webhook request must carry a form field Token in the post body or url query that matches the value
- path
The path portion of the webhook url, by default
/opsgenie
For example
---
systems:
opsgenie:
data:
API_KEY: ENC[gcloud-kms,...masked...]
token: ENC[gcloud-kms,...masked...]
path: "/webhook/opsgenie"
Assuming the domain name for the webhook server is :code:`myhoneydipper.com', you should configure the webhook in your opsgenie integration with url like below
https://myhoneydipper.com/webhook/opsgenie?token=...masked...
This event is triggered when an opsgenie alert is raised.
Matching Parameters
- .json.alert.message
This field can used to match alert with only certain messages
- .json.alert.alias
This field is to match only the alerts with certain alias
Export Contexts
- alert_message
This context variable will be set to the detailed message of the alert.
- alert_alias
This context variable will be set to the alias of the alert.
- alert_Id
This context variable will be set to the short alert ID.
- alert_system
This context variable will be set to the constant string,
opsgenie
- alert_url
This context variable will be set to the url of the alert, used for creating links
See below snippet for example
---
rules:
- when:
source:
system: opsgenie
trigger: alert
if_match:
json:
alert:
message: :regex:^test-alert.*$
do:
call_workflow: notify
with:
message: 'The alert url is {{ .ctx.alert_url }}'
This function will send a heartbeat request to opsgenie.
Input Contexts
- heartbeat
The name of the heartbeat as configured in your opsgenie settings
Export Contexts
- result
The return result of the API call
See below for example
---
workflows:
steps:
- call_workflow: do_something
- call_function: opsgenie.heartbeat
with:
heartbeat: test-heart-beat
This function list all on-call schedules or fetch a schedule detail if given a schedule identifier.
Important
This function only fetches first 100 schedules when listing.
Input Contexts
- scheduleId
The name or ID or the schedule of interest; if missing, list all schedules.
- scheduleIdType
The type of the identifier,
name
orid
.
Export Contexts
- schedule
For fetching detail, the data structure that contains the schedule detail
- schedules
For listing, a list of data structure contains the schedule details
See below for example
---
workflows:
steps:
- call_function: opsgenie.schedules
This function will snooze the alert with given alert ID.
Input Contexts
- alert_Id
The ID of the alert to be snoozed
- duration
For how long the alert should be snoozed, use golang time format
Export Contexts
- result
The return result of the API call
See below for example
---
rules:
- when:
source:
system: opsgenie
trigger: alert
do:
if_match:
alert_message: :regex:test-alert
call_function: opsgenie.snooze
# alert_Id is exported from the event
This function gets the user detail with a given ID or list all users
Input Contexts
- userId
The ID of the user for which to get details; if missing, list users
- offset
Number of users to skip from start, used for paging
- query
Field:value
combinations with most of user fields to make more advanced searches. Possible fields areusername
,fullName blocked
,verified
,role
,locale
,timeZone
,userAddress
andcreatedAt
- order
The direction of the sorting,
asc
ordesc
, default isasc
- sort
The field used for sorting the result, could be
username
,fullname
orinsertedAt
.
Export Contexts
- user
The detail of user in a map, or a list of users
- users
The detail of user in a map, or a list of users
- opsgenie_offset
The offset that can be used for continue fetching the rest of the users, for paging
See below for example
---
workflows:
steps:
- call_function: opsgenie.users
with:
query: username:foobar
This function gets the current on-call persons for the given schedule.
Input Contexts
- scheduleId
The name or ID or the schedule of interest, required
- scheduleIdType
The type of the identifier,
name
orid
.- flat
If true, will only return the usernames, otherwise, will return all including notification, team etc.
Export Contexts
- result
the data portion of the json payload.
See below for example
---
workflows:
steps:
- call_function: opsgenie.whoisoncall
with:
scheduleId: sre_schedule
This system enables Honeydipper to integrate with slack, so Honeydipper can send messages to and react to commands from slack channels. This system uses Custom
Integrations
to integrate with slack. It is recommended to use slack_bot
system, which uses a slack app to integrate with slack.
Configurations
- url
The slack incoming webhook integration url
- slash_token
The token for authenticating slash command requests
- slash_path
The path portion of the webhook url for receiving slash command requests, by default
/slack/slashcommand
For example
---
systems:
slack:
data:
url: ENC[gcloud-kms,...masked...]
slash_token: ENC[gcloud-kms,...masked...]
slash_path: "/webhook/slash"
To configure the integration in slack,
- select from menu
Administration
=>Manage Apps
- select
Custom Integrations
- add a
Incoming Webhooks
, and copy the webhook url and use it asurl
in system data - create a random token to be used in slash command integration, and record it as
slash_token
in system data - add a
Slash Commands
, and use the url like below to send commands
https://myhoneydipper.com/webhook/slash?token=...masked...
This is triggered when an user issue a slash command in a slack channel. It is recommended to use the helper workflows and the predefined rules instead of using this trigger directly.
Matching Parameters
- .form.text
The text of the command without the prefix
- .form.channel_name
This field is to match only the command issued in a certain channel, this is only available for public channels
- .form.channel_id
This field is to match only the command issued in a certain channel
- .form.user_name
This field is to match only the command issued by a certain user
Export Contexts
- response_url
Used by the
reply
function to send reply messages- text
The text of the command without the slash word prefix
- channel_name
The name of the channel without # prefix, this is only available for public channels
- channel_fullname
The name of the channel with # prefix, this is only available for public channels
- channel_id
The IDof the channel
- user_name
The name of the user who issued the command
- command
The first word in the text, used as command keyword
- parameters
The remaining string with the first word removed
See below snippet for example
---
rules:
- when:
source:
system: slack
trigger: slashcommand
if_match:
form:
channel_name:
- public_channel1
- channel2
steps:
- call_function: slack.reply
with:
chat_colors:
this: good
message_type: this
message: command received `{{ .ctx.command }}`
- call_workflow: do_something
This function send a reply message to a slash command request. It is recommended to use notify
workflow instead so we can manage the colors, message types and receipient lists through contexts easily.
Input Contexts
- chat_colors
a map from message_types to color codes
- message_type
a string that represents the type of the message, used for selecting colors
- message
the message to be sent
- blocks
construct the message using the slack
layout blocks
, see slack document for detail
See below for example
---
rules:
- when:
source:
system: slack
trigger: slashcommand
do:
call_function: slack.reply
with:
chat_colors:
critical: danger
normal: ""
error: warning
good: good
special: "#e432ad2e"
message_type: normal
message: I received your request.
This function send a message to a slack channel slack incoming webhook. It is recommended to use notify
workflow instead so we can manage the colors, message types and receipient lists through contexts easily.
Input Contexts
- chat_colors
A map from message_types to color codes
- message_type
A string that represents the type of the message, used for selecting colors
- message
The message to be sent
- channel_id
The id of the channel the message is sent to. Use channel name here only when sending to a public channel or to the home channel of the webhook.
- blocks
construct the message using the slack
layout blocks
, see slack document for detail
See below for example
---
rules:
- when:
source:
system: something
trigger: happened
do:
call_function: slack.say
with:
chat_colors:
critical: danger
normal: ""
error: warning
good: good
special: "#e432ad2e"
message_type: error
message: Something happened
channel_id: '#public_announce'
This system enables Honeydipper to integrate with slack, so Honeydipper can send messages to and react to commands from slack channels. This system uses slack app to integrate with slack. It is recommended to use this instead of slack
system, which uses a Custom Integrations
to integrate with slack.
Configurations
- token
The bot user token used for making API calls
- slash_token
The token for authenticating slash command requests
- interact_token
The token for authenticating slack interactive messages
- slash_path
The path portion of the webhook url for receiving slash command requests, by default
/slack/slashcommand
- interact_path
The path portion of the webhook url for receiving interactive component requests, by default
/slack/interact
For example
---
systems:
slack_bot:
data:
token: ENC[gcloud-kms,...masked...]
slash_token: ENC[gcloud-kms,...masked...]
interact_token: ENC[gcloud-kms,...masked...]
slash_path: "/webhook/slash"
interact_path: "/webhook/slash_interact"
To configure the integration in slack,
- select from menu
Administration
=>Manage Apps
- select
Build
from top menu, create an app or select an exist app fromYour Apps
- add feature
Bot User
, and copy theBot User OAuth Access Token
and record it astoken
in system data - create a random token to be used in slash command integration, and record it as
slash_token
in system data - add feature
Slash Commands
, and use the url like below to send commands
https://myhoneydipper.com/webhook/slash?token=...masked...
- create another random token to be used in interactive components integration, and record it as
interact_token
in system data - add feature
interactive components
and use url like below
https://myhoneydipper.com/webhook/slash_interact?token=...masked...
This is triggered when an user responds to an interactive component in a message. This enables honeydipper to interactively reacts to user choices through slack messages. A builtin rule is defined to respond to this trigger, so in normal cases, it is not necessary to use this trigger directly.
Export Contexts
- slack_payload
The payload of the interactive response
This is triggered when an user issue a slash command in a slack channel. It is recommended to use the helper workflows and the predefined rules instead of using this trigger directly.
Matching Parameters
- .form.text
The text of the command without the prefix
- .form.channel_name
This field is to match only the command issued in a certain channel, this is only available for public channels
- .form.channel_id
This field is to match only the command issued in a certain channel
- .form.user_name
This field is to match only the command issued by a certain user
Export Contexts
- response_url
Used by the
reply
function to send reply messages- text
The text of the command without the slash word prefix
- channel_name
The name of the channel without # prefix, this is only available for public channels
- channel_fullname
The name of the channel with # prefix, this is only available for public channels
- channel_id
The IDof the channel
- user_name
The name of the user who issued the command
- command
The first word in the text, used as command keyword
- parameters
The remaining string with the first word removed
See below snippet for example
---
rules:
- when:
source:
system: slack
trigger: slashcommand
if_match:
form:
channel_name:
- public_channel1
- channel2
steps:
- call_function: slack.reply
with:
chat_colors:
this: good
message_type: this
message: command received `{{ .ctx.command }}`
- call_workflow: do_something
This function send a reply message to a slash command request. It is recommended to use notify
workflow instead so we can manage the colors, message types and receipient lists through contexts easily.
Input Contexts
- chat_colors
a map from message_types to color codes
- message_type
a string that represents the type of the message, used for selecting colors
- message
the message to be sent
- blocks
construct the message using the slack
layout blocks
, see slack document for detail
See below for example
---
rules:
- when:
source:
system: slack
trigger: slashcommand
do:
call_function: slack.reply
with:
chat_colors:
critical: danger
normal: ""
error: warning
good: good
special: "#e432ad2e"
message_type: normal
message: I received your request.
This function send a message to a slack channel slack incoming webhook. It is recommended to use notify
workflow instead so we can manage the colors, message types and receipient lists through contexts easily.
Input Contexts
- chat_colors
A map from message_types to color codes
- message_type
A string that represents the type of the message, used for selecting colors
- message
The message to be sent
- channel_id
The id of the channel the message is sent to. Use channel name here only when sending to a public channel or to the home channel of the webhook.
- blocks
construct the message using the slack
layout blocks
, see slack document for detail
See below for example
---
rules:
- when:
source:
system: something
trigger: happened
do:
call_function: slack.say
with:
chat_colors:
critical: danger
normal: ""
error: warning
good: good
special: "#e432ad2e"
message_type: error
message: Something happened
channel_id: '#public_announce'
This function queries all users for the team
Input Contexts
- cursor
Used for pagination, continue fetching from the cursor
Export Contexts
- slack_next_cursor
Used for pagination, used by next call to continue fetch
- members
A list of data structures containing member information
---
workflows:
get_all_slack_users:
call_function: slack_bot.users
translate channel_names to channel_ids
Input Contexts
- channel_names
a list of channel names to be translated
- channel_maps
a map from channel names to ids
Export Contexts
- channel_ids
a list of channel ids corresponding to the input names
By pre-populating a map, we don't have to make API calls to slack everytime we need to convert a channel name to a ID.
This is used by slashcommand
workflow and notify
workflow to automatically translate the names.
---
workflows:
attention:
with:
channel_map:
'#private_channel1': UGKLASE
'#private_channel2': UYTFYJ2
'#private_channel3': UYUJH56
'#private_channel4': UE344HJ
'@private_user': U78JS2F
steps:
- call_workflow: channel_translate
with:
channel_names:
- '#private_channel1'
- '#private_channel3'
- '@private_user'
- '#public_channel1'
- call_workflow: loop_send_slack_message
# with:
# channel_ids:
# - UGKLASE
# - UYUJH56
# - U78JS2F
# - '#public_channel1' # remain unchanged if missing from the map
send chat message through chat system
Input Contexts
- chat_system
A system name that supports
reply
andsay
function, can be eitherslack
orslack_bot
, by defaultslack_bot
.- notify
A list of channels to which the message is beng sent, a special name
reply
means replying to the slashcommand user.- notify_on_error
A list of additional channels to which the message is beng sent if the message_type is error or failure.
- message_type
The type of the message used for coloring, could be
success
,failure
,error
,normal
,warning
, orannouncement
- chat_colors
A map from message_type to color codes. This should usually be defined in default context so it can be shared.
This workflow wraps around say
and reply
method, and allows multiple recipients.
For example
---
workflows:
attention:
call_workflow: notify
with:
notify:
- "#honeydipper-notify"
- "#myteam"
notify_on_error:
- "#oncall"
message_type: $labels.status
message: "work status is {{ .labels.status }}"
This workflow wraps around the opsgenie.users
function and handles paging to get all users from Opsgenie.
reload honeydipper config
Input Contexts
- force
If force is truy, Honeydipper will simply quit, expecting to be re-started by deployment manager.
For example
---
rules:
- when:
source:
system: slack_bot
trigger: slashcommand
do:
if_match:
command: reload
call_workflow: reload
with:
force: $?ctx.parameters
resume a suspended workflow
Input Contexts
- resume_token
Every suspended workflow has a
resume_token
, use this to match the workflow to be resumed- labels_status
Continue the workflow with a dipper message that with the specified status
- labels_reason
Continue the workflow with a dipper message that with the specified reason
- resume_payload
Continue the workflow with a dipper message that with the given payload
For example
---
rules:
- when:
source:
system: slack_bot
trigger: interact
do:
call_workflow: resume_workflow
with:
resume_token: $ctx.slack_payload.callback_id
labels_status: success
resume_payload: $ctx.slack_payload
run kubernetes job
Input Contexts
- system
The k8s system to use to create and run the job
- steps
The steps that the job is made up with. Each step is an
initContainer
or acontainer
. The steps are executed one by one as ordered in the list. A failure in a step will cause the whole job to fail. Each step is defined with fields includingtype
,command
, orshell
. Thetype
tells k8s what image to use, thecommand
is the command to be executed with language supported by that image. If a shell script needs to be executed, useshell
instead ofcommand
.
Also supported are env
and volumes
for defining the environment variables and volumes specific to this step.
- env
A list of environment variables for all the steps.
- volumes
A list of volumes to be attached for all the steps. By default, there will be a
EmptyDir
volume attached at/honeydipper
. Each item should have a name and volume and optionally a subPath, and they will be used for creating the volume definition and volume mount definition.- workingDir
The working directory in which the command or script to be exected. By default,
/honeydipper
. Note that, the defaultworkingDir
defined in the image is not used here.- script_types
A map of predefined script types. The
type
field insteps
will be used to select the image here.image
field is required.command_entry
is used for defining the entrypoint when usingcommand
field in step, andcommand_prefix
are a list or a string that inserted at the top of container args. Correspondingly, theshell_entry
andshell_prefix
are used for defining the entrypoint and argument prefix for running a shell script.
Also supported is an optional securtyContext
field for defining the image security context.
- predefined_steps
A map of predefined steps. Use the name of the predefined step in
steps
list to easily define a step without specifying the fields. This makes it easier to repeat or share the steps that can be used in multiple places. We can also override part of the predefined steps when defining the steps with use and overriding fields.- predefined_env
A map of predefined environment variables.
- predefined_volumes
A map of predefined volumes.
- nodeSelector
See k8s pod specification for detail
- affinity
See k8s pod specification for detail
- tolerations
See k8s pod specification for detail
- timeout
Used for setting the
activeDeadlineSeconds
for the k8s pod- cleanupAfter
Used for setting the
TTLSecondsAfterFinished
for the k8s job, requires 1.13+ and the feature to be enabled for the cluster.
Export Contexts
- log
The logs of the job organized in map by container and by pod
- output
The concatinated log outputs as a string
- job_status
A string indicating if the job is
success
orfailure
See below for a simple example
---
workflows:
ci:
call_workflow: run_kubernetes
with:
system: myrepo.k8s_cluster
steps:
- git_clone # predefined step
- type: node
workingDir: /honeydipper/repo
shell: npm install && npm build && npm test
Another example with overrriden predefined step
---
workflows:
make_change:
call_workflow: run_kubernetes
with:
system: myrepo.k8s
steps:
- git_clone # predefined step
- type: bash
shell: sed 's/foo/bar/g' repo/package.json
- use: git_clone # use predefined step with overriding
name: git_commit
workingDir: /honeydipper/repo
shell: git commit -m 'change' -a && git push
sending heartbeat to alert system
Input Contexts
- alert_system
The alert system used for monitoring, by default
opsgenie
- heartbeat
The name of the heartbeat
This workflow is just a wraper around the opsgenie.heartbeat
function.
This workflow wraps around the slack_bot.users
function and make multiple calls to stitch pages together.
This workflow is used internally to respond to slashcommand webhook events. You don't need to use this workflow directly in most cases. Instead, customize the workflow using _slashcommands
context.
Input Contexts
- slashcommands
A map of commands to their definitions. Each definition should have a brief
usage
,workflow
contexts
, andallowed_channels
fields. By default, two commands are already defined,help
, andreload
. You can extend the list or override the commands by defining this variable in_slashcommands
context.- slash_notify
A recipient list that will receive notifications and status of the commands executed through slashcommand.
Export Contexts
- command
This variable will be passed the actual workflow invoked by the slashcommand. The command is the first word after the prefix of the slashcommand. It is used for matching the definition in
$ctx.slashcommands
.- parameters
This variable will be passed the actual workflow invoked by the slashcommand. The parameters is a string that contains the rest of the content in the slashcommand after the first word.
You can try to convert the $ctx.parameters
to the variables the workflow required by the workflow being invoked through the _slashcommands
context.
---
contexts:
_slashcommands:
######## definition of the commands ###########
slashcommand:
slashcommands:
greeting:
usage: just greet the requestor
workflow: greet
######## setting the context variable for the invoked workflow ###########
greet:
recipient: $ctx.user_name # exported by slashcommand event trigger
type: $ctx.parameters # passed from slashcommand workflow
This workflow sends a announcement message to the channels listed in slash_notify
. Used internally.
This workflow sends a list of supported commands to the requestor. Used internally.
This workflow sends a status message to the channels listed in slash_notify
. Used internally.
snooze an alert
Input Contexts
- alert_system
The alert system used for monitoring, by default
opsgenie
- alert_Id
The Id of the alert, usually exported from the alert event
- duration
How long to snooze the alert for, using golang time format, by default
20m
This workflow is just a wraper around the opsgenie.snooze
function. It also sends a notification through chat to inform if the snoozing is success or not.
For example
---
rules:
- when:
source:
system: opsgenie
trigger: alert
do:
steps:
- call_workflow: snooze_alert
- call_workflow: do_something
This workflow creates a k8s job with given job spec. It is not recommended to use this workflow directly. Instead, use run_kubernetes
to leverage all the predefined context variables.
This workflow is a helper to add a step into steps
context variable to ensure the in-cluster kubeconfig is used. Basically, it will delete the kubeconfig files if any presents. It is useful when switching from other clusters to local cluster in the same k8s job.
---
workflows:
copy_deployment_to_local:
steps:
- call_workflow: use_google_credentials
- call_workflow: use_gcloud_kubeconfig
with:
cluster:
project: foo
cluster: bar
zone: us-central1-a
- export:
steps+:
- type: gcloud
shell: kubectl get -o yaml deployment {{ .ctx.deployment }} > kuberentes.yaml
- call_workflow: use_local_kubeconfig # switching back to local cluster
- call_workflow: run_kubernetes
with:
steps+:
- type: gcloud
shell: kubectl apply -f kubernetes.yaml
This workflow sends announcement messages to the slack channels. It can be used in the hooks to automatically announce the start of the workflow executions.
---
workflows:
do_something:
with:
hooks:
on_first_action:
- workflow_announcement
steps:
- ...
- ...
This workflow sends workflow status messages to the slack channels. It can be used in the hooks to automatically announce the exit status of the workflow executions.
---
workflows:
do_something:
with:
hooks:
on_exit:
- workflow_status
steps:
- ...
- ...