Giter VIP home page Giter VIP logo

gopherbot's Introduction

Gopherbot DevOps Chatbot

Slack1 DevOps / ChatOps general purpose IT robot framework for Linux, supporting extensions in Bash, Python, Ruby, and Go2.

Slogans under consideration:

  • The Co-worker that Never Sleeps
  • The DevOps Swiss-Army Chainsaw

What does Gopherbot do?

Gopherbot runs as a process or container in your infrastructure and connects to your team chat. From there it can respond to CLI-like commands written in Bash, Ruby or Python, and perform any number of functions to provision resources, run reports and scheduled jobs, deploy software or interact with CI/CD - just about any functionality a DevOps engineer might want to provide in team chat. You can find a lot more information in the introduction of the online manual.

Major Features

  • Self-deploying and updating with GitOps-style management
  • Threaded conversation support and thread-awareness
  • Powerful pipeline-oriented engine for creating and combining reusable components in multiple scripting languages
  • Flexible support for encrypted secrets
  • Wide variety of security features including built-in Google Authenticator TOTP
  • Full-featured IDE and terminal connector for developing extensions
  • Highly configurable with Go-templated YAML

Software Overview

Gopherbot uses a model similar to Ansible, distributing a core robot with an array of built-in reusable components. Individual robots are configured and stored in a git repository that is cloned when you bootstrap your robot in your infrastructure; several example robot repositories are given below.

Running a Gopherbot robot essentially means running the core robot (on a VM or in a container) with a handful of environment variables that tell the core robot how to clone and run your individual robot.

Documentation

The latest documentation can always be found at the GitHub-hosted online manual; the documentation source is in a separate repository. Documentation automatically generated from the Go sources can be found at pkg.go.dev.

The manual is still very incomplete; however, sometimes the best documentation is example code. To that end, the most powerful and complete robot I have is Mr. Data (now retired) - the robot that ran my home Kubernetes cluster when I still had time for such things. Clu is the development robot used for development and writing documentation. Though Clu doesn't do any useful work, he has examples of most facets of Gopherbot functionality. Floyd (a utility robot I share with my wife) is the oldest and longest-running robot instance - occasionally he does useful work, but mostly he just makes dinner meal suggestions.

Release Status

Version 2 has been stable for me for over a year, and has finally been released. I've accepted that a fully up-to-date manual will lag significantly, but that is currently where the most work is being done.

With the recent (2021) addition of ParameterSets, a container-based IDE and threaded conversation support (2022), there are no major updates in functionality currently planned.

Previewing

If you have Docker available, you can kick the tires on the default robot running the terminal connector:

$ docker run -it --rm ghcr.io/lnxjedi/gopherbot
...
Terminal connector running; Type '|c?' to list channels, '|u?' to list users
...
general: *******
general: Welcome to the *Gopherbot* terminal connector. Since no configuration was
detected, you're connected to 'floyd', the default robot.
general: If you've started the robot by mistake, just hit ctrl-D to exit and try
'gopherbot --help'; otherwise feel free to play around with the default robot - you
can start by typing 'help'. If you'd like to start configuring a new robot, type:
';setup slack'.
c:general/u:alice -> help
...

For a more thorough preview of Gopherbot in the IDE, see the preview section in the online manual.

Downloading

You can download the latest release build from the release page. Up-to-date container builds can be found in the GitHub Container Registry.

Gopherbot Container Variants

Gopherbot CI/CD pipelines create two container variants:

  • gopherbot - ghcr.io/lnxjedi/gopherbot
    • gopherbot is a fairly minimal gopherbot container for running a production containerized robot
  • gopherbot-dev - ghcr.io/lnxjedi/gopherbot-dev
    • gopherbot-dev uses OpenVSCode Server for the entrypoint, and is intended for use in setting up and developing extensions for your robots3

Building from Source

Building from source is as straight-forward as make dist with the Makefile, as long as the build system has all the requirements.

Requirements:

  • A recent (1.18+) version of Go
  • Standard build utilities; make, tar, gzip

Steps:

  1. Clone this repository
  2. Optionally check out a release version - git checkout v2.6.2.1
  3. make dist in the repository root to create an installable archive, or just make to build the binaries
  4. Follow the manual installation instructions for installing an archive on your system

This example transcript is a little outdated, and doesn't showcase the new job functionality introduced in version 2 - but Gopherbot still knows how to tell jokes.

Deprecated and Unsupported Platforms

The Windows and Darwin (MacOS) ports have both been removed. The best solution for these platforms is to take advantage of the excellent Linux container support to run your robot in a container, perhaps with Docker Desktop. WSL is also a good solution for Windows.

Sample Command Plugin with the Ruby API

#!/usr/bin/ruby
require 'net/http'
require 'json'

require 'gopherbot_v1'
bot = Robot.new()

defaultConfig = <<'DEFCONFIG'
Help:
- Keywords: [ "weather" ]
  Helptext: [ "(bot), weather in <city(,country) or zip code> - fetch the weather from OpenWeatherMap" ]
CommandMatchers:
- Command: weather
  Regex: '(?i:weather (?:in|for) (.+))'
DEFCONFIG

# NOTE: the required environment variables need to be supplied as
# `Parameters` for the `weather` plugin in custom/conf/robot.yaml.
# The API key should be encrypted.

command = ARGV.shift()

case command
when "configure"
    puts defaultConfig
    exit
when "weather"
    location = ARGV.shift()
    location += ",#{ENV["DEFAULT_COUNTRY"]}" unless location.include?(',')
    uri = URI("http://api.openweathermap.org/data/2.5/weather?q=#{location}&units=#{ENV["TEMP_UNITS"]}&APPID=#{ENV["OWM_APIKEY"]}")
    d = JSON::parse(Net::HTTP.get(uri))
    if d["message"]
        bot.Say("Sorry: \"#{d["message"]}\", maybe try the zip code?")
    else
        w = d["weather"][0]
        t = d["main"]
        bot.Say("The weather in #{d["name"]} is currently \"#{w["description"]}\" and #{t["temp"]} degrees, with a forecast low of #{t["temp_min"]} and high of #{t["temp_max"]}")
    end
end

Contributing

PR's welcome. For development, testing, and collaboration, feel free to shoot me an email for an invite to the LinuxJedi Slack team.

Footnotes

  1. Gopherbot a modular interface for writing other protocol connectors in Go; currently only Slack and the Terminal connector are supported

  2. Go extensions are the hardest to write, requiring custom forks/builds; Gopherbot is heavily optimized for extension with scripting

  3. Note that the development container always contains the most recent code in /opt/gopherbot - you may want to e.g. cd /opt/gopherbot; git checkout v2.6.2.1; make

gopherbot's People

Contributors

arcsbot avatar parsley42 avatar pasali avatar redhat-developers-launcher avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

gopherbot's Issues

Make GOPHER_CALLER_ID cryptographically random

The only thing that prevents one external task from impersonating another, possibly accessing private / privileged memories, is the difficulty of guessing the GOPHER_CALLER_ID of another external task that may still be running. Should be simple enough to make this large enough and random enough for it to be sufficiently improbable.

Encryption CLI commands

As encryption becomes more heavily used, the current chat-only "encrypt" and template-only "decrypt" are proving inadequate. Need something like:

gopherbot encrypt "somestring"
gopherbot encrypt (-b) -f path/to/file # -b encode with base64
gopherbot decrypt "string"
etc.

Encrypt and decrypt file should print to stdout, which can be redirected.

Replace arrays instead of concatenate

At issue is that e.g. the parameters for weather.rb can't be overridden / replaced, since parameters are an array. Also, items in a configured array can't be removed; for instance, a user may wish to remove a command matcher to avoid interfering with a locally defined command, or update the help for a plugin.

Evaluate "PromptUsersForReply"

A potentially useful variant of Prompt*Reply, allowing any user listed in Task.Users to reply; mainly for pipelines, to allow overriding defaults for a pipeline - e.g. "Tests passed, deploy? (y/n)" or "Skip deploying? (y/n)"

Build refs in CI/CD status

The simplest way to email the log you want is for the build job to remember build refs from the short commit hash, and say them in the output, so for instance:

; mail joblog #c564ab

Repository jobs with localbuild

Make a 3-argument version of localbuild for repo, branch, pipeline; let localbuild do the work of initializing ssh and cloning a repository, then run a custom pipeline script for the job.

Update new_robot / setup

  • Add support for Rocket.Chat
  • Script should run the robot, then run it again, allowing the robot to write out the administrator
  • Remove builtin_admin config once admin added

TLS Webhook support

Gopherbot needs a TLS, authenticated restful API to support triggering jobs with webhooks, pinging another instance in an HA pair, and other stuff. The design still needs to be worked out, but generally:

  • The central bot library should use configuration in gopherbot.yaml to set up the URL and TLS
  • Loadable Go modules should be able to register individual handlers with unique, configurable tokens
  • The library authenticates the request by checking for ?token=XYZZY, then passes the token and request to the registered handler for the provided token
  • The TLS key file should be a #GOPHERBOT-ENCRYPTED-BASE64 file in custom
  • Non-TLS endpoints should be allowed when e.g. the webhook may sit behind an SSL proxy

Adding attachments to messages

It would be very useful to add attachment. In my case, bot generates a config file for the user and i want to reply with file as a attachment.

Path handling

Unprivileged plugin/job scripts, running as e.g. nobody, should be able to run without having full path access to the running script in $GOPHER_CONFIGDIR.

Add new Homed boolean to tasks, interpreted as follows:

  • When a new pipeline starts, if the initial job/plugin is Homed, the basePath should be ".", and environment vars should be set:

    • GOPHER_WORKSPACE should be set to the location of the workspace, likely a path relative to cwd
    • GOPHER_CONFIGDIR should be set to the configuration directory
  • When a task has Homed = true, that task should always start in $(pwd), with GOPHER_WORKSPACE and GOPHER_CONFIGDIR set, and also GOPHER_WORKDIR set to c.workingDirectory

  • Update cleanup task to run Homed, and to clean up GOPHER_WORKDIR; be sure to check and fail on absolute paths

  • Update robot/* interface to add SetWorkingDirectory

  • Update pipeline to set basePath to "." when Homed = true, or c.cfg,workSpace otherwise

  • Check ExtendNamespace for correct operation

  • Check calltask for correct operation

  • Check SetWorkingDirectory for correct operation

  • Check task environment to eliminate absolute paths when Homed = false

  • Re-futz Start() to deal with relative paths; bootstrapping should work with relative config path, but not absolute - "clean" will need to clean configDir during bootstrap, which will fail for abs. paths

Update CI/CD functionality

  • When Quiet: true, job events including namespace should emit no messages
  • gopherci should log stuff, like "skipping foo, not listed" when nothing happens silently
  • gopherci or localbuild should emit a single job start message with URL link if available
  • gopherci should add fail task(s) to spit out messages on fail
  • gopherci should take an "event" argument; currently one of "tag" / "commit"; the branch argument is either the branch committed to or the tag
  • individual services such as github, gitea, etc. should have small "connector" jobs that match messages from the service and call gopherci <branch/tag>

-> Robot should only emit messages for e.g. user jobs that don't use the library and don't have quiet: true
-> gopherci should be responsible for messaging when a job fails

CLI builds for Mac, Windows

Updates to Makefile and pipeline to build and publish small static builds for Windows and Mac, disabling "run" mode but allowing e.g. memory and secret management with the CLI.

The only thing that would prevent a build on Windows ATM is privsep.go. This could be re-split in to privsep_unix and privsep_win with empty function definitions.

The Mac and Win builds should probably include the terminal connector and statically link all brains, but leave off e.g. duo and totp plugins.

Go jobs and tasks

  • RegisterTask, RegisterJob for static compiles (less likely, but might as well)
  • GetJobs, GetTasks for loadable modules (more likely)

CLI/brain enhancement

the SimpleBrain interface should include a list function available to the innards and the CLI, to list all the keys. The CLI should be enhanced with a "list" command for listing memories, and a "store" command for storing a file to a given memory. This would allow easy and flexible migrations between different brain types, or to/from encrypted brains.

Documentation Needs

Per @pasali, API docs are high prio; especially for Go plugins (tasks, jobs)

  • Update external script API docs
  • API docs for Go plugins, tasks, jobs
    • Compiled-in Go modules
    • Building loadable modules
  • Document deployment
    • Deploying a container
    • Running from the CLI
    • Manual systemd setup
    • Deploying with Ansible
  • Documentation for workflows and admin robot operations
  • Jobs, pipelines, scheduled jobs

sendlog task

Sending error logs is kinda painful; make a simple to use task for this (which really just adds a command).

Implement dynamic port

There's really no good reason to fix the local listening port at e.g. 8080, since it's passed to scripts in GOPHER_HTTP_POST anyway. Using a value of "0" should select one dynamically.

Pass slack.Msg to commands

There is a lot of information in slack.Msg like file, attachment, comment etc. so passing it in commands would be very nice. Just passing slack.Msg.Text won't be enough in every case.
For ex:

(Probably) Remove set task parameter in favor of encrypted secrets in repositories.yaml

Usability for "set task parameter" is pretty lousy. Storing it in per-repository Parameters is more transparent. Replace "set namespace parameter" with a new "NameSpaces" section in gopherbot.yaml with shared parameters for a given namespace. Task/job/plugin-specific parameters should override anything from the namespace. Remove "set task parameter", evaluate whether "get/get * secret" is needed.

  • The GetRepoData() call should have all Parameters blanked out.
  • When ExtendNamespace() is called, parameters for type:repo should be set in the pipeline, e.g. localbuild:github.com/lnxjedi/gopherbot

Go loadable module support

Support for loadable modules, especially connectors and user plugins.
Compile options need to support:

  • Module support with connectors / plugins either built in or loadable
  • Fully static builds w/ no support for modules

Standard build archive is a modular build including loadable modules for most connectors.

Bot can not read other bots messages

I have a one specific channel for jira slackbot. It posts jira events to its channel. On the other hand my own bot listens jira channels messages and does some action. That does not work currently with gopherbot. So i debugged the code and realize that on the below line:
https://github.com/uva-its/gopherbot/blob/master/connectors/slack/util.go#L160
msg.Msg.Text is empty when its a bot message. And userID is also empty. So if a message comes from another bot, gopherbot should extract text from msg.Attachments[0].Fallback. What do you think about this ?

.Include enhancement

.Include'd templates should be expanded before being returned, to allow for encrypted secrets - duh! Don't forget to update the doc for .Include.

Fix lists plugin

Needs more thinking and work, for instance:

  • list <something> is too general, needs to be show list <something> or show (the) <something> list

Name collision handling

When a plugin is given the same name as a task, the plugin should be disabled to highlight the error to the admin.

Issues with Duo elevator

  • The robot remembers duo answers in short-term memory, but doesn't say anything before activating Duo, so the user thinks the robot isn't responding
  • The plugin should have commands for permanently saving or changing settings in long-term memory

PANIC in show log

Aug 02 09:20:57 gir.skyline gopherbot[22951]: Stack trace:goroutine 162 [running]:
Aug 02 09:20:57 gir.skyline gopherbot[22951]: runtime/debug.Stack(0xc0005d1318, 0xac32a0, 0x1162400)
Aug 02 09:20:57 gir.skyline gopherbot[22951]: /usr/local/go/src/runtime/debug/stack.go:24 +0x9d
Aug 02 09:20:57 gir.skyline gopherbot[22951]: github.com/lnxjedi/gopherbot/bot.checkPanic(0xc0005d1f68, 0xc0004085b1, 0x8)
Aug 02 09:20:57 gir.skyline gopherbot[22951]: /var/lib/gopherbot/workspace/github.com/lnxjedi/gopherbot/master/bot/util.go:52 +0x6e
Aug 02 09:20:57 gir.skyline gopherbot[22951]: panic(0xac32a0, 0x1162400)
Aug 02 09:20:57 gir.skyline gopherbot[22951]: /usr/local/go/src/runtime/panic.go:522 +0x1b5
Aug 02 09:20:57 gir.skyline gopherbot[22951]: github.com/lnxjedi/gopherbot/bot.(*Robot).SendUserMessage(0xc0005d1538, 0xc00034a75c, 0x4, 0xc0001ecd80, 0x5f, 0xc0001ecd80)
Aug 02 09:20:57 gir.skyline gopherbot[22951]: /var/lib/gopherbot/workspace/github.com/lnxjedi/gopherbot/master/bot/robot_connector_methods.go:158 +0x4a
Aug 02 09:20:57 gir.skyline gopherbot[22951]: github.com/lnxjedi/gopherbot/bot.(*botContext).debugTask(0xc00036c2c0, 0xc0005c2160, 0xc0003f24c0, 0x38, 0xc0005d1500)
Aug 02 09:20:57 gir.skyline gopherbot[22951]: /var/lib/gopherbot/workspace/github.com/lnxjedi/gopherbot/master/bot/debug.go:115 +0x45a
Aug 02 09:20:57 gir.skyline gopherbot[22951]: github.com/lnxjedi/gopherbot/bot.(*botContext).pluginAvailable.func1(0xc0005d16d0, 0xc00036c2c0, 0xc0005c2160, 0xc0003f2400,
Aug 02 09:20:57 gir.skyline gopherbot[22951]: /var/lib/gopherbot/workspace/github.com/lnxjedi/gopherbot/master/bot/available.go:26 +0x66
Aug 02 09:20:57 gir.skyline gopherbot[22951]: github.com/lnxjedi/gopherbot/bot.(*botContext).pluginAvailable(0xc00036c2c0, 0xc0005c2160, 0x0, 0x1)
Aug 02 09:20:57 gir.skyline gopherbot[22951]: /var/lib/gopherbot/workspace/github.com/lnxjedi/gopherbot/master/bot/available.go:71 +0x54b
Aug 02 09:20:57 gir.skyline gopherbot[22951]: github.com/lnxjedi/gopherbot/bot.(*botContext).checkPluginMatchersAndRun(0xc00036c2c0, 0x1, 0x11744e0)
Aug 02 09:20:57 gir.skyline gopherbot[22951]: /var/lib/gopherbot/workspace/github.com/lnxjedi/gopherbot/master/bot/dispatch.go:43 +0xcc4
Aug 02 09:20:57 gir.skyline gopherbot[22951]: github.com/lnxjedi/gopherbot/bot.(*botContext).handleMessage(0xc00036c2c0)
Aug 02 09:20:57 gir.skyline gopherbot[22951]: /var/lib/gopherbot/workspace/github.com/lnxjedi/gopherbot/master/bot/dispatch.go:227 +0x1168
Aug 02 09:20:57 gir.skyline gopherbot[22951]: created by github.com/lnxjedi/gopherbot/bot.handler.IncomingMessage
Aug 02 09:20:57 gir.skyline gopherbot[22951]: /var/lib/gopherbot/workspace/github.com/lnxjedi/gopherbot/master/bot/handler.go:188 +0x96c```

Overhaul install / bootstrapping, github-based standard install

Goal: simplified portable installation for server and container based deployment, well documented. Standard install based on github & slack.

Initial Installation

You should only ever need to run the gopherbot binary, and the setup plugin, bootstrap & terminal connectors should do the rest. Installing an instance of gopherbot means creating the custom and optional private git repositories such that a particular robot can be run in any environment with just a small set of environment variables.

  • Setting up a robot in a local docker container should just mean running the container in the foreground initially, redirecting the log to a file: docker run gopherbot 2>setup.log
  • Setting up a robot on a Linux host should just mean running e.g. /opt/gopherbot/gopherbot 2>setup.log

Post Install Setup

Once the robot is running and linked to it's configuration repository, the administrator will need to configure users and administrators using the globally available whoami and identify <user> commands. This information can be used to populate the user roster and administrator configuration items, which can then be made active with reload <setupkey>.

Optional post-install setup would include github integration for automated git pull and reload when the custom repository updates.

Default and Custom Configuration

Most of the default configuration should be moved out in to robot.skel for populating the starting configuration for a freshly-created robot.

Super-powered setup plugin

  • When the robot is completely unconfigured:
    • the "setup" plugin goes in to action during "init"
    • Robot automatically starts with the "terminal" connector, and prompts for:
      • brain encryption key
      • custom configuration repository
      • optional private memories repository
    • ... these values will be written out to ./.env
  • When the robot starts with only a set of environment vars:
    • minimal env:
      • GOPHER_ENCRYPTION_KEY - min. 32 char key for decrypting binary brain key
      • GOPHER_CUSTOM_REPOSITORY - publicly available or password-accessible repo
      • GOPHER_PROTOCOL - connector protocol should default to terminal unless this is set; not strictly required, but default for new installs
      • NOTE: the binary brain key will need to be in custom repo, but it's only useful w/ the encryption key
    • optional additional env:
      • GOPHER_GIT_USER - username for access to GOPHER_CUSTOM_REPOSITORY
      • GOPHER_GIT_PASS - password for git access
      • GOPHER_PROTOCOL - connector protocol to use; normally for setting to "term" to interact with a specific robot on the command line, for e.g. encrypting passwords
    • If the custom repo is empty, the robot should start with the bootstrap (null) connector, and the setup plugin init should try to clone it
    • If the clone returns an empty repo, the robot should restart with the terminal connector running the setup plugin which will prompt for protocol (if not already set), protocol credentials, and a setup token needed to issue the reload <token> command.

New canonical directory structure

To support the simplified installation and bootstrapping, the following canonical directory structure will be adopted:

  • clu/ - top-level directory, not a repository root, optionally persistent in containerized installs
    • gopherbot -> /path/to/gopherbot - optional symlink to binary for cd path/to/clu; ./gopherbot
    • .env - optional environment file w/ brain unlock key (most secure)
    • custom/ - custom configuration directory, possibly with custom jobs/plugins and potentially with encrypted secrets (ala {{ decrypt "encryptedstring" }} a public (or possibly private) github repo in the standard install that the robot monitors and performs a pull/reload on change
      • ssh/ - robot's ssh config file and keys
      • binary-encrypted-key - internal binary brain encryption key, base64 encoded, used for all brains
    • private/ - location for files that should rarely or never be shared
      • environment - backup location for loadable environment; useful for dev robots
      • brain/ - directory for file-based brain; a private github repo in the standard install that the robot can automatically back up to with it's ssh key
      • NOTE: the default .gitignore should exclude noisy memories like history logs
    • history/ - location for file-based history logs, considered disposable but might want to back up (not to git, it would be too noisy); if backing up history is desired, the associated memories will also need to be backed up
    • workspace/ - location where local builds are done, definitely disposable

Update privilege separation

Plugins should run with dropped privileges by default, jobs should run privileged. AddJob should fail if the plugin isn't running privileged.

The robot should be executed by the appropriate privileged user with access to e.g. read and update configuration, and setuid to an unprivileged user, e.g. daemon. The privsep init func should setresuid to priv,priv,unpriv, then droppriv should setresuid to unpriv,unpriv,unpriv. The privcheck function should be renamed to raisepriv, and called for job pipelines and privileged plugins.

Re-purpose outdated "protected" flag as a "privileged" flag, to mark plugins as privileged, and this flag must be set in gopherbot.yaml, and ignored in the plugin external config file. Plugins that were formerly "protected" now need only set working directory to $GOPHER_CONFIGDIR (which should be in the environment).

ssh-scan improvement

The current means of scanning hosts doesn't work well with Debian-based systems where the hostname is hashed; explore alternative means using e.g. ssh -oStrictHostKeyChecking=no user@host exit, or

ssh <<EOF | ssh -oStrictHostKeyChecking=no user@host
EOF

Go API updates to avoid need for fmt.Sprintf

Many calls to Say, Reply, etc. end up importing fmt and using fmt.Sprintf; it's easy enough to convert methods from string to strting, ...interface{}, avoiding the need to import fmt for future go plugin loadble modules.

New "NameSpaces" section

The current v2 snapshot implementation of shared namespaces is not very transparent and hard to use. Implement a separate "NameSpaces" that just takes shared parameters; require NameSpace parameter for tasks, plugins and jobs to refer to one.

Audit currentCfg locking

There are still lots of places in the code where the global lock on currentCfg is taken, even though there's a valid cfg attached to the current context. Audit and remove all those extra locks in favor of using the non-changing value attached to the context.

The robot should see edited messages

This is an issue with the Slack connector. When users get a command syntax wrong, it's normal to try and edit the last message - but the robot isn't reading it.

How to mention a specific user

Is there any way to mention a user other than who calls bot ? For example hubot's encourage command, you can pass a bot something like this hubot encourage name then it responds with mentioning target user.

Simple active/standby HA support

For increased reliability and availability, Gopherbot should support simple HA pairs (not clusters).

A few design notes:

  • HA should rely on webhooks between instances on the same subnet, in case one or both instances are unable to reach the chat service - but are still running automated jobs; optionally the standby could check chat availability of the active instance, and complain but not take over if the active instance doesn't respond
  • gopherbot.yaml will need a new stanza for HA config, and the standby instance shouldn't start until it can actually reach the primary
  • A dotfile in $GOPHER_HOME should indicate to each instance whether it is 'active' or 'standby'
  • The active node should have a scheduled (late-night) job to initiate a "swap", with positive acknowledgement, where the instances swap active/passive roles on a regular basis, to insure that both robots are capable of running performing all tasks (they can write out new dot-files indicating active/standby)
  • The standby robot shouldn't run scheduled jobs, but should expect to hear from the active node when a scheduled job completes, and complain otherwise
  • gopherbot.yaml will need to have IP/port for contacting both instances, with a per-robot unique ID that each robot can locally determine (perhaps a unique dot-file in $GOPHER_HOME); logic to determine how to contact the other instance should be look at both endpoints and contact the one that's "not me"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.