- πOverview
- βοΈ Credential Configuration
- π Flow
- πΌοΈ Images
- π¬ Methods
- β° Reminders
- π¬ Deadline
- π§ͺ Testing
- ποΈ DB
- π Resources
- ππ¨ Getting Started
- πΊ Roadmap
- π€ Contributing
- π Acknowledgments
Cuebert is a slackbot to help encourage users to complete a task. Initially written to help encourage users to upgrade the OS on their machine(s) Cuebert has grown to be a general purpose reminderbot. Written in Go this program is intended to be lightweight, fast, and scalable.
While the scope has grown, Cuebert is still a simple bot - pass the required OS version, task name/ID, and deadline as arguments, and any other relevant flags, and the process will begin.
The goal of Cuebert is empowering the end user. Offering custom reminders and the ability to leverage exclusions, this program seeks to let the user decide when the right time to finish the task while giving them subtle reminders to do so.
This program was written using Slack's socket mode making testing quick and easy. There is no need for callback urls or public listener's, Cuebert will be "live" wherever you run it from.
There are three ways to store the required credentials for the program environmental variables, configuration file, and the system keychain.
If testing locally the program will default to -env-type=dev
which handles authentication through the system keychain using keyring. If running the program in production it is recommended to set the credentials as environmental variables.
To set the environmental variables take any of the json key values in the Config
struct, prepend them with CUEBERT
and export the value.
ex:
export CUEBERT_DB_ADDRESS=localhost
export CUEBERT_DB_USER=cue
While the other two methods are preferred, you may also store the values in a local json configuration file.
{
"db_address": "localhost",
"db_name": "cue",
...
}
By default when the program starts it does not begin the process of messaging users. This allows Cuebert to be started and configured before any routines begin. At this point Cuebert will respond to messages and commands but will not actively message users. This is defined by the init
flag.
To advance Cuebert from the initialization stage you can run
start cuebert
This will pull up a modal allowing you to adjust configuration options.
- This menu can be pulled up at anytime using
update cuebert
.
By default when the program starts the tables are deleted. Pulling the data and populating the tables takes roughly 2-3 seconds and ensures we start with a fresh data set. Should you wish to keep the data pass -clear-tables=false
.
After reading in the configuration needed to start the first action takin is to start a goroutine to respond to user input. This handles any messages sent to Cuebert, reminder modal input, acknowledgement of messages sent, or any information Cuebert would need to respond to.
Once the configuration has been read in and the tables have been populated the compliance_tracking
table is configured. This pulls data from the compliance_task
and compliance_users
table to gather the information on the user, and their manager, needed to begin.
Once the configuration has been read in and the tables have been populated the bot_results
table is configured. This pulls data from the devices
and users
table to gather the information on the user, and their manager, needed to begin.
At this point Cuebert begins maintenance tasks. Three routines are started and will repeat on a set time interval.
- Diff
- Every 60 minutes the
Diff
function runs to pull info from the DB, compare that to the MDM, or Compliance source, information, and update where necessary. This ensures we are not messaging users who have updated in between reminders and always operating off fresh data.
- Every 60 minutes the
- Check
- Every 30 minutes
Check
runs to see if messaging needs to be sent to the user. The information is pulled from either thebot_results
orcompliance_tracking
table which stores if a user has been sent the message and when/if they responded. If the conditions are met where the user should be notified that will occur.
- Every 30 minutes
- Poll
- Every 15 minutes
Poll
runs to see if anyone needs a custom OS upgrade reminder set. Since a user can set a reminder for any point, at any time, we need to regularly check this data. Should a reminder be set in within the next 15 minutes of check running a routine is started to remind the user at that time.
- Every 15 minutes
___________________________________________________________
There are three main messages Cuebert will send.
-
First Message
- This message is sent on Monday to the user informing them of the task and deadline. This message is sent to the user in a DM with Cuebert.
-
Final Message - This message is sent on Friday to the user informing them of the task and deadline. This message is sent to the user in a DM with Cuebert.
At anytime a user can request a reminder to finish the task at hand. A prompt appears to ask if the user would like to set a reminder.
If the user clicks yes a date/time modal appears to set the reminder.
Each method implements a Deadline interface. Since this is highly subjective to each organization it is hard to put anything sane there that anyone could use. Examples will be added as ideas but it is your responsibility to implement what works for you.
By passing cuebert the -testing
and -testing-users
flags you can simulate the actions that would take place during messaging.
The testing flag is a bool value. The testing users is a comma-separated lists of Slack ID's to act on as the program normally would while logging what would happen to others. This flag is very useful for beta testing against IT and other willing participants.
An example of a possible testing scenario:
./build/darwin/cuebert -deadline-date 2023-05-09 -cutoff-time 18:00:00 -log-level=trace -required-os 13.4.1 -auth-users=ABC123,DEB456 -testing=true -clear-tables=false -testing-users=ABC123
To test locally we first need to setup Postgres. This can be done by downloading the standalone Postgres package or by creating a Postgres Docker image.
The docker image is going to be quicker to get up and running but either option will work.
make run-docker-postgres
This will build the Dockerfile, configuring the database as we need it and starting Postgres.
To connect to the db you can:
- exec into the container
- use
psql
if you have the postgres binaries installed locally.
- Download the latest version.
- Move to Applications folder β Open.
- Click
Initialize
- You now have a PostgreSQL server running on your Mac with these default settings:
- Host: localhost
- Port: 5432
- User: your system user name
- Database: same as user
- Password: none
- Configure your $PATH to use the included command line tools (optional):
sudo mkdir -p /etc/paths.d && echo /Applications/Postgres.app/Contents/Versions/latest/bin | sudo tee /etc/paths.d/postgresapp
- Run the init script to configure the DB as needed.
Once the database has been configured run cuebert to interact as needed.
- Unless you have changed some of the default values the connection information should:
- Host: localhost
- Port: 5432
- User: cue
- Database: cue
- Password: cue
Now you can authenticate and start using the tools.
The database stores information on the users, devices, bot results, and exclusions. Each table has its own tooling defined under db that help facilitate interactions with the table. By design the functionality and code is very similar between each of these packages - they are meant to be fully independent of one another while feeling similar when moving between them.
The four table definitions can be found here
- bot results
- This table is the one Cuebert will be writing state information to about interactions with the user such as when a user acknowledges or receives a message, the time it occurred, etc.
- devices
- Information about the device. All information is pulled from the MDM to store the device serial, os, platform, and user.
- users
- Used to correlate information between the MDM device users and their Slack ID.
- exclusions
- Devices to be excluded from receiving messaging.
To help automate the creation of the tables, especially when testing, there is a script that can be used.
This does make some assumptions on the default user of the db (postgres) but that can be overridden with flags.
Create the cue user, db, tables, and triggers.
bash resources/db/create.sh -a true
Create the cue user
bash resources/db/create.sh -u true
Create the DB
bash resources/db/create.sh -d true
Create the tables
bash resources/db/create.sh -t true
Create the triggers
bash resources/db/create.sh -tr true
Under images you will find some sample assets you can use for both Cuebert
and Bertcue
Slack's App Manifests make it easy to get this up and running.
Under manifest there are two options to choose from:
Since this application uses socketmode testing with the same app, if already deployed into production, leads to a split-brain problem.
Messages will deliver to whichever app it feels like and will cause a world of pain and confusion.
To save yourself from this, simply deploy a second app instance and test away.
Usage of ./build/darwin/cuebert:
-auth-users string
Set which users can perform authorized functions. (comma separated)
-auth-users-from-idp
Set whether to pull authorized users from the IDP. (default true)
-check-interval int
the number of minutes between device messaging checks and db clean-ups. (default 15)
-clear-tables
Drop all info from tables on initialization. (default true)
-cutoff-time string
the hour when the install must be done by (HH:MM:SS).
-daily-report
send a daily report to the admin alert channel.
-deadline-date string
the date the install must be done by (YYYY:MM:DD).
-default-reminder-interval int
the number of minutes between reminders. (default 60)
-device-diff-interval int
the number of minutes between device diff checks. (default 30)
-env-type string
Set the env type. Options are [prod, dev]. (default "dev")
-help-docs-url string
the url to the cuebert docs. (default "https://help.megacorp.com/cuebert")
-help-repo-url string
the url to the cuebert repo. (default "https://github.com/johnmikee/cuebert")
-help-ticket-url string
the url to the cuebert ticketing system. (default "https://tickets.megacorp.com/cuebert")
-idp string
Set the IDP to use. Options are [okta]. (default "okta")
-init
Start the program, load the config, and wait for input before running. (default true)
-log-level string
Set the log level. (default "trace")
-log-to-file
Log results to file.
-mdm string
Set the MDM to use. Options are [jamf, kandji]. (default "kandji")
-method string
Set the method to use. Options are [manager, device]. (default "manager")
-poll-interval int
the number of minutes between device polling checks. (default 10)
-rebuild-tables-on-failure
rebuild tables on an abnormal exit.
-required-os string
the version to require for the fleet (default "13.4.1")
-send-manager-missing
send a message to the alert channel of missing managers
-service-name string
if using the dev env the service name to store keys under. (default "cuebert")
-table-names string
a list of tables to clear on initialization. (comma separated)
-testing
Log actions that would take place instead of performing them. (default true)
-testing-end-time string
the time to end testing (HH:MM). (default "17:00")
-testing-start-time string
the time to start testing (HH:MM). (default "11:00")
-testing-users string
a list of slack id's to perform the actions on during testing instead of every user. (comma separated)
______________________________________________________________________
Contributions are always welcome! Please follow these steps:
- Clone the repository.
- Create a new branch with a descriptive name (e.g.,
new-feature-branch
orcuebert-bugfix-123
).
git checkout -b new-feature-branch
- Make the changes, commit with a clear commit message that explains the changes you've made, and push to the new branch.
git commit -m 'fixed cuebert going sentient'
git push -u origin cuebert-selfaware-removal
- Create a pull request to the original repository and describe the changes you've made and why they're necessary.