Skip to content

johnmikee/cuebert

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

4 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation


cuebert

πŸ“š Table of Contents


Overview

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.


Credential Configuration

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",
    ...
}


Flow

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.
alt text

  • 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.

Compliance

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.

OS Update

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.

  • Check
    • Every 30 minutes Check runs to see if messaging needs to be sent to the user. The information is pulled from either the bot_results or compliance_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.

  • 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.

___________________________________________________________

Messaging

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.


Reminders

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.
alt text

If the user clicks yes a date/time modal appears to set the reminder.

alt text


Deadline

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.


Testing

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

Setup

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.


Docker Postgres

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

alt text

  • use psql if you have the postgres binaries installed locally.

alt text

Standalone Postgres

  • Download the latest version.
  • Move to Applications folder ➜ Open.
  • Click Initialize
    alt text
  • 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.
    alt text

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. alt text


DB

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.

Tables

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.

Creating tables

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


Resources

Images

Under images you will find some sample assets you can use for both Cuebert and Bertcue

Manifests

Slack's App Manifests make it easy to get this up and running.
Under manifest there are two options to choose from:

  • prod: this will create the app as Cuebert
  • testing: this will create the testing instance Bertcue

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.


Getting Started

Using cuebert

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)

______________________________________________________________________

Contributing

Contributions are always welcome! Please follow these steps:

  1. Clone the repository.
  2. Create a new branch with a descriptive name (e.g., new-feature-branch or cuebert-bugfix-123).
git checkout -b new-feature-branch
  1. 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
  1. Create a pull request to the original repository and describe the changes you've made and why they're necessary.

About

OS upgrade helper

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages