archive

package
v0.26.2 Latest Latest
Warning

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

Go to latest
Published: Nov 7, 2022 License: Apache-2.0 Imports: 24 Imported by: 1

README

Archive Watcher for Choria Autonomous Agents

This is an Autonomous Agent Watcher plugin capable of downloading tar.gz archives from an HTTP(S) repository, verify them continuously and repair them on unexpected changes.

It's primarily designed to work with the machines watcher also in this repository, neither are enabled by default in standard released Choria.

Goals

This is built in a way that would allow the initial Autonomous Agent to be compiled into the Choria binary, meaning no-one can modify its behaviour or requirements for checksum verification etc.

The compiled-in Autonomous Agent then reads configuration about URLs and checksums to download from a Key-Value store that sets the URL to fetch, the checksum of the downloaded archive AND the checksum of the SHA256SUMS file in the archive.

This way should someone on the server change any downloaded file or tries to edit the SHA256SUMS file would trigger a remediation via re-download.

The download concurrency can be controlled using a Choria Governor ensuring that on a large network the webservers are not overwhelmed.

Every event such as verification failing, new files downloaded etc publish CloudEvents into Choria Streams that can be viewed real time using choria tool event.

Today it's focussed on small single directory archives - like Choria Autonomous Agents - and the verification is restricted to a single directory.

Preparing an archive

This supports GZipped Tar files only, we have a typical Choria Autonomous Agent here:

metadata
├── machine.yaml
├── gather.sh
└── SHA256SUMS

The SHA256SUMS file was made using sha256sum * > SHA256SUMS.

We tar up this archive and again get another SHA256 for it:

$ cd metadata
$ sha256sum * > SHA256SUMS
$ cd -
$ tar -cvzf metadata-machine-1.0.0.tgz metadata
$ sha256sum metadata-machine-1.0.0.tgz metadata/SHA256SUMS
f11ea2005de97bf309bafac46e77c01925307a26675f44f388d4502d2b9d00bf  metadata-machine-1.0.0.tgz
1e85719c6959eb0f2c8f2166e30ae952ccaef2c286f31868ea1d311d3738a339  metadata/SHA256SUMS

Place this file on any webserver of your choice. Note these checksums for later.

Configuration

First we'll create a Key-Value store to configure this Autonomous Agent, since we're creating one that introspect the machine for some metadata we call it METADATA:

$ choria kv add METADATA --replicas 3

We then place our initial configuration in the bucket:

$ choria kv put METADATA machine \
'{
  "source": "https://my.example.net/metadata/metadata-machine-1.0.0.tgz",
  "checksum": "f11ea2005de97bf309bafac46e77c01925307a26675f44f388d4502d2b9d00bf",
  "verify_checksum": "1e85719c6959eb0f2c8f2166e30ae952ccaef2c286f31868ea1d311d3738a339"
}'

The source is where to get the file, checksum is the SHA256 sum of the metadata-machine-1.0.0.tgz and the verify_checksum is the SHA256 sum of the SHA256SUMS file that's inside metadata-machine-1.0.0.tgz

Now we arrange for this data to be placed on each node and subsequent changes to be monitored using the KV Watcher:

watchers:
  - name: data
    type: kv
    interval: 55s
    state_match: [MANAGE]
    properties:
      bucket: METADATA
      key: machine
      mode: poll
      bucket_prefix: false

Finally, we set up our metadata manager to fetch and maintain the metadata gathering Autonomous Agent:

watchers:
  - name: download
    state_match: [MANAGE]
    type: archive
    interval: 1m
    properties:
      source: '{{ lookup "data.machine.source" "" }}'
      checksum: '{{ lookup "data.machine.checksum" "" }}'
      verify_checksum: '{{ lookup "data.machine.verify_checksum" "" }}'
      username: artifacts
      password: toomanysecrets
      target: /etc/choria/machines
      creates: metadata
      verify: SHA256SUMS

This will:

  • Every minute
    • Checks that the /etc/choria/machines/metadata directory exist
    • Verify the checksum of /etc/choria/machines/metadata/SHA256SUMS
    • Verify the checksum of every file in /etc/choria/machines/metadata using the SHA256SUMS file
    • If verification failed, downloads the file:
      • Into a temporary directory
      • Verifies the checksum of the tar.gz
      • Extract it, verifies it makes metadata
      • Verify every file in it based on SHA256SUMS after first verifying SHA256SUMS is legit
      • Remove the existing files in /etc/choria/machines/metadata
      • Replace them with the new files

Compiling into Choria

This plugin requires custom-builds of Choria. Update the user-plugins.yaml:

# packager/user_plugins.yaml
archive_watcher: github.com/choria-io/go-choria/aagent/watchers/archivewatcher

And run go generate, the plugin will be compiled in.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ChoriaPlugin

func ChoriaPlugin() *plugin.WatcherPlugin

func New

func New(machine model.Machine, name string, states []string, failEvent string, successEvent string, interval string, ai time.Duration, rawprop map[string]any) (any, error)

Types

type Properties

type Properties struct {
	// ArchiveChecksum is a sha256 hex string of the archive being downloaded, requires ArchiveChecksumChecksum
	ArchiveChecksum string `mapstructure:"checksum"`
	// Creates is a subdirectory that the tarball will create on untar, it has to create a sub directory
	Creates string
	// Governor is the optional name of a governor to use for concurrency control
	Governor string
	// GovernorTimeout is how long we'll try to access the governor
	GovernorTimeout time.Duration `mapstructure:"governor_timeout"`
	// Insecure skips TLS verification on https downloads (not implemented)
	Insecure bool
	// Password for accessing the source, required when a username is set
	Password string
	// Source is a URL to the file being downloaded, only tar.gz format is supported
	Source string
	// TargetDirectory is the directory where the tarball will be extracted
	TargetDirectory string `mapstructure:"target"`
	// Timeout is how long HTTP operations are allowed to take
	Timeout time.Duration
	// Username is the username to use when downloading, Password is required in addition
	Username string
	// ContentChecksums a file in the archive made using sha256 used for verification of files in the archive after extraction and on every interval check
	ContentChecksums string `mapstructure:"verify"`
	// ContentChecksumsChecksum is a sha256 hex string of the file specified in ContentChecksums
	ContentChecksumsChecksum string `mapstructure:"verify_checksum"`
}

type State

type State int
const (
	Unknown State = iota
	Skipped
	Error
	VerifiedOK
	Downloaded
	VerifyFailed
	MissingCreates
	MissingChecksums
)

type StateNotification

type StateNotification struct {
	event.Event

	Source          string `json:"source"`
	Creates         string `json:"creates"`
	PreviousOutcome string `json:"previous_outcome"`
	PreviousRunTime int64  `json:"previous_run_time"`
}

StateNotification describes the current state of the watcher described by io.choria.machine.watcher.exec.v1.state

func (*StateNotification) CloudEvent

func (s *StateNotification) CloudEvent() cloudevents.Event

CloudEvent creates a CloudEvent from the state notification

func (*StateNotification) JSON

func (s *StateNotification) JSON() ([]byte, error)

JSON creates a JSON representation of the notification

func (*StateNotification) String

func (s *StateNotification) String() string

String is a string representation of the notification suitable for printing

type Watcher

type Watcher struct {
	*watcher.Watcher
	// contains filtered or unexported fields
}

func (*Watcher) CurrentState

func (w *Watcher) CurrentState() any

func (*Watcher) Run

func (w *Watcher) Run(ctx context.Context, wg *sync.WaitGroup)

Jump to

Keyboard shortcuts

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