sdk

package module
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: May 22, 2023 License: MIT Imports: 12 Imported by: 1

README

concourse-go-sdk

Go Reference

a minimal SDK for implementing an idiomatic Concourse custom resource type in go.

Getting Started

  1. Define 4 required types as structs with appropriate json struct tags
  2. Provide a resource implementation that leverages the types defined in step 1
  3. Define a func main() {} that invokes this sdk's Main function with your resource and type definitions
  4. Build a check, in, and out binary using goreleaser or directly passing the appropriate linker flags to configure the build variable (e.g. -ldflags="-X 'github.com/cludden/concourse-go-sdk.Operation={check,in,out}'")

Example

package main

import (
	"context"
	"errors"

	sdk "github.com/cludden/concourse-go-sdk"
)

// 3. Invoke the Main function provided by this sdk
func main() {
	sdk.Main[Source, Version, GetParams, PutParams](&Resource{})
}

// 1. Define required type definitions
type (
	GetParams struct{}

	PutParams struct{}

	Source struct{}

	Version struct{}
)

// 2. Define resource type and corresponding methods
type Resource struct{
    // embed BaseResource to inherit noop implementations of all optional methods
    sdk.BaseResource[Source, Version, GetParams, PutParams]
}

// Check checks for new versions
func (r *Resource) Check(ctx context.Context, s *Source, v *Version) ([]Version, error) {
	return nil, errors.New("not implemented")
}

// In retrieves the specified version and writes it to the filesystem
func (r *Resource) In(ctx context.Context, s *Source, v *Version, dir string, p *GetParams) ([]sdk.Metadata, error) {
	return nil, errors.New("not implemented")
}

// Out creates a new version
func (r *Resource) Out(ctx context.Context, s *Source, dir string, p *PutParams) (Version, []sdk.Metadata, error) {
	return Version{}, nil, errors.New("not implemented")
}

Required Types

The various resource methods leverage a combination of 4 required types (Source, Version, GetParams, PutParams), which should be implemented as Go struct types with appropriate struct tags defined for accurate JSON decoding. Note that the names of these types are not important, but their position in the various method signatures is.

Source

an arbitrary JSON object which specifies the runtime configuration of the resource, including any credentials. This is passed verbatim from the resource configuration. For the git resource, this would include the repo URI, the branch, and the private key, if necessary.

Example

// Source describes the available configuration for a git resource
type Source struct {
    URI           string   `json:"uri"`
    Branch        string   `json:"branch"`
    PrivateKey    string   `json:"private_key"`
    Paths         []string `json:"paths"`
    IgnorePaths   []string `json:"ignore_paths"`
    DisableCISkip bool     `json:"disable_ci_skip"`
}
Version

a JSON object with string fields, used to uniquely identify an instance of the resource. For git this would be the commit's SHA.

Example

// Version describes the attributes that uniquely identify a git resource version
type Version struct {
    Ref string `json:"ref"`
}
GetParams

an arbitrary JSON object passed along verbatim from get step params on a get step.

Example

// GetParams describes the available parameters for a git resource get step
type GetParams struct {
    Depth      int      `json:"depth"`
    FetchTags  bool     `json:"fetch_tags"`
    Submodules []string `json:"submodules"`
}
PutParams

an arbitrary JSON object passed along verbatim from put step params on a put step.

Example

// PutParams describes the available parameters for a git resource put step
type PutParams struct {
    Repository string `json:"repository"`
    Rebase     bool   `json:"rebase"`
    Merge      bool   `json:"merge"`
    Tag        string `json:"tag"`
    Force      bool   `json:"force"`
}
Validation

Any of the above types can optionally choose to implement the Validatable interface shown below, in which case the sdk will perform runtime validation prior to invoking action methods.

type Validatable interface {
    Validate(context.Context) error
}

Resource Implementation

A Resource can be any struct that satisfies the following interface utilizing the required types documented above. This package provides a BaseResource type that provides an embeddable Resource implementation with noops for all methods, allowing consumers to only provide implementations for desired functionality.

// Resource describes a Concourse custom resource implementation
type Resource[Source any, Version any, GetParams any, PutParams any] interface {
    // Archive intializes an Archive implementation for persisting resource
    // version history outside of Concourse
    Archive(context.Context, *Source) (Archive, error)

    // Check checks for new versions
    Check(context.Context, *Source, *Version) ([]Version, error)

    // Close is called after any Check/In/Out operation
    Close(context.Context) error

    // In fetches the specified version and writes it to the filesystem
    In(context.Context, *Source, *Version, string, *GetParams) ([]Metadata, error)

    // Initialize is called prior to any Check/In/Out operation and provides
    // an opportunity to perform common resource initialization logic
    Initialize(context.Context, *Source) error

    // Out creates a new resource version
    Out(context.Context, *Source, string, *PutParams) (Version, []Metadata, error)
}

Example

type (
	GetParams struct{}

	PutParams struct{}

	Source struct{}

	Version struct{
        Ref string `json:"ref"`
    }
)

type MyResource struct {
	sdk.BaseResource[Source, Version, GetParams, PutParams]
}

func (r *MyResource) Out(ctx context.Context, source *Source, path string, p *PutParams) (Version, []sdk.Metadata, error) {
	return Version{Ref: "foo"}, []sdk.Metadata{{Name: "bar", Value: "baz"}}, nil
}

Archiving

In certain situations, Concourse can reset a particular resource's version history (e.g. when the source parameters change). Often times, this is undesirable. This sdk supports archiving resource version history as a workaround. To enable this functionality, a resource should implement an Archive method that initializes and returns a valid archive:

type Archive interface {
    // Close should handle any graceful termination steps (e.g. closing open connections or file handles, persisting local data to a remote store, etc)
	Close(ctx context.Context) error
    // History returns an ordered list of json serialized versions
	History(ctx context.Context) ([][]byte, error)
    // Put appends an ordered list of versions to a resource's history, making sure to avoid duplicates
	Put(ctx context.Context, versions ...[]byte) error
}

This sdk also provides the following out-of-the-box archive implementations that can be utilized via:

import (
    "github.com/cludden/concourse-go-sdk/pkg/archive"
)

type Source struct {
    Archive *archive.Config `json:"archive"`
}

func (r *Resource) Archive(ctx context.Context, s *Source) (archive.Archive, error) {
    if s != nil && s.Archive != nil {
        return archive.New(ctx, *s.Archive)
    }
    return nil, nil
}
boltdb

an archive implementation that utilizes boltdb backed by AWS S3.

License

Licensed under the MIT License
Copyright (c) 2023 Chris Ludden

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Operation = "check"

Operation describes the resource operation to perform, set via linker flags

Functions

func ContextWithStdErr

func ContextWithStdErr(ctx context.Context, stderr io.Writer) context.Context

ContextWithStdErr returns a child context with the resource's configured stderr writer

func Exec

func Exec[Source any, Version any, GetParams any, PutParams any](
	ctx context.Context,
	op Op,
	r Resource[Source, Version, GetParams, PutParams],
	stdin io.Reader,
	stdout, stderr io.Writer,
	args []string,
) (err error)

Exec implements a shared entrypoint for all supported resource operations and handles parsing and validating resource configuration and initializing the resource if implemented

func Main

func Main[Source any, Version any, GetParams any, PutParams any](r Resource[Source, Version, GetParams, PutParams])

Main executes a Concourse custom resource operation

func StdErrFromContext

func StdErrFromContext(ctx context.Context) io.Writer

StdErrFromContext extracts the resource's configured stderr writer from the given context value

Types

type Archive added in v1.0.0

type Archive interface {
	Close(ctx context.Context) error
	History(ctx context.Context, latest []byte) ([][]byte, error)
	Put(ctx context.Context, versions ...[]byte) error
}

Archive describes a Concourse version archive

type BaseResource added in v1.0.0

type BaseResource[Source any, Version any, GetParams any, PutParams any] struct{}

BaseResource provides an embeddable Resource implementation with noops for optional methods

func (*BaseResource[Source, Version, GetParams, PutParams]) Archive added in v1.0.0

func (r *BaseResource[Source, Version, GetParams, PutParams]) Archive(ctx context.Context, s *Source) (Archive, error)

func (*BaseResource[Source, Version, GetParams, PutParams]) Check added in v1.0.0

func (r *BaseResource[Source, Version, GetParams, PutParams]) Check(ctx context.Context, s *Source, v *Version) ([]Version, error)

func (*BaseResource[Source, Version, GetParams, PutParams]) Close added in v1.0.0

func (r *BaseResource[Source, Version, GetParams, PutParams]) Close(ctx context.Context) error

func (*BaseResource[Source, Version, GetParams, PutParams]) In added in v1.0.0

func (r *BaseResource[Source, Version, GetParams, PutParams]) In(ctx context.Context, s *Source, v *Version, path string, p *GetParams) ([]Metadata, error)

func (*BaseResource[Source, Version, GetParams, PutParams]) Initialize added in v1.0.0

func (r *BaseResource[Source, Version, GetParams, PutParams]) Initialize(ctx context.Context, s *Source) error

func (*BaseResource[Source, Version, GetParams, PutParams]) Out added in v1.0.0

func (r *BaseResource[Source, Version, GetParams, PutParams]) Out(ctx context.Context, s *Source, path string, p *GetParams) (Version, []Metadata, error)

type Metadata

type Metadata struct {
	Name  string
	Value string
}

Metadata describes resource version metadata, returned by get/put steps

type Op added in v1.0.0

type Op int

Op implements an enumeration of supported resource operations

const (
	CheckOp Op
	InOp
	OutOp
)

Supported operations

type Resource added in v1.0.0

type Resource[Source any, Version any, GetParams any, PutParams any] interface {
	// Archive intializes an Archive implementation for persisting resource
	// version history outside of Concourse
	Archive(context.Context, *Source) (Archive, error)

	// Check checks for new versions
	Check(context.Context, *Source, *Version) ([]Version, error)

	// Close is called after any Check/In/Out operation
	Close(context.Context) error

	// In fetches the specified version and writes it to the filesystem
	In(context.Context, *Source, *Version, string, *GetParams) ([]Metadata, error)

	// Initialize is called prior to any Check/In/Out operation and provides
	// an opportunity to perform common resource initialization logic
	Initialize(context.Context, *Source) error

	// Out creates a new resource version
	Out(context.Context, *Source, string, *PutParams) (Version, []Metadata, error)
}

Resource describes a Concourse custom resource implementation

type Response

type Response[Version any] struct {
	Version  *Version   `json:"version"`
	Metadata []Metadata `json:"metadata"`
}

Reponse describes a in/out response payload

type Validatable

type Validatable interface {
	Validate(context.Context) error
}

Validatable describes an interface that can be implemented by third party types to opt into automatic resource validation

Directories

Path Synopsis
pkg

Jump to

Keyboard shortcuts

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