gosync

package module
v0.14.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 21, 2023 License: Apache-2.0 Imports: 6 Imported by: 11

README

⚠️ Go Sync is under active development and subject to breaking changes.

Go Sync (all the things)

GitHub go.mod Go version GitHub release (latest SemVer) Go Report Card Go Reference Test Status GitHub issues GitHub pull requests License

Summary of Go-Sync

You have people*. You have places you want them to be. Go Sync makes it happen.

* Doesn't have to be people.

Installation

go get github.com/ovotech/go-sync@latest

# Then get the adapters you need.
go get github.com/ovotech/go-sync/adapters/slack@latest

You're ready to Go Sync! 🎉

Usage

Read the documentation on pkg.go.dev.

Go Sync consists of two fundamental parts:

  1. Sync
  2. Adapters

As long as your adapters are compatible, you can synchronise anything.

// Create an adapter using the recommended method.
client := service.New("some-token")
source := myAdapter.New(client, "some-value")

// Initialise an adapter using an Init function.
destination, err := myAdapter.Init(map[gosync.ConfigKey]string{
	myAdapter.Token:     "some-token",
	myAdapter.Something: "some-value",
})
if err != nil {
	log.Fatal(err)
}

sync := gosync.New(source)

err := sync.SyncWith(context.Background(), destination)
if err != nil {
	log.Fatal(err)
}
Init

While we recommend using New to create an adapter in most cases, some plugins may provide an Init function for instantiating them too. Init functions are intended for programmatically creating adapters either via environment variables or some other dynamic configuration.

Sync 🔄

Sync is the logic that powers the automation. It accepts a source adapter, and synchronises it with destination adapters.

Sync is only uni-directional by design. You know where your things are, and where you want them to be. It works by:

  1. Get a list of things in your source service.
    1. Cache it, so you're not calling your source service more than you have to.
  2. Get a list of things in your destination service.
  3. Add the things that are missing.
  4. Remove the things that shouldn't be there.
  5. Repeat from 2 for further adapters.

Adapters 🔌

Adapters provide a common interface to services. Adapters must implement our Adapter interface and functionally perform 3 things:

  1. Get the things.
  2. Add some things.
  3. Remove some things.

These things can be anything, but we recommend email addresses. There's no point trying to sync a Slack User ID with a GitHub user! 🙅

Can't find an adapter you're looking for? Why not write your own! ✨

Made with 💚 by OVO Energy's DevEx team

DevEx Platforms Tools Golden Paths Guard Rails For You

Documentation

Index

Examples

Constants

View Source
const (
	// AddOnly only runs add operations.
	AddOnly OperatingMode = "Add"
	// RemoveOnly only runs remove operations.
	RemoveOnly OperatingMode = "Remove"
	// RemoveAdd first removes things, then adds them.
	RemoveAdd OperatingMode = "RemoveAdd"
	// AddRemove first adds things, then removes them.
	AddRemove OperatingMode = "AddRemove"
	// NoChangeLimit tells Sync not to set a change limit.
	NoChangeLimit int = -1
)

Variables

View Source
var ErrCacheEmpty = errors.New("cache is empty, run Get first")

ErrCacheEmpty is returned if an adapter expects Get to be called before Add/Remove.

View Source
var ErrInvalidConfig = errors.New("invalid configuration")

ErrInvalidConfig is returned when an InitFn is passed an invalid configuration.

View Source
var ErrMissingConfig = errors.New("missing configuration")

ErrMissingConfig is returned when an InitFn is missing a required configuration.

View Source
var ErrNotImplemented = errors.New("not implemented")

ErrNotImplemented is for brand-new adapters that are still being worked on.

View Source
var ErrReadOnly = errors.New("cannot perform action, adapter is readonly")

ErrReadOnly is returned for adapters that cannot Add/Remove, but have been set as a destination.

View Source
var ErrTooManyChanges = errors.New("too many changes")

ErrTooManyChanges is returned when a change limit has been set, and the number of changes exceeds it.

Functions

This section is empty.

Types

type Adapter

type Adapter interface {
	Get(ctx context.Context) (things []string, err error) // Get things in a service.
	Add(ctx context.Context, things []string) error       // Add things to a service.
	Remove(ctx context.Context, things []string) error    // Remove things from a service.
}

Adapter interfaces are used to allow Sync to communicate with third party services.

type ConfigFn added in v0.14.0

type ConfigFn[T Adapter] func(T)

A ConfigFn is used to pass additional or custom functionality to an adapter.

type ConfigKey added in v0.7.0

type ConfigKey = string

ConfigKey is a configuration key to Init a new adapter.

type InitFn added in v0.7.0

type InitFn[T Adapter] func(context.Context, map[ConfigKey]string, ...ConfigFn[T]) (T, error)

InitFn is an optional adapter function that can initialise a new adapter using a static configuration. This is to make it easier to use an adapter in a CLI or other service that invokes adapters programmatically.

type OperatingMode added in v0.9.0

type OperatingMode string

OperatingMode specifies how Sync operates, which sync operations are run and in what order.

type Service

type Service interface {
	SyncWith(ctx context.Context, adapter Adapter) error // Sync the things in a source service with this service.
}

Service can be used for downstream services that implement Sync in your own workflow.

type Sync

type Sync struct {
	DryRun        bool          // DryRun mode calculates membership, but doesn't add or remove.
	OperatingMode OperatingMode // Change the order of Sync's operation. Default is RemoveAdd.
	CaseSensitive bool          // CaseSensitive sets if Go Sync is case-sensitive. Default is true.

	/*
		MaximumChanges sets the maximum number of allowed changes per add/remove operation. It is not a cumulative
		total, and the number only applies to each distinct operation.

		For example:

		Setting this value to 3 means that a maximum of 3 things can be added AND removed from a destination (total 6)
		changes before Sync returns an ErrTooManyChanges error.

		Default is NoChangeLimit (or -1).
	*/
	MaximumChanges int
	Logger         *log.Logger
	// contains filtered or unexported fields
}

func New

func New(source Adapter, optsFn ...func(*Sync)) *Sync

New creates a new Sync service.

Example
package main

import (
	"context"
	"log"
	"os"

	gosync "github.com/ovotech/go-sync"
	"github.com/ovotech/go-sync/adapters/github/team"
	"github.com/ovotech/go-sync/adapters/slack/conversation"
)

func main() {
	ctx := context.Background()

	// Specify a custom logger for the GitHub adapter.
	logger := log.New(os.Stderr, "new logger", log.LstdFlags)

	// Create a GitHub team adapter.
	source, err := team.Init(ctx, map[gosync.ConfigKey]string{
		team.GitHubToken: "some-token",
	}, team.WithLogger(logger))
	if err != nil {
		log.Panic(err)
	}

	// Create a Slack conversation adapter.
	destination, err := conversation.Init(ctx, map[gosync.ConfigKey]string{
		conversation.Name: "example",
	})
	if err != nil {
		log.Panic(err)
	}

	err = gosync.New(source).SyncWith(ctx, destination)
	if err != nil {
		log.Panic(err)
	}
}
Output:

func (*Sync) SyncWith

func (s *Sync) SyncWith(ctx context.Context, adapter Adapter) error

SyncWith synchronises the destination service with the source service, adding & removing things as necessary.

Directories

Path Synopsis
adapters
azuread Module
github Module
google Module
opsgenie Module
slack Module
packages
gosync Module
slack Module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL