<commit_before>package commands

import (
	"os"

	"github.com/Shopify/themekit/kit"
	"github.com/Shopify/themekit/theme"
)

// ReplaceCommand overwrite theme file(s)
func ReplaceCommand(args Args, done chan bool) {
	rawEvents, throttledEvents := prepareChannel(args)
	logs := args.ThemeClient.Process(throttledEvents, done)
	mergeEvents(args.EventLog, []chan kit.ThemeEvent{logs})
	enqueueEvents(args.ThemeClient, args.Filenames, rawEvents)
}

func enqueueEvents(client kit.ThemeClient, filenames []string, events chan kit.AssetEvent) {
	root, _ := os.Getwd()
	if len(filenames) == 0 {
		go fullReplace(client.AssetListSync(), client.LocalAssets(root), events)
		return
	}
	go func() {
		for _, filename := range filenames {
			asset, err := theme.LoadAsset(root, filename)
			if err == nil {
				events <- kit.NewUploadEvent(asset)
			}
		}
		close(events)
	}()
}

// fullReplace takes slices with assets both from the local filesystem and the remote server and translates them
// into a suitable set of events that updates the remote site to the local state.
func fullReplace(remoteAssets, localAssets []theme.Asset, events chan kit.AssetEvent) {
	assetsActions := map[string]kit.AssetEvent{}
	generateActions := func(assets []theme.Asset, assetEventFn func(asset theme.Asset) kit.SimpleAssetEvent) {
		for _, asset := range assets {
			assetsActions[asset.Key] = assetEventFn(asset)
		}
	}
	generateActions(remoteAssets, kit.NewRemovalEvent)
	generateActions(localAssets, kit.NewUploadEvent)
	go func() {
		for _, event := range assetsActions {
			events <- event
		}
		close(events)
	}()

}

func prepareChannel(args Args) (rawEvents, throttledEvents chan kit.AssetEvent) {
	rawEvents = make(chan kit.AssetEvent)
	if args.Bucket == nil {
		return rawEvents, rawEvents
	}

	foreman := kit.NewForeman(args.Bucket)
	foreman.JobQueue = rawEvents
	foreman.WorkerQueue = make(chan kit.AssetEvent)
	foreman.IssueWork()
	return foreman.JobQueue, foreman.WorkerQueue
}
<commit_msg>added removal to replace single file to make it more consistent with full replace<commit_after>package commands

import (
	"os"

	"github.com/Shopify/themekit/kit"
	"github.com/Shopify/themekit/theme"
)

// ReplaceCommand overwrite theme file(s)
func ReplaceCommand(args Args, done chan bool) {
	rawEvents, throttledEvents := prepareChannel(args)
	logs := args.ThemeClient.Process(throttledEvents, done)
	mergeEvents(args.EventLog, []chan kit.ThemeEvent{logs})
	enqueueEvents(args.ThemeClient, args.Filenames, rawEvents)
}

func enqueueEvents(client kit.ThemeClient, filenames []string, events chan kit.AssetEvent) {
	root, _ := os.Getwd()
	if len(filenames) == 0 {
		go fullReplace(client.AssetListSync(), client.LocalAssets(root), events)
		return
	}
	go func() {
		for _, filename := range filenames {
			asset, err := theme.LoadAsset(root, filename)
			if err == nil {
				events <- kit.NewRemovalEvent(asset)
				events <- kit.NewUploadEvent(asset)
			}
		}
		close(events)
	}()
}

// fullReplace takes slices with assets both from the local filesystem and the remote server and translates them
// into a suitable set of events that updates the remote site to the local state.
func fullReplace(remoteAssets, localAssets []theme.Asset, events chan kit.AssetEvent) {
	assetsActions := map[string]kit.AssetEvent{}
	generateActions := func(assets []theme.Asset, assetEventFn func(asset theme.Asset) kit.SimpleAssetEvent) {
		for _, asset := range assets {
			assetsActions[asset.Key] = assetEventFn(asset)
		}
	}
	generateActions(remoteAssets, kit.NewRemovalEvent)
	generateActions(localAssets, kit.NewUploadEvent)
	go func() {
		for _, event := range assetsActions {
			events <- event
		}
		close(events)
	}()

}

func prepareChannel(args Args) (rawEvents, throttledEvents chan kit.AssetEvent) {
	rawEvents = make(chan kit.AssetEvent)
	if args.Bucket == nil {
		return rawEvents, rawEvents
	}

	foreman := kit.NewForeman(args.Bucket)
	foreman.JobQueue = rawEvents
	foreman.WorkerQueue = make(chan kit.AssetEvent)
	foreman.IssueWork()
	return foreman.JobQueue, foreman.WorkerQueue
}
<|endoftext|>


<commit_before>package commands

import (
	"fmt"
	"strings"

	"github.com/spf13/cobra"

	"github.com/nanobox-io/nanobox/models"
)

var (

	// VersionCmd ...
	VersionCmd = &cobra.Command{
		Use:   "version",
		Short: "Show the current Nanobox version.",
		Long:  ``,
		Run:   versionFn,
	}
)

// versionFn ...
func versionFn(ccmd *cobra.Command, args []string) {
	v := "0.9.0"
	update, _ := models.LoadUpdate()
	md5Parts := strings.Fields(update.CurrentVersion)
	md5 := ""
	if len(md5Parts) > 1 {
		md5 = md5Parts[len(md5Parts)-1]
	}
	fmt.Printf("Nanobox version %s (%s)\n", v, md5)
}
<commit_msg>bump the version on the version command<commit_after>package commands

import (
	"fmt"
	"strings"

	"github.com/spf13/cobra"

	"github.com/nanobox-io/nanobox/models"
)

var (

	// VersionCmd ...
	VersionCmd = &cobra.Command{
		Use:   "version",
		Short: "Show the current Nanobox version.",
		Long:  ``,
		Run:   versionFn,
	}
)

// versionFn ...
func versionFn(ccmd *cobra.Command, args []string) {
	v := "v2.0.0"
	update, _ := models.LoadUpdate()
	md5Parts := strings.Fields(update.CurrentVersion)
	md5 := ""
	if len(md5Parts) > 1 {
		md5 = md5Parts[len(md5Parts)-1]
	}
	fmt.Printf("Nanobox version %s (%s)\n", v, md5)
}
<|endoftext|>


<commit_before>// +build appengine

package gcache

import (
	"net/http"

	"golang.org/x/net/context"
	newappengine "google.golang.org/appengine"
)

func newContext(
	r *http.Request,
) *context.Context {
	ctx := newappengine.NewContext(r)
	return &ctx
}
<commit_msg>set 60 sec to timeout on App Engine<commit_after>// +build appengine

package gcache

import (
	"net/http"
	"time"

	"golang.org/x/net/context"
	newappengine "google.golang.org/appengine"
)

const (
	deadline = time.Duration(60) * time.Second
)

func newContext(
	r *http.Request,
) *context.Context {
	ctx, _ := context.WithTimeout(newappengine.NewContext(r), deadline)
	return &ctx
}
<|endoftext|>


<commit_before>package etcdhttp

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"
	"time"

	"code.google.com/p/go.net/context"
	"github.com/coreos/etcd/elog"
	etcdserver "github.com/coreos/etcd/etcdserver2"
	"github.com/coreos/etcd/raft"
	"github.com/coreos/etcd/store"
)

var errClosed = errors.New("etcdhttp: client closed connection")

const DefaultTimeout = 500 * time.Millisecond

type Handler struct {
	Timeout time.Duration
	Server  etcdserver.Server
}

func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// TODO: set read/write timeout?

	timeout := h.Timeout
	if timeout == 0 {
		timeout = DefaultTimeout
	}

	ctx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()

	switch {
	case strings.HasPrefix(r.URL.Path, "/raft"):
		h.serveRaft(ctx, w, r)
	case strings.HasPrefix(r.URL.Path, "/keys/"):
		h.serveKeys(ctx, w, r)
	default:
		http.NotFound(w, r)
	}
}

func (h Handler) serveKeys(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	rr := parseRequest(r)

	resp, err := h.Server.Do(ctx, rr)
	if err != nil {
		// TODO(bmizerany): switch on store errors and etcdserver.ErrUnknownMethod
		panic("TODO")
	}

	if err := encodeResponse(ctx, w, resp); err != nil {
		http.Error(w, "Timeout while waiting for response", 504)
	}
}

func (h Handler) serveRaft(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	b, err := ioutil.ReadAll(r.Body)
	if err != nil {
		elog.TODO()
	}
	var m raft.Message
	if err := m.Unmarshal(b); err != nil {
		elog.TODO()
	}
	if err := h.Server.Node.Step(ctx, m); err != nil {
		elog.TODO()
	}
}

func genId() int64 {
	panic("implement me")
}

func parseRequest(r *http.Request) etcdserver.Request {
	q := r.URL.Query()
	rr := etcdserver.Request{
		Id:        genId(),
		Method:    r.Method,
		Path:      r.URL.Path[len("/keys/"):],
		Val:       q.Get("value"),
		PrevValue: q.Get("prevValue"),
		PrevIndex: parseUint64(q.Get("prevIndex")),
		Recursive: parseBool(q.Get("recursive")),
		Since:     parseUint64(q.Get("waitIndex")),
		Sorted:    parseBool(q.Get("sorted")),
		Wait:      parseBool(q.Get("wait")),
	}

	// PrevExists is nullable, so we leave it null if prevExist wasn't
	// specified.
	_, ok := q["wait"]
	if ok {
		bv := parseBool(q.Get("wait"))
		rr.PrevExists = &bv
	}

	ttl := parseUint64(q.Get("ttl"))
	if ttl > 0 {
		expr := time.Duration(ttl) * time.Second
		rr.Expiration = time.Now().Add(expr).UnixNano()
	}

	return rr
}

func parseBool(s string) bool {
	v, _ := strconv.ParseBool(s)
	return v
}

func parseUint64(s string) uint64 {
	v, _ := strconv.ParseUint(s, 10, 64)
	return v
}

func encodeResponse(ctx context.Context, w http.ResponseWriter, resp etcdserver.Response) (err error) {
	var ev *store.Event
	switch {
	case resp.Event != nil:
		ev = resp.Event
	case resp.Watcher != nil:
		ev, err = waitForEvent(ctx, w, resp.Watcher)
		if err != nil {
			return err
		}
	default:
		panic("should not be reachable")
	}

	w.Header().Set("Content-Type", "application/json")
	w.Header().Add("X-Etcd-Index", fmt.Sprint(ev.Index()))

	if ev.IsCreated() {
		w.WriteHeader(http.StatusCreated)
	} else {
		w.WriteHeader(http.StatusOK)
	}

	if err := json.NewEncoder(w).Encode(ev); err != nil {
		panic(err) // should never be reached
	}
	return nil
}

func waitForEvent(ctx context.Context, w http.ResponseWriter, wa *store.Watcher) (*store.Event, error) {
	// TODO(bmizerany): support streaming?
	defer wa.Remove()
	var nch <-chan bool
	if x, ok := w.(http.CloseNotifier); ok {
		nch = x.CloseNotify()
	}

	select {
	case ev := <-wa.EventChan:
		return ev, nil
	case <-nch:
		elog.TODO()
		return nil, errClosed
	case <-ctx.Done():
		return nil, ctx.Err()
	}
}
<commit_msg>etcdserver/etcdhttp: remove unncessary else<commit_after>package etcdhttp

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"
	"time"

	"code.google.com/p/go.net/context"
	"github.com/coreos/etcd/elog"
	etcdserver "github.com/coreos/etcd/etcdserver2"
	"github.com/coreos/etcd/raft"
	"github.com/coreos/etcd/store"
)

var errClosed = errors.New("etcdhttp: client closed connection")

const DefaultTimeout = 500 * time.Millisecond

type Handler struct {
	Timeout time.Duration
	Server  etcdserver.Server
}

func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// TODO: set read/write timeout?

	timeout := h.Timeout
	if timeout == 0 {
		timeout = DefaultTimeout
	}

	ctx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()

	switch {
	case strings.HasPrefix(r.URL.Path, "/raft"):
		h.serveRaft(ctx, w, r)
	case strings.HasPrefix(r.URL.Path, "/keys/"):
		h.serveKeys(ctx, w, r)
	default:
		http.NotFound(w, r)
	}
}

func (h Handler) serveKeys(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	rr := parseRequest(r)

	resp, err := h.Server.Do(ctx, rr)
	if err != nil {
		// TODO(bmizerany): switch on store errors and etcdserver.ErrUnknownMethod
		panic("TODO")
	}

	if err := encodeResponse(ctx, w, resp); err != nil {
		http.Error(w, "Timeout while waiting for response", 504)
	}
}

func (h Handler) serveRaft(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	b, err := ioutil.ReadAll(r.Body)
	if err != nil {
		elog.TODO()
	}
	var m raft.Message
	if err := m.Unmarshal(b); err != nil {
		elog.TODO()
	}
	if err := h.Server.Node.Step(ctx, m); err != nil {
		elog.TODO()
	}
}

func genId() int64 {
	panic("implement me")
}

func parseRequest(r *http.Request) etcdserver.Request {
	q := r.URL.Query()
	rr := etcdserver.Request{
		Id:        genId(),
		Method:    r.Method,
		Path:      r.URL.Path[len("/keys/"):],
		Val:       q.Get("value"),
		PrevValue: q.Get("prevValue"),
		PrevIndex: parseUint64(q.Get("prevIndex")),
		Recursive: parseBool(q.Get("recursive")),
		Since:     parseUint64(q.Get("waitIndex")),
		Sorted:    parseBool(q.Get("sorted")),
		Wait:      parseBool(q.Get("wait")),
	}

	// PrevExists is nullable, so we leave it null if prevExist wasn't
	// specified.
	_, ok := q["wait"]
	if ok {
		bv := parseBool(q.Get("wait"))
		rr.PrevExists = &bv
	}

	ttl := parseUint64(q.Get("ttl"))
	if ttl > 0 {
		expr := time.Duration(ttl) * time.Second
		rr.Expiration = time.Now().Add(expr).UnixNano()
	}

	return rr
}

func parseBool(s string) bool {
	v, _ := strconv.ParseBool(s)
	return v
}

func parseUint64(s string) uint64 {
	v, _ := strconv.ParseUint(s, 10, 64)
	return v
}

func encodeResponse(ctx context.Context, w http.ResponseWriter, resp etcdserver.Response) (err error) {
	var ev *store.Event
	switch {
	case resp.Event != nil:
		ev = resp.Event
	case resp.Watcher != nil:
		ev, err = waitForEvent(ctx, w, resp.Watcher)
		if err != nil {
			return err
		}
	default:
		panic("should not be reachable")
	}

	w.Header().Set("Content-Type", "application/json")
	w.Header().Add("X-Etcd-Index", fmt.Sprint(ev.Index()))

	if ev.IsCreated() {
		w.WriteHeader(http.StatusCreated)
	}

	if err := json.NewEncoder(w).Encode(ev); err != nil {
		panic(err) // should never be reached
	}
	return nil
}

func waitForEvent(ctx context.Context, w http.ResponseWriter, wa *store.Watcher) (*store.Event, error) {
	// TODO(bmizerany): support streaming?
	defer wa.Remove()
	var nch <-chan bool
	if x, ok := w.(http.CloseNotifier); ok {
		nch = x.CloseNotify()
	}

	select {
	case ev := <-wa.EventChan:
		return ev, nil
	case <-nch:
		elog.TODO()
		return nil, errClosed
	case <-ctx.Done():
		return nil, ctx.Err()
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"log"
	"os"
	"path/filepath"

	"github.com/couchbaselabs/cbfs/client"
	"github.com/couchbaselabs/cbfs/tools"
	"github.com/dustin/httputil"
)

var findFlags = flag.NewFlagSet("find", flag.ExitOnError)
var findTemplate = findFlags.String("t", "", "Display template")
var findTemplateFile = findFlags.String("T", "", "Display template filename")
var findDashName = findFlags.String("name", "*", "Glob name to match")

const defaultFindTemplate = `{{.Name}}
`

func findCommand(u string, args []string) {
	src := findFlags.Arg(0)
	for src[len(src)-1] == '/' {
		src = src[:len(src)-1]
	}

	tmpl := cbfstool.GetTemplate(*findTemplate, *findTemplateFile,
		defaultFindTemplate)

	httputil.InitHTTPTracker(false)

	client, err := cbfsclient.New(u)
	cbfstool.MaybeFatal(err, "Can't build a client: %v", err)

	things, err := client.ListDepth(src, 4096)
	cbfstool.MaybeFatal(err, "Can't list things: %v", err)

	matchedDirs := map[string]struct{}{}
	for fn, inf := range things.Files {
		fn = fn[len(src)+1:]
		dir := filepath.Dir(fn)
		matched := false
		if _, seen := matchedDirs[dir]; !seen {
			matched, err = filepath.Match(*findDashName,
				filepath.Base(dir))
			if err != nil {
				log.Fatalf("Error globbing: %v", err)
			}
			matchedDirs[dir] = struct{}{}
			if matched {
				if err := tmpl.Execute(os.Stdout, struct {
					Name  string
					IsDir bool
					Meta  cbfsclient.FileMeta
				}{Name: dir, IsDir: true}); err != nil {
					log.Fatalf("Error executing template: %v", err)
				}
				continue
			}
		}
		if !matched {
			matched, err = filepath.Match(*findDashName,
				filepath.Base(fn))
			if err != nil {
				log.Fatalf("Error globbing: %v", err)
			}
		}
		if matched {
			if err := tmpl.Execute(os.Stdout, struct {
				Name  string
				IsDir bool
				Meta  cbfsclient.FileMeta
			}{fn, false, inf}); err != nil {
				log.Fatalf("Error executing template: %v", err)
			}
		}
	}
}
<commit_msg>Refactored matching for sanity<commit_after>package main

import (
	"flag"
	"log"
	"os"
	"path/filepath"

	"github.com/couchbaselabs/cbfs/client"
	"github.com/couchbaselabs/cbfs/tools"
	"github.com/dustin/httputil"
)

var findFlags = flag.NewFlagSet("find", flag.ExitOnError)
var findTemplate = findFlags.String("t", "", "Display template")
var findTemplateFile = findFlags.String("T", "", "Display template filename")
var findDashName = findFlags.String("name", "", "Glob name to match")

const defaultFindTemplate = `{{.Name}}
`

func findNameMatches(name string) bool {
	if *findDashName == "" {
		return true
	}
	matched, err := filepath.Match(*findDashName, filepath.Base(name))
	if err != nil {
		log.Fatalf("Error globbing: %v", err)
	}
	return matched
}

func findCommand(u string, args []string) {
	src := findFlags.Arg(0)
	for src[len(src)-1] == '/' {
		src = src[:len(src)-1]
	}

	tmpl := cbfstool.GetTemplate(*findTemplate, *findTemplateFile,
		defaultFindTemplate)

	httputil.InitHTTPTracker(false)

	client, err := cbfsclient.New(u)
	cbfstool.MaybeFatal(err, "Can't build a client: %v", err)

	things, err := client.ListDepth(src, 4096)
	cbfstool.MaybeFatal(err, "Can't list things: %v", err)

	matchedDirs := map[string]struct{}{}
	for fn, inf := range things.Files {
		fn = fn[len(src)+1:]
		dir := filepath.Dir(fn)
		matched := false
		if _, seen := matchedDirs[dir]; !seen {
			matched = findNameMatches(filepath.Base(dir))
			matchedDirs[dir] = struct{}{}
			if matched {
				if err := tmpl.Execute(os.Stdout, struct {
					Name  string
					IsDir bool
					Meta  cbfsclient.FileMeta
				}{Name: dir, IsDir: true}); err != nil {
					log.Fatalf("Error executing template: %v", err)
				}
				continue
			}
		}
		if !matched {
			matched = findNameMatches(filepath.Base(fn))
		}
		if matched {
			if err := tmpl.Execute(os.Stdout, struct {
				Name  string
				IsDir bool
				Meta  cbfsclient.FileMeta
			}{fn, false, inf}); err != nil {
				log.Fatalf("Error executing template: %v", err)
			}
		}
	}
}
<|endoftext|>


<commit_before>// Package probes provides some probe implementations.
//
// This package defines some helpers to send alert emails, while
// actual probes are defined in subpackages.
package probes // import "hkjn.me/probes"

import (
	"bytes"
	"fmt"
	"html/template"

	"github.com/golang/glog"
	"github.com/sendgrid/sendgrid-go"
	"hkjn.me/prober"
)

type ConfigT struct {
	Template *template.Template
	Alert    struct {
		// From:, To: addresses for alert emails.
		Sender, Recipient string
		CCs               []string
	}
	Sendgrid struct {
		User, Password string
	}
}

var Config = ConfigT{}

func getClient() (*sendgrid.SGClient, error) {
	user := Config.Sendgrid.User
	pw := Config.Sendgrid.Password
	if user == "" {
		return nil, fmt.Errorf("no sendgrid user specified - set Config.Sendgrid.User")
	}
	if pw == "" {
		return nil, fmt.Errorf("no sendgrid password specified - set Config.Sendgrid.Password")
	}
	return sendgrid.NewSendGridClient(user, pw), nil
}

// SendAlertEmail sends an alert email.
func SendAlertEmail(name, desc string, badness int, records prober.Records) error {
	glog.V(1).Infof("sending alert email..\n")
	data := struct {
		Name, Desc string
		Badness    int
		Records    prober.Records
	}{name, desc, badness, records}

	var html bytes.Buffer
	err := Config.Template.ExecuteTemplate(&html, "email", data)
	if err != nil {
		return fmt.Errorf("failed to construct email from template: %v", err)
	}

	m := sendgrid.NewMail()
	subject := fmt.Sprintf("%s failed (badness %d)", name, badness)
	m.SetSubject(subject)
	err = m.AddTo(Config.Alert.Recipient)
	if err != nil {
		return fmt.Errorf("failed to add recipients: %v", err)
	}
	err = m.AddCcs(Config.Alert.CCs)
	if err != nil {
		return fmt.Errorf("failed to add cc recipients: %v", err)
	}
	m.SetHTML(html.String())
	err = m.SetFrom(Config.Alert.Sender)
	if err != nil {
		return fmt.Errorf("failed to add sender %q: %v", Config.Alert.Sender, err)
	}
	sgClient, err := getClient()
	if err != nil {
		return fmt.Errorf("failed to create mail client: %v", err)
	}
	err = sgClient.Send(m)
	if err != nil {
		return fmt.Errorf("failed to send mail: %v", err)
	}
	glog.Infof("sent alert email to %s\n", Config.Alert.Recipient)
	return nil
}
<commit_msg>makes email template less magic: makes Config.Template hold the HTML email template string instead of *template.Template, exposes Config.TemplateName (only needs to be changed if user desires another template name), exposes EmailData struct showing which values are available within the template, adds some comments<commit_after>// Package probes provides some probe implementations.
//
// This package defines some helpers to send alert emails, while
// actual probes are defined in subpackages.
//
// To send alert emails, the following configuration is required at
// minimum:
//   - Config.SendGrid: sendgrid credentials
//   - Config.Alert.Recipient: who receives the emails
package probes // import "hkjn.me/probes"

import (
	"bytes"
	"fmt"
	"html/template"

	"github.com/golang/glog"
	"github.com/sendgrid/sendgrid-go"
	"hkjn.me/prober"
)

// Config is the email configuration.
var Config = EmailConfig{TemplateName: "email"}

// EmailConfig describes the structure of the email configuration.
type EmailConfig struct {
	// Template for HTML email. See EmailData for what's passed to the template.
	Template     string
	TemplateName string // name of the template
	Alert        struct {
		Sender    string   // From: address
		Recipient string   // To: address
		CCs       []string // CC: addresses
	}
	Sendgrid struct {
		User, Password string // sendgrid credentials
	}
}

// EmailData describes the data available in EmailConfig.Template.
type EmailData struct {
	Name, Desc string
	Badness    int
	Records    prober.Records
}

func getClient() (*sendgrid.SGClient, error) {
	user := Config.Sendgrid.User
	pw := Config.Sendgrid.Password
	if user == "" {
		return nil, fmt.Errorf("no sendgrid user specified - set Config.Sendgrid.User")
	}
	if pw == "" {
		return nil, fmt.Errorf("no sendgrid password specified - set Config.Sendgrid.Password")
	}
	return sendgrid.NewSendGridClient(user, pw), nil
}

// SendAlertEmail sends an alert email using SendGrid.
//
// This is provided to simplify Alert() prober.Probe implementations.
func SendAlertEmail(name, desc string, badness int, records prober.Records) error {
	glog.V(1).Infof("sending alert email..\n")

	var t *template.Template
	var err error
	if Config.Alert.Recipient == "" {
		err = fmt.Errorf("missing email recipient - set Config.Alert.Recipient")
	}
	// TODO: would be nice to only parse the template once, but little
	// complicated without complicating config for user, since this will
	// be called from separate goroutines..
	t, err = template.New(Config.TemplateName).Parse(Config.Template)
	if err != nil {
		err = fmt.Errorf("failed to parse email: %v", err)
	}
	if err != nil {
		return err
	}

	var html bytes.Buffer
	data := EmailData{name, desc, badness, records}
	err = t.ExecuteTemplate(
		&html, Config.TemplateName, data)
	if err != nil {
		return fmt.Errorf("failed to construct email from template: %v", err)
	}

	m := sendgrid.NewMail()
	subject := fmt.Sprintf("%s failed (badness %d)", name, badness)
	m.SetSubject(subject)
	err = m.AddTo(Config.Alert.Recipient)
	if err != nil {
		return fmt.Errorf("failed to add recipients: %v", err)
	}
	err = m.AddCcs(Config.Alert.CCs)
	if err != nil {
		return fmt.Errorf("failed to add cc recipients: %v", err)
	}
	m.SetHTML(html.String())
	err = m.SetFrom(Config.Alert.Sender)
	if err != nil {
		return fmt.Errorf("failed to add sender %q: %v", Config.Alert.Sender, err)
	}
	sgClient, err := getClient()
	if err != nil {
		return fmt.Errorf("failed to create mail client: %v", err)
	}
	err = sgClient.Send(m)
	if err != nil {
		return fmt.Errorf("failed to send mail: %v", err)
	}
	glog.Infof("sent alert email to %s\n", Config.Alert.Recipient)
	return nil
}
<|endoftext|>


<commit_before>package profitbricks

import (
	"net/http"
)

//ContractResources object
type ContractResources struct {
	ID         string                      `json:"id,omitempty"`
	PBType     string                      `json:"type,omitempty"`
	Href       string                      `json:"href,omitempty"`
	Properties ContractResourcesProperties `json:"properties,omitempty"`
	Response   string                      `json:"Response,omitempty"`
	Headers    *http.Header                `json:"headers,omitempty"`
	StatusCode int                         `json:"statuscode,omitempty"`
}

//ContractResourcesProperties object
type ContractResourcesProperties struct {
	PBContractNumber string           `json:"PB-Contract-Number,omitempty"`
	Owner            string           `json:"owner,omitempty"`
	Status           string           `json:"status,omitempty"`
	ResourceLimits   *ResourcesLimits `json:"resourceLimits,omitempty"`
}

//ResourcesLimits object
type ResourcesLimits struct {
	CoresPerServer        int32 `json:"coresPerServer,omitempty"`
	CoresPerContract      int32 `json:"coresPerContract,omitempty"`
	CoresProvisioned      int32 `json:"coresProvisioned,omitempty"`
	RAMPerServer          int32 `json:"ramPerServer,omitempty"`
	RAMPerContract        int32 `json:"ramPerContract,omitempty"`
	RAMProvisioned        int32 `json:"ramProvisioned,omitempty"`
	HddLimitPerVolume     int64 `json:"hddLimitPerVolume,omitempty"`
	HddLimitPerContract   int64 `json:"hddLimitPerContract,omitempty"`
	HddVolumeProvisioned  int64 `json:"hddVolumeProvisioned,omitempty"`
	SsdLimitPerVolume     int64 `json:"ssdLimitPerVolume,omitempty"`
	SsdLimitPerContract   int64 `json:"ssdLimitPerContract,omitempty"`
	SsdVolumeProvisioned  int64 `json:"ssdVolumeProvisioned,omitempty"`
	ReservableIps         int32 `json:"reservableIps,omitempty"`
	ReservedIpsOnContract int32 `json:"reservedIpsOnContract,omitempty"`
	ReservedIpsInUse      int32 `json:"reservedIpsInUse,omitempty"`
}

// GetContractResources returns list of contract resources
func (c *Client) GetContractResources() (*ContractResources, error) {
	url := contractsPath()
	ret := &ContractResources{}
	err := c.Get(url, ret, http.StatusOK)
	return ret, err

}
<commit_msg>Fix: contractNumber<commit_after>package profitbricks

import (
	"net/http"
)

//ContractResources object
type ContractResources struct {
	ID         string                      `json:"id,omitempty"`
	PBType     string                      `json:"type,omitempty"`
	Href       string                      `json:"href,omitempty"`
	Properties ContractResourcesProperties `json:"properties,omitempty"`
	Response   string                      `json:"Response,omitempty"`
	Headers    *http.Header                `json:"headers,omitempty"`
	StatusCode int                         `json:"statuscode,omitempty"`
}

//ContractResourcesProperties object
type ContractResourcesProperties struct {
	PBContractNumber string           `json:"contractNumber,omitempty"`
	Owner            string           `json:"owner,omitempty"`
	Status           string           `json:"status,omitempty"`
	ResourceLimits   *ResourcesLimits `json:"resourceLimits,omitempty"`
}

//ResourcesLimits object
type ResourcesLimits struct {
	CoresPerServer        int32 `json:"coresPerServer,omitempty"`
	CoresPerContract      int32 `json:"coresPerContract,omitempty"`
	CoresProvisioned      int32 `json:"coresProvisioned,omitempty"`
	RAMPerServer          int32 `json:"ramPerServer,omitempty"`
	RAMPerContract        int32 `json:"ramPerContract,omitempty"`
	RAMProvisioned        int32 `json:"ramProvisioned,omitempty"`
	HddLimitPerVolume     int64 `json:"hddLimitPerVolume,omitempty"`
	HddLimitPerContract   int64 `json:"hddLimitPerContract,omitempty"`
	HddVolumeProvisioned  int64 `json:"hddVolumeProvisioned,omitempty"`
	SsdLimitPerVolume     int64 `json:"ssdLimitPerVolume,omitempty"`
	SsdLimitPerContract   int64 `json:"ssdLimitPerContract,omitempty"`
	SsdVolumeProvisioned  int64 `json:"ssdVolumeProvisioned,omitempty"`
	ReservableIps         int32 `json:"reservableIps,omitempty"`
	ReservedIpsOnContract int32 `json:"reservedIpsOnContract,omitempty"`
	ReservedIpsInUse      int32 `json:"reservedIpsInUse,omitempty"`
}

// GetContractResources returns list of contract resources
func (c *Client) GetContractResources() (*ContractResources, error) {
	url := contractsPath()
	ret := &ContractResources{}
	err := c.Get(url, ret, http.StatusOK)
	return ret, err

}
<|endoftext|>


<commit_before>package git

import (
	"archive/tar"
	"bytes"
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
	"time"
)

var logger = log.New(os.Stderr, "", 0)

type Repository struct {
	Origin    string
	LocalPath string
}

func (repo *Repository) cacheDir() string {
	return os.Getenv("HOME") + "/.dgtk/cache/git_repositories"
}

func (repo *Repository) Fetch() error {
	logger.Println("fetching origin")
	// -f is required to make sure force pushes will properly update.
	_, e := repo.executeGitCommand("fetch", "-f")
	return e
}

const githubPrefix = "git@github.com:"

func (repo *Repository) clone() error {
	logger.Printf("cloning %s into %s", repo.Origin, repo.localPath())
	cmd := exec.Command("git", "clone", "--bare", repo.Origin, repo.localPath())
	if b, e := cmd.CombinedOutput(); e != nil {
		logger.Printf("ERROR: %s", strings.TrimSpace(string(b)))
		return e
	}
	cmd = exec.Command("git", "--git-dir="+repo.localPath(), "config", "remote.origin.fetch", "refs/heads/*:refs/heads/*")
	if b, e := cmd.CombinedOutput(); e != nil {
		logger.Printf("ERROR: %s", strings.TrimSpace(string(b)))
		return e
	}
	return nil
}

func (repo *Repository) Init() error {
	e := os.MkdirAll(repo.cacheDir(), 0755)
	if e != nil {
		return e
	}

	if !fileExists(repo.localPath()) {
		if e := repo.clone(); e != nil {
			return e
		}
	} else {
		logger.Printf("already cloned %s to %s", repo.Origin, repo.localPath())
	}
	return nil
}

func (repo *Repository) createGitCommand(gitCommand ...string) *exec.Cmd {
	return exec.Command("git", append([]string{"--git-dir=" + repo.localPath()}, gitCommand...)...)
}

func (repo *Repository) executeGitCommand(gitCommand ...string) (b []byte, e error) {
	cmd := repo.createGitCommand(gitCommand...)
	b, e = cmd.CombinedOutput()
	if e != nil {
		logger.Printf("ERROR: %s (%v)", strings.TrimSpace(string(b)), cmd)
		return b, e
	}
	return b, nil
}

func (repo *Repository) MostRecentCommitFor(pattern string) (commit string, e error) {
	commits, e := repo.Commits(&CommitOptions{Limit: 1, Pattern: pattern})
	if e != nil {
		return "", e
	}
	if len(commits) == 0 {
		return "", e
	}
	return commits[0].Checksum, nil
}

var validTar = regexp.MustCompile("^([0-9a-f]{40})$")

// Writes tgz archive to the given tar writer.
func (repo *Repository) WriteArchiveToTar(revision string, w *tar.Writer) (e error) {
	if !validTar.MatchString(revision) {
		return fmt.Errorf("revision %q not valid (must be 40 digit git sha)", revision)
	}

	mtime, e := repo.DateOf(revision, ".")
	if e != nil {
		return e
	}

	e = repo.addArchiveToTar(revision, mtime, w)
	if e != nil {
		return e
	}

	return addFileToArchive("REVISION", []byte(revision), mtime, w)
}

func (repo *Repository) WriteFilesToTar(revision string, w *tar.Writer, files ...string) (e error) {
	if len(files) == 0 {
		return fmt.Errorf("empty file list given")
	}

	if !validTar.MatchString(revision) {
		return fmt.Errorf("revision %q not valid (must be 40 digit git sha)", revision)
	}

	for _, file := range files {
		mtime, e := repo.DateOf(revision, file)
		if e != nil {
			return e
		}

		buf, e := repo.getFileAtRevision(revision, file)
		if e != nil {
			return e
		}

		if e = addFileToArchive(file, buf, mtime, w); e != nil {
			return e
		}
	}

	return nil
}

func (repo *Repository) getFileAtRevision(revision, file string) (content []byte, e error) {
	buf := bytes.NewBuffer(nil)

	cmd := repo.createGitCommand("show", revision+":"+file)
	cmd.Stdout = buf

	if e = cmd.Run(); e != nil {
		return nil, e
	}

	return buf.Bytes(), nil
}

func addFileToArchive(name string, content []byte, modTime time.Time, w *tar.Writer) error {
	e := w.WriteHeader(&tar.Header{Name: name, Size: int64(len(content)), ModTime: modTime, Mode: 0644})
	if e != nil {
		return e
	}
	_, e = w.Write(content)
	return e
}

// write tar.gz archive to writer
func (repo *Repository) Archive(revision string, w io.Writer, files ...string) (int64, error) {
	if err := repo.Init(); err != nil {
		return 0, err
	}
	args := append([]string{"archive", "--format=tar.gz", revision}, files...)
	cmd := repo.createGitCommand(args...)
	stderr := &bytes.Buffer{}
	cmd.Stderr = stderr
	cnt := &counter{}
	cmd.Stdout = io.MultiWriter(w, cnt)
	if err := cmd.Run(); err != nil {
		return 0, fmt.Errorf("%s: %s", err, stderr.String())
	}
	return cnt.cnt, nil
}

type counter struct {
	cnt int64
}

func (c *counter) Write(b []byte) (int, error) {
	c.cnt += int64(len(b))
	return len(b), nil

}

func (repo *Repository) addArchiveToTar(revision string, mtime time.Time, w *tar.Writer) (e error) {
	filename := repo.Name() + ".tar.gz"

	buf := &bytes.Buffer{}

	if _, err := repo.Archive(revision, buf); err != nil {
		return err
	}

	e = w.WriteHeader(&tar.Header{Name: filename, Size: int64(buf.Len()), ModTime: mtime, Mode: 0644})
	if e != nil {
		return e
	}
	_, err := io.Copy(w, buf)
	return err
}

func (repo *Repository) Name() string {
	return strings.TrimSuffix(filepath.Base(repo.Origin), ".git")
}

func (repo *Repository) DateOf(revision, file string) (time.Time, error) {
	b, e := repo.executeGitCommand("log", "-1", "--format='%ct'", revision, "--", file)
	if e != nil {
		return time.Now(), e
	}
	d, e := strconv.Atoi(strings.Trim(string(b), "'\n"))
	if e != nil {
		return time.Now(), e
	}

	return time.Unix(int64(d), 0), nil
}

func (repo *Repository) localPath() string {
	if repo.LocalPath == "" {
		name := repo.Name()
		if strings.HasPrefix(repo.Origin, githubPrefix) {
			name = strings.TrimPrefix(repo.Origin, githubPrefix)
			repo.LocalPath = repo.cacheDir() + "/github.com/" + name
		} else {
			repo.LocalPath = repo.cacheDir() + "/" + repo.Name()
		}
	}
	return repo.LocalPath
}

func (repo *Repository) Commits(options *CommitOptions) (commits []*Commit, e error) {
	if options == nil {
		options = &CommitOptions{Limit: 10}
	}

	parts := []string{"log", "-n", strconv.Itoa(options.Limit), "--pretty=format:%H\t%at\t%s"}
	if options.Pattern != "" {
		parts = append(parts, options.Pattern)
	}
	b, e := repo.executeGitCommand(parts...)
	if e != nil {
		return nil, e
	}
	lines := strings.Split(string(b), "\n")
	commits = make([]*Commit, 0, len(lines))

	for _, line := range lines {
		parts := strings.SplitN(line, "\t", 3)
		if len(parts) == 3 {
			if t, e := strconv.ParseInt(parts[1], 10, 64); e == nil {
				commits = append(commits, &Commit{Checksum: parts[0], AuthorDate: time.Unix(t, 0), Message: parts[2]})
			} else {
				logger.Printf("ERROR: %s", e.Error())
			}
		}
	}
	return commits, nil
}

func fileExists(path string) bool {
	_, err := os.Stat(path)
	return err == nil || !os.IsNotExist(err)
}
<commit_msg>git: remove global logger<commit_after>package git

import (
	"archive/tar"
	"bytes"
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
	"time"
)

type Repository struct {
	Origin    string
	LocalPath string

	Logger Logger
}

func (r *Repository) Printf(m string, args ...interface{}) {
	if r.Logger != nil {
		r.Logger.Printf(m, args...)
	}
}

type Logger interface {
	Printf(string, ...interface{})
}

func (repo *Repository) cacheDir() string {
	return os.Getenv("HOME") + "/.dgtk/cache/git_repositories"
}

func (repo *Repository) Fetch() error {
	repo.Printf("fetching origin")
	// -f is required to make sure force pushes will properly update.
	_, e := repo.executeGitCommand("fetch", "-f")
	return e
}

const githubPrefix = "git@github.com:"

func (repo *Repository) clone() error {
	repo.Printf("cloning %s into %s", repo.Origin, repo.localPath())
	cmd := exec.Command("git", "clone", "--bare", repo.Origin, repo.localPath())
	if b, e := cmd.CombinedOutput(); e != nil {
		repo.Printf("ERROR: %s", strings.TrimSpace(string(b)))
		return e
	}
	cmd = exec.Command("git", "--git-dir="+repo.localPath(), "config", "remote.origin.fetch", "refs/heads/*:refs/heads/*")
	if b, e := cmd.CombinedOutput(); e != nil {
		repo.Printf("ERROR: %s", strings.TrimSpace(string(b)))
		return e
	}
	return nil
}

func (repo *Repository) Init() error {
	e := os.MkdirAll(repo.cacheDir(), 0755)
	if e != nil {
		return e
	}

	if !fileExists(repo.localPath()) {
		if e := repo.clone(); e != nil {
			return e
		}
	} else {
		repo.Printf("already cloned %s to %s", repo.Origin, repo.localPath())
	}
	return nil
}

func (repo *Repository) createGitCommand(gitCommand ...string) *exec.Cmd {
	return exec.Command("git", append([]string{"--git-dir=" + repo.localPath()}, gitCommand...)...)
}

func (repo *Repository) executeGitCommand(gitCommand ...string) (b []byte, e error) {
	cmd := repo.createGitCommand(gitCommand...)
	b, e = cmd.CombinedOutput()
	if e != nil {
		repo.Printf("ERROR: %s (%v)", strings.TrimSpace(string(b)), cmd)
		return b, e
	}
	return b, nil
}

func (repo *Repository) MostRecentCommitFor(pattern string) (commit string, e error) {
	commits, e := repo.Commits(&CommitOptions{Limit: 1, Pattern: pattern})
	if e != nil {
		return "", e
	}
	if len(commits) == 0 {
		return "", e
	}
	return commits[0].Checksum, nil
}

var validTar = regexp.MustCompile("^([0-9a-f]{40})$")

// Writes tgz archive to the given tar writer.
func (repo *Repository) WriteArchiveToTar(revision string, w *tar.Writer) (e error) {
	if !validTar.MatchString(revision) {
		return fmt.Errorf("revision %q not valid (must be 40 digit git sha)", revision)
	}

	mtime, e := repo.DateOf(revision, ".")
	if e != nil {
		return e
	}

	e = repo.addArchiveToTar(revision, mtime, w)
	if e != nil {
		return e
	}

	return addFileToArchive("REVISION", []byte(revision), mtime, w)
}

func (repo *Repository) WriteFilesToTar(revision string, w *tar.Writer, files ...string) (e error) {
	if len(files) == 0 {
		return fmt.Errorf("empty file list given")
	}

	if !validTar.MatchString(revision) {
		return fmt.Errorf("revision %q not valid (must be 40 digit git sha)", revision)
	}

	for _, file := range files {
		mtime, e := repo.DateOf(revision, file)
		if e != nil {
			return e
		}

		buf, e := repo.getFileAtRevision(revision, file)
		if e != nil {
			return e
		}

		if e = addFileToArchive(file, buf, mtime, w); e != nil {
			return e
		}
	}

	return nil
}

func (repo *Repository) getFileAtRevision(revision, file string) (content []byte, e error) {
	buf := bytes.NewBuffer(nil)

	cmd := repo.createGitCommand("show", revision+":"+file)
	cmd.Stdout = buf

	if e = cmd.Run(); e != nil {
		return nil, e
	}

	return buf.Bytes(), nil
}

func addFileToArchive(name string, content []byte, modTime time.Time, w *tar.Writer) error {
	e := w.WriteHeader(&tar.Header{Name: name, Size: int64(len(content)), ModTime: modTime, Mode: 0644})
	if e != nil {
		return e
	}
	_, e = w.Write(content)
	return e
}

// write tar.gz archive to writer
func (repo *Repository) Archive(revision string, w io.Writer, files ...string) (int64, error) {
	if err := repo.Init(); err != nil {
		return 0, err
	}
	args := append([]string{"archive", "--format=tar.gz", revision}, files...)
	cmd := repo.createGitCommand(args...)
	stderr := &bytes.Buffer{}
	cmd.Stderr = stderr
	cnt := &counter{}
	cmd.Stdout = io.MultiWriter(w, cnt)
	if err := cmd.Run(); err != nil {
		return 0, fmt.Errorf("%s: %s", err, stderr.String())
	}
	return cnt.cnt, nil
}

type counter struct {
	cnt int64
}

func (c *counter) Write(b []byte) (int, error) {
	c.cnt += int64(len(b))
	return len(b), nil

}

func (repo *Repository) addArchiveToTar(revision string, mtime time.Time, w *tar.Writer) (e error) {
	filename := repo.Name() + ".tar.gz"

	buf := &bytes.Buffer{}

	if _, err := repo.Archive(revision, buf); err != nil {
		return err
	}

	e = w.WriteHeader(&tar.Header{Name: filename, Size: int64(buf.Len()), ModTime: mtime, Mode: 0644})
	if e != nil {
		return e
	}
	_, err := io.Copy(w, buf)
	return err
}

func (repo *Repository) Name() string {
	return strings.TrimSuffix(filepath.Base(repo.Origin), ".git")
}

func (repo *Repository) DateOf(revision, file string) (time.Time, error) {
	b, e := repo.executeGitCommand("log", "-1", "--format='%ct'", revision, "--", file)
	if e != nil {
		return time.Now(), e
	}
	d, e := strconv.Atoi(strings.Trim(string(b), "'\n"))
	if e != nil {
		return time.Now(), e
	}

	return time.Unix(int64(d), 0), nil
}

func (repo *Repository) localPath() string {
	if repo.LocalPath == "" {
		name := repo.Name()
		if strings.HasPrefix(repo.Origin, githubPrefix) {
			name = strings.TrimPrefix(repo.Origin, githubPrefix)
			repo.LocalPath = repo.cacheDir() + "/github.com/" + name
		} else {
			repo.LocalPath = repo.cacheDir() + "/" + repo.Name()
		}
	}
	return repo.LocalPath
}

func (repo *Repository) Commits(options *CommitOptions) (commits []*Commit, e error) {
	if options == nil {
		options = &CommitOptions{Limit: 10}
	}

	parts := []string{"log", "-n", strconv.Itoa(options.Limit), "--pretty=format:%H\t%at\t%s"}
	if options.Pattern != "" {
		parts = append(parts, options.Pattern)
	}
	b, e := repo.executeGitCommand(parts...)
	if e != nil {
		return nil, e
	}
	lines := strings.Split(string(b), "\n")
	commits = make([]*Commit, 0, len(lines))

	for _, line := range lines {
		parts := strings.SplitN(line, "\t", 3)
		if len(parts) == 3 {
			if t, e := strconv.ParseInt(parts[1], 10, 64); e == nil {
				commits = append(commits, &Commit{Checksum: parts[0], AuthorDate: time.Unix(t, 0), Message: parts[2]})
			} else {
				repo.Printf("ERROR: %s", e.Error())
			}
		}
	}
	return commits, nil
}

func fileExists(path string) bool {
	_, err := os.Stat(path)
	return err == nil || !os.IsNotExist(err)
}
<|endoftext|>


<commit_before>package udata

//-----------------------------------------------------------------------------
// Import statements:
//-----------------------------------------------------------------------------

import (
	"sort"
	"strconv"
)

//-----------------------------------------------------------------------------
// Typedefs:
//-----------------------------------------------------------------------------

type service struct {
	name   string
	roles  []string
	groups []string
	ports  []portRange
}

type portRange struct {
	from, to int
	protocol string
	ingress  string
}

type serviceMap map[string]service

//-----------------------------------------------------------------------------
// func: findOne
//-----------------------------------------------------------------------------

func findOne(src, dst []string) bool {
	for _, i := range src {
		for _, j := range dst {
			if i == j {
				return true
			}
		}
	}
	return false
}

//-----------------------------------------------------------------------------
// func: listUnits
//-----------------------------------------------------------------------------

func (s *serviceMap) listUnits() (list []string) {

	// Map as set:
	m := map[string]struct{}{}
	for _, service := range *s {
		m[service.name] = struct{}{}
	}

	// Set to slice:
	for k := range m {
		list = append(list, k)
	}

	// Sort and return:
	sort.Strings(list)
	return
}

//-----------------------------------------------------------------------------
// func: listPorts
//-----------------------------------------------------------------------------

func (s *serviceMap) listPorts(protocol string) (list []string) {

	// Port range map:
	portRange := map[string]struct{ from, to int }{}
	for _, service := range *s {
		for _, port := range service.ports {
			if port.protocol == protocol && port.to != 0 {
				from := strconv.Itoa(port.from)
				to := strconv.Itoa(port.to)
				portRange[from+":"+to] = struct{ from, to int }{
					from: port.from, to: port.to,
				}
			}
		}
	}

	// Single port map:
	singlePort := map[int]struct{}{}
	for _, service := range *s {
	next:
		for _, port := range service.ports {
			if port.protocol == protocol && port.to == 0 {
				for _, r := range portRange {
					if port.from >= r.from && port.from <= r.to {
						continue next
					}
				}
				singlePort[port.from] = struct{}{}
			}
		}
	}

	// Append to list:
	for k := range portRange {
		list = append(list, k)
	}
	for k := range singlePort {
		list = append(list, strconv.Itoa(k))
	}

	return
}

//-----------------------------------------------------------------------------
// func: load
//-----------------------------------------------------------------------------

func (s *serviceMap) load(roles, groups []string) {

	// Map roles to services:
	roleServices := map[string][]string{

		"quorum": {
			"docker", "rexray", "etchost", "zookeeper", "etcd-master", "rkt-api",
			"cadvisor", "node-exporter", "zookeeper-exporter"},

		"master": {
			"docker", "rexray", "etchost", "etcd-proxy", "calico", "mesos-dns",
			"mesos-master", "marathon", "rkt-api", "cadvisor", "node-exporter",
			"mesos-master-exporter", "confd", "alertmanager", "prometheus"},

		"worker": {
			"docker", "rexray", "etchost", "etcd-proxy", "calico", "go-dnsmasq",
			"marathon-lb", "mesos-agent", "rkt-api", "cadvisor", "node-exporter",
			"mesos-agent-exporter", "haproxy-exporter"},

		"border": {
			"docker", "rexray", "etchost", "etcd-proxy", "calico", "mongodb",
			"pritunl", "rkt-api", "cadvisor", "node-exporter"},
	}

	// Map services to config:
	serviceConfig := map[string]service{

		"docker": {
			name:   "docker.service",
			groups: []string{"base"},
			ports: []portRange{
				{from: 2375, protocol: "tcp", ingress: ""},
			},
		},

		"rexray": {
			name:   "rexray.service",
			groups: []string{"base"},
			ports: []portRange{
				{from: 7979, protocol: "tcp", ingress: ""},
			},
		},

		"etchost": {
			name:   "etchost.timer",
			groups: []string{"base"},
			ports: []portRange{
				{from: 22, protocol: "tcp", ingress: ""},
			},
		},

		"etcd-proxy": {
			name:   "etcd2.service",
			groups: []string{"base"},
			ports: []portRange{
				{from: 2379, protocol: "tcp", ingress: ""},
			},
		},

		"calico": {
			name:   "calico.service",
			groups: []string{"base"},
			ports: []portRange{
				{from: 179, protocol: "tcp", ingress: ""},
			},
		},

		"zookeeper": {
			name:   "zookeeper.service",
			groups: []string{"base"},
			ports: []portRange{
				{from: 2181, protocol: "tcp", ingress: ""},
				{from: 2888, protocol: "tcp", ingress: ""},
				{from: 3888, protocol: "tcp", ingress: ""},
			},
		},

		"etcd-master": {
			name:   "etcd2.service",
			groups: []string{"base"},
			ports: []portRange{
				{from: 2379, to: 2380, protocol: "tcp", ingress: ""},
			},
		},

		"mesos-dns": {
			name:   "mesos-dns.service",
			groups: []string{"base"},
			ports: []portRange{
				{from: 53, to: 54, protocol: "tcp", ingress: ""},
				{from: 53, to: 54, protocol: "udp", ingress: ""},
			},
		},

		"mesos-master": {
			name:   "mesos-master.service",
			groups: []string{"base"},
			ports: []portRange{
				{from: 5050, protocol: "tcp", ingress: ""},
			},
		},

		"marathon": {
			name:   "marathon.service",
			groups: []string{"base"},
			ports: []portRange{
				{from: 8080, protocol: "tcp", ingress: ""},
				{from: 9292, protocol: "tcp", ingress: ""},
			},
		},

		"go-dnsmasq": {
			name:   "go-dnsmasq.service",
			groups: []string{"base"},
			ports: []portRange{
				{from: 53, protocol: "tcp", ingress: ""},
			},
		},

		"marathon-lb": {
			name:   "marathon-lb.service",
			groups: []string{"base"},
			ports: []portRange{
				{from: 80, protocol: "tcp", ingress: ""},
				{from: 443, protocol: "tcp", ingress: ""},
				{from: 9090, to: 9091, protocol: "tcp", ingress: ""},
				{from: 10000, to: 10100, protocol: "tcp", ingress: ""},
			},
		},

		"mesos-agent": {
			name:   "mesos-agent.service",
			groups: []string{"base"},
			ports: []portRange{
				{from: 5051, protocol: "tcp", ingress: ""},
			},
		},

		"mongodb": {
			name:   "mongodb.service",
			groups: []string{"base"},
			ports: []portRange{
				{from: 27017, protocol: "tcp", ingress: ""},
			},
		},

		"pritunl": {
			name:   "pritunl.service",
			groups: []string{"base"},
			ports: []portRange{
				{from: 80, protocol: "tcp", ingress: ""},
				{from: 443, protocol: "tcp", ingress: ""},
				{from: 9756, protocol: "tcp", ingress: ""},
				{from: 18443, protocol: "udp", ingress: ""},
			},
		},

		"rkt-api": {
			name:   "rkt-api.service",
			groups: []string{"insight"},
		},

		"cadvisor": {
			name:   "cadvisor.service",
			groups: []string{"insight"},
			ports: []portRange{
				{from: 4194, protocol: "tcp", ingress: ""},
			},
		},

		"node-exporter": {
			name:   "node-exporter.service",
			groups: []string{"insight"},
			ports: []portRange{
				{from: 9101, protocol: "tcp", ingress: ""},
			},
		},

		"zookeeper-exporter": {
			name:   "zookeeper-exporter.service",
			groups: []string{"insight"},
			ports: []portRange{
				{from: 9103, protocol: "tcp", ingress: ""},
			},
		},

		"mesos-master-exporter": {
			name:   "mesos-master-exporter.service",
			groups: []string{"insight"},
			ports: []portRange{
				{from: 9104, protocol: "tcp", ingress: ""},
			},
		},

		"mesos-agent-exporter": {
			name:   "mesos-agent-exporter.service",
			groups: []string{"insight"},
			ports: []portRange{
				{from: 9105, protocol: "tcp", ingress: ""},
			},
		},

		"haproxy-exporter": {
			name:   "haproxy-exporter.service",
			groups: []string{"insight"},
			ports: []portRange{
				{from: 9102, protocol: "tcp", ingress: ""},
			},
		},

		"confd": {
			name:   "confd.service",
			groups: []string{"insight"},
		},

		"alertmanager": {
			name:   "alertmanager.service",
			groups: []string{"insight"},
			ports: []portRange{
				{from: 9093, protocol: "tcp", ingress: ""},
			},
		},

		"prometheus": {
			name:   "prometheus.service",
			groups: []string{"insight"},
			ports: []portRange{
				{from: 9191, protocol: "tcp", ingress: ""},
			},
		},
	}

	// Filter my services:
	*s = serviceMap{}
	for _, role := range roles {
		for _, service := range roleServices[role] {
			if findOne(serviceConfig[service].groups, groups) {
				(*s)[service] = serviceConfig[service]
			}
		}
	}
}
<commit_msg>O(n Log n) time complexity and O(1) extra space<commit_after>package udata

//-----------------------------------------------------------------------------
// Import statements:
//-----------------------------------------------------------------------------

import (
	"sort"
	"strconv"
)

//-----------------------------------------------------------------------------
// Typedefs:
//-----------------------------------------------------------------------------

type service struct {
	name   string
	roles  []string
	groups []string
	ports  []portRange
}

type portRange struct {
	interval startEnd
	protocol string
	ingress  string
}

type startEnd struct {
	start, end int
}

type serviceMap map[string]service

//-----------------------------------------------------------------------------
// Custom sort:
//-----------------------------------------------------------------------------

type byStart []startEnd

func (a byStart) Len() int {
	return len(a)
}

func (a byStart) Swap(i, j int) {
	a[i], a[j] = a[j], a[i]
}

func (a byStart) Less(i, j int) bool {
	return a[i].start > a[j].start
}

//-----------------------------------------------------------------------------
// func: findOne
//-----------------------------------------------------------------------------

func findOne(src, dst []string) bool {
	for _, i := range src {
		for _, j := range dst {
			if i == j {
				return true
			}
		}
	}
	return false
}

//-----------------------------------------------------------------------------
// func: listUnits
//-----------------------------------------------------------------------------

func (s *serviceMap) listUnits() (list []string) {

	// Map as set:
	m := map[string]struct{}{}
	for _, service := range *s {
		m[service.name] = struct{}{}
	}

	// Set to slice:
	for k := range m {
		list = append(list, k)
	}

	// Sort and return:
	sort.Strings(list)
	return
}

//-----------------------------------------------------------------------------
// func: min, max
//-----------------------------------------------------------------------------

func min(x, y int) int {
	if x < y {
		return x
	}
	return y
}

func max(x, y int) int {
	if x > y {
		return x
	}
	return y
}

//-----------------------------------------------------------------------------
// func: listPorts
//-----------------------------------------------------------------------------

func (s *serviceMap) listPorts(protocol string) (list []string) {

	// Initialize the intervals:
	arr := []startEnd{}
	for _, service := range *s {
		for _, port := range service.ports {
			if port.protocol == protocol {
				arr = append(arr, port.interval)
			}
		}
	}

	// Sort the intervals array:
	sort.Sort(byStart(arr))
	i := 0

	// Merge the intervals:
	for _, v := range arr {

		// Overlap
		if i != 0 && arr[i-1].start <= v.end {
			for i != 0 && arr[i-1].start <= v.end {
				arr[i-1].end = max(arr[i-1].end, v.end)
				arr[i-1].start = min(arr[i-1].start, v.start)
				i--
			}

			// Adjacent
		} else if i != 0 && arr[i-1].end == v.start+1 {
			arr[i-1].start = v.start
			arr[i-1].end = max(arr[i-1].end, v.end)
			i--

			// Outlying
		} else {
			arr[i] = v
		}

		i++
	}

	// Append to the list:
	for j := 0; j < i; j++ {
		if arr[j].start == arr[j].end {
			list = append(list, strconv.Itoa(arr[j].start))
		} else {
			list = append(list,
				strconv.Itoa(arr[j].start)+":"+strconv.Itoa(arr[j].end))
		}
	}

	return
}

//-----------------------------------------------------------------------------
// func: load
//-----------------------------------------------------------------------------

func (s *serviceMap) load(roles, groups []string) {

	// Map roles to services:
	roleServices := map[string][]string{

		"quorum": {
			"docker", "rexray", "etchost", "zookeeper", "etcd-master", "rkt-api",
			"cadvisor", "node-exporter", "zookeeper-exporter"},

		"master": {
			"docker", "rexray", "etchost", "etcd-proxy", "calico", "mesos-dns",
			"mesos-master", "marathon", "rkt-api", "cadvisor", "node-exporter",
			"mesos-master-exporter", "confd", "alertmanager", "prometheus"},

		"worker": {
			"docker", "rexray", "etchost", "etcd-proxy", "calico", "go-dnsmasq",
			"marathon-lb", "mesos-agent", "rkt-api", "cadvisor", "node-exporter",
			"mesos-agent-exporter", "haproxy-exporter"},

		"border": {
			"docker", "rexray", "etchost", "etcd-proxy", "calico", "mongodb",
			"pritunl", "rkt-api", "cadvisor", "node-exporter"},
	}

	// Map services to config:
	serviceConfig := map[string]service{

		"docker": {
			name:   "docker.service",
			groups: []string{"base"},
			ports: []portRange{
				{interval: startEnd{2375, 2375}, protocol: "tcp", ingress: ""},
			},
		},

		"rexray": {
			name:   "rexray.service",
			groups: []string{"base"},
			ports: []portRange{
				{interval: startEnd{7979, 7979}, protocol: "tcp", ingress: ""},
			},
		},

		"etchost": {
			name:   "etchost.timer",
			groups: []string{"base"},
			ports: []portRange{
				{interval: startEnd{22, 22}, protocol: "tcp", ingress: ""},
			},
		},

		"etcd-proxy": {
			name:   "etcd2.service",
			groups: []string{"base"},
			ports: []portRange{
				{interval: startEnd{2379, 2379}, protocol: "tcp", ingress: ""},
			},
		},

		"calico": {
			name:   "calico.service",
			groups: []string{"base"},
			ports: []portRange{
				{interval: startEnd{179, 179}, protocol: "tcp", ingress: ""},
			},
		},

		"zookeeper": {
			name:   "zookeeper.service",
			groups: []string{"base"},
			ports: []portRange{
				{interval: startEnd{2181, 2181}, protocol: "tcp", ingress: ""},
				{interval: startEnd{2888, 2888}, protocol: "tcp", ingress: ""},
				{interval: startEnd{3888, 3888}, protocol: "tcp", ingress: ""},
			},
		},

		"etcd-master": {
			name:   "etcd2.service",
			groups: []string{"base"},
			ports: []portRange{
				{interval: startEnd{2379, 2380}, protocol: "tcp", ingress: ""},
			},
		},

		"mesos-dns": {
			name:   "mesos-dns.service",
			groups: []string{"base"},
			ports: []portRange{
				{interval: startEnd{53, 54}, protocol: "tcp", ingress: ""},
				{interval: startEnd{53, 54}, protocol: "udp", ingress: ""},
			},
		},

		"mesos-master": {
			name:   "mesos-master.service",
			groups: []string{"base"},
			ports: []portRange{
				{interval: startEnd{5050, 5050}, protocol: "tcp", ingress: ""},
			},
		},

		"marathon": {
			name:   "marathon.service",
			groups: []string{"base"},
			ports: []portRange{
				{interval: startEnd{8080, 8080}, protocol: "tcp", ingress: ""},
				{interval: startEnd{9292, 9292}, protocol: "tcp", ingress: ""},
			},
		},

		"go-dnsmasq": {
			name:   "go-dnsmasq.service",
			groups: []string{"base"},
			ports: []portRange{
				{interval: startEnd{53, 53}, protocol: "tcp", ingress: ""},
			},
		},

		"marathon-lb": {
			name:   "marathon-lb.service",
			groups: []string{"base"},
			ports: []portRange{
				{interval: startEnd{80, 80}, protocol: "tcp", ingress: ""},
				{interval: startEnd{443, 443}, protocol: "tcp", ingress: ""},
				{interval: startEnd{9090, 9091}, protocol: "tcp", ingress: ""},
				{interval: startEnd{10000, 10100}, protocol: "tcp", ingress: ""},
			},
		},

		"mesos-agent": {
			name:   "mesos-agent.service",
			groups: []string{"base"},
			ports: []portRange{
				{interval: startEnd{5051, 5051}, protocol: "tcp", ingress: ""},
			},
		},

		"mongodb": {
			name:   "mongodb.service",
			groups: []string{"base"},
			ports: []portRange{
				{interval: startEnd{27017, 27017}, protocol: "tcp", ingress: ""},
			},
		},

		"pritunl": {
			name:   "pritunl.service",
			groups: []string{"base"},
			ports: []portRange{
				{interval: startEnd{80, 80}, protocol: "tcp", ingress: ""},
				{interval: startEnd{443, 443}, protocol: "tcp", ingress: ""},
				{interval: startEnd{9756, 9756}, protocol: "tcp", ingress: ""},
				{interval: startEnd{18443, 18443}, protocol: "udp", ingress: ""},
			},
		},

		"rkt-api": {
			name:   "rkt-api.service",
			groups: []string{"insight"},
		},

		"cadvisor": {
			name:   "cadvisor.service",
			groups: []string{"insight"},
			ports: []portRange{
				{interval: startEnd{4194, 4194}, protocol: "tcp", ingress: ""},
			},
		},

		"node-exporter": {
			name:   "node-exporter.service",
			groups: []string{"insight"},
			ports: []portRange{
				{interval: startEnd{9101, 9101}, protocol: "tcp", ingress: ""},
			},
		},

		"zookeeper-exporter": {
			name:   "zookeeper-exporter.service",
			groups: []string{"insight"},
			ports: []portRange{
				{interval: startEnd{9103, 9103}, protocol: "tcp", ingress: ""},
			},
		},

		"mesos-master-exporter": {
			name:   "mesos-master-exporter.service",
			groups: []string{"insight"},
			ports: []portRange{
				{interval: startEnd{9104, 9104}, protocol: "tcp", ingress: ""},
			},
		},

		"mesos-agent-exporter": {
			name:   "mesos-agent-exporter.service",
			groups: []string{"insight"},
			ports: []portRange{
				{interval: startEnd{9105, 9105}, protocol: "tcp", ingress: ""},
			},
		},

		"haproxy-exporter": {
			name:   "haproxy-exporter.service",
			groups: []string{"insight"},
			ports: []portRange{
				{interval: startEnd{9102, 9102}, protocol: "tcp", ingress: ""},
			},
		},

		"confd": {
			name:   "confd.service",
			groups: []string{"insight"},
		},

		"alertmanager": {
			name:   "alertmanager.service",
			groups: []string{"insight"},
			ports: []portRange{
				{interval: startEnd{9093, 9093}, protocol: "tcp", ingress: ""},
			},
		},

		"prometheus": {
			name:   "prometheus.service",
			groups: []string{"insight"},
			ports: []portRange{
				{interval: startEnd{9191, 9191}, protocol: "tcp", ingress: ""},
			},
		},
	}

	// Filter my services:
	*s = serviceMap{}
	for _, role := range roles {
		for _, service := range roleServices[role] {
			if findOne(serviceConfig[service].groups, groups) {
				(*s)[service] = serviceConfig[service]
			}
		}
	}
}
<|endoftext|>


<commit_before>package controller

import (
	"sync"
	"sync/atomic"
	"time"
)

type aint struct{ v int64 }

func (a *aint) add(d int) int {
	return int(atomic.AddInt64(&a.v, int64(d)))
}
func (a *aint) get() int {
	return int(atomic.LoadInt64(&a.v))
}
func (a *aint) set(i int) int {
	return int(atomic.SwapInt64(&a.v, int64(i)))
}

type abool struct{ v int64 }

func (a *abool) on() bool {
	return atomic.LoadInt64(&a.v) != 0
}
func (a *abool) set(t bool) bool {
	if t {
		return atomic.SwapInt64(&a.v, 1) != 0
	}
	return atomic.SwapInt64(&a.v, 0) != 0
}

type astring struct {
	mu sync.Mutex
	v  string
}

func (a *astring) get() string {
	a.mu.Lock()
	p := a.v
	a.mu.Unlock()
	return p
}
func (a *astring) set(s string) string {
	a.mu.Lock()
	p := a.v
	a.v = s
	a.mu.Unlock()
	return p
}

type atime struct {
	mu sync.Mutex
	v  time.Time
}

func (a *atime) get() time.Time {
	a.mu.Lock()
	p := a.v
	a.mu.Unlock()
	return p
}
func (a *atime) set(t time.Time) time.Time {
	a.mu.Lock()
	p := a.v
	a.v = t
	a.mu.Unlock()
	return p
}
<commit_msg>safe atomic ints for rpi3, #269<commit_after>package controller

import (
	"sync"
	"sync/atomic"
	"time"
)

type aint struct{ v uintptr }

func (a *aint) add(d int) int {
	if d < 0 {
		return int(atomic.AddUintptr(&a.v, ^uintptr(d-1)))
	}
	return int(atomic.AddUintptr(&a.v, uintptr(d)))
}
func (a *aint) get() int {
	return int(atomic.LoadUintptr(&a.v))
}
func (a *aint) set(i int) int {
	return int(atomic.SwapUintptr(&a.v, uintptr(i)))
}

type abool struct{ v uint32 }

func (a *abool) on() bool {
	return atomic.LoadUint32(&a.v) != 0
}
func (a *abool) set(t bool) bool {
	if t {
		return atomic.SwapUint32(&a.v, 1) != 0
	}
	return atomic.SwapUint32(&a.v, 0) != 0
}

type astring struct {
	mu sync.Mutex
	v  string
}

func (a *astring) get() string {
	a.mu.Lock()
	p := a.v
	a.mu.Unlock()
	return p
}
func (a *astring) set(s string) string {
	a.mu.Lock()
	p := a.v
	a.v = s
	a.mu.Unlock()
	return p
}

type atime struct {
	mu sync.Mutex
	v  time.Time
}

func (a *atime) get() time.Time {
	a.mu.Lock()
	p := a.v
	a.mu.Unlock()
	return p
}
func (a *atime) set(t time.Time) time.Time {
	a.mu.Lock()
	p := a.v
	a.v = t
	a.mu.Unlock()
	return p
}
<|endoftext|>


<commit_before>// Copyright 2014 Brady Catherman
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package testlib

import (
	"fmt"
	"reflect"
	"strings"
)

// This file contains a super utility for checking the equality of structures
// or values. It is designed to compare anything to basically anything.

// Compares two values to ensure that they are equal to each other. This will
// deep inspect both values to ensure that the full structure tree is equal.
// It also walks through pointers ensuring that everything is equal.
func (t *T) Equal(have, want interface{}, desc ...string) {
	prefix := ""
	if len(desc) > 0 {
		prefix = strings.Join(desc, " ") + ": "
	}

	// Check to see if either value is nil and then verify that the are
	// either both nil, or fail if one is nil.
	haveNil := t.isNil(have)
	wantNil := t.isNil(want)
	if haveNil && wantNil {
		return
	} else if haveNil && !wantNil {
		t.Fatalf("%sExpected non nil, got nil.", prefix)
	} else if !haveNil && wantNil {
		t.Fatalf("%sExpected nil, got non nil.", prefix)
	}

	// Next we need to get the value of both objects so we can compare them.
	haveValue := reflect.ValueOf(have)
	wantValue := reflect.ValueOf(want)
	visited := make(map[uintptr]*visitedNode)
	reason := t.deepEqual("", haveValue, wantValue, visited)
	if len(reason) > 0 {
		t.Fatalf("%sNot Equal\n%s", prefix, strings.Join(reason, "\n"))
	}
}

// Like Equal() except that it asserts that the two values are not equal
// to each other.
func (t *T) NotEqual(have, want interface{}, desc ...string) {
	prefix := ""
	if len(desc) > 0 {
		prefix = strings.Join(desc, " ") + ": "
	}

	// Check to see if either value is nil and then verify that the are
	// either both nil, or fail if one is nil.
	haveNil := t.isNil(have)
	wantNil := t.isNil(want)
	if haveNil && wantNil {
		t.Fatalf("%sEquality not expected, have=nil", prefix)
	} else if haveNil || wantNil {
		return
	}

	// Next we need to get the value of both objects so we can compare them.
	haveValue := reflect.ValueOf(have)
	wantValue := reflect.ValueOf(want)
	visited := make(map[uintptr]*visitedNode)
	reason := t.deepEqual("", haveValue, wantValue, visited)
	if len(reason) == 0 {
		t.Fatalf("%sValues are not expected to be equal: %#v", prefix, have)
	}
}

// Tracks access to specific pointers so we do not recurse.
type visitedNode struct {
	a1   uintptr
	a2   uintptr
	typ  reflect.Type
	next *visitedNode
}

// Returns true if the underlying object is nil.
func (t *T) isNil(obj interface{}) bool {
	if obj == nil {
		return true
	}
	v := reflect.ValueOf(obj)
	switch v.Kind() {
	case reflect.Func:
	case reflect.Map:
	case reflect.Ptr:
	case reflect.Slice:
	default:
		return false
	}
	return v.IsNil()
}

// Deep comparison. This is based on golang 1.2's reflect.Equal functionality.
func (t *T) deepEqual(
	desc string, have, want reflect.Value, visited map[uintptr]*visitedNode,
) (diffs []string) {
	if !want.IsValid() && !have.IsValid() {
		return nil
	} else if !want.IsValid() && have.IsValid() {
		// This is rare, not sure how to document this better.
		return []string{
			fmt.Sprintf("%s: have invalid or nil object.", desc),
		}
	} else if want.IsValid() && !have.IsValid() {
		// This is rare, not sure how to document this better.
		return []string{
			fmt.Sprintf("%s: wanted a valid, non nil object.", desc),
		}
	} else if want.Type() != have.Type() {
		return []string{fmt.Sprintf(
			"%s: Not the same type have: '%s', want: '%s'",
			desc, have.Type(), want.Type())}
	}

	if want.CanAddr() && have.CanAddr() {
		addr1 := want.UnsafeAddr()
		addr2 := have.UnsafeAddr()
		if addr1 > addr2 {
			// Canonicalize order to reduce number of entries in visited.
			addr1, addr2 = addr2, addr1
		}

		// Short circuit if references are identical ...
		if addr1 == addr2 {
			return []string{}
		}

		// ... or already seen
		h := 17*addr1 + addr2
		seen := visited[h]
		typ := want.Type()
		for p := seen; p != nil; p = p.next {
			if p.a1 == addr1 && p.a2 == addr2 && p.typ == typ {
				return []string{}
			}
		}

		// Remember for later.
		visited[h] = &visitedNode{addr1, addr2, typ, seen}
	}

	// Checks to see if one value is nil, while the other is not.
	checkNil := func() bool {
		if want.IsNil() && !have.IsNil() {
			diffs = append(diffs, fmt.Sprintf("%s: not equal.", desc))
			diffs = append(diffs, fmt.Sprintf("  have: %#v", have.Interface()))
			diffs = append(diffs, "  wantA: nil")
			return true
		} else if !want.IsNil() && have.IsNil() {
			diffs = append(diffs, fmt.Sprintf("%s: not equal.", desc))
			diffs = append(diffs, "  have: nil")
			diffs = append(diffs, fmt.Sprintf("  wantB: %#v", want.Interface()))
			return true
		}
		return false
	}

	// Checks to see that the lengths of both objects are equal.
	checkLen := func() bool {
		if want.Len() != have.Len() {
			diffs = append(diffs, fmt.Sprintf(
				"%s: (len(have): %d, len(want): %d)",
				desc, have.Len(), want.Len()))
			diffs = append(diffs, fmt.Sprintf("  have: %#v", have.Interface()))
			diffs = append(diffs, fmt.Sprintf("  want: %#v", want.Interface()))
			return true
		}
		return false
	}

	switch want.Kind() {
	case reflect.Array:
		if !checkLen() {
			for i := 0; i < want.Len(); i++ {
				newdiffs := t.deepEqual(
					fmt.Sprintf("%s[%d]", desc, i),
					want.Index(i), have.Index(i), visited)
				diffs = append(diffs, newdiffs...)
			}
		}

	case reflect.Chan:
		// Channels are complex to compare so we rely on the existing type
		// checks to assert correctness, and then we add an additional
		// capacity check to assert buffer size.
		hcap := have.Cap()
		wcap := want.Cap()
		if hcap != wcap {
			diffs = append(diffs, fmt.Sprintf(
				"%sCapacities differ:\n  have: %d\n  want: %d",
				desc, hcap, wcap))
			return diffs
		}

	case reflect.Func:
		// Can't do better than this:
		checkNil()

	case reflect.Interface:
		if !checkNil() {
			newdiffs := t.deepEqual(
				desc, want.Elem(), have.Elem(), visited)
			diffs = append(diffs, newdiffs...)
		}

	case reflect.Map:
		if !checkNil() {
			// Check that the keys are present in both maps.
			for _, k := range want.MapKeys() {
				if !have.MapIndex(k).IsValid() {
					// Add the error.
					diffs = append(diffs, fmt.Sprintf(
						"%sExpected key [%q] is missing.", desc, k))
					diffs = append(diffs, "  have: not present")
					diffs = append(diffs, fmt.Sprintf("  want: %#v",
						want.MapIndex(k)))
					continue
				}
				newdiffs := t.deepEqual(
					fmt.Sprintf("%s[%q] ", desc, k),
					want.MapIndex(k), have.MapIndex(k), visited)
				diffs = append(diffs, newdiffs...)
			}
			for _, k := range have.MapKeys() {
				if !want.MapIndex(k).IsValid() {
					// Add the error.
					diffs = append(diffs, fmt.Sprintf(
						"%sUnexpected key [%q].", desc, k))
					diffs = append(diffs,
						fmt.Sprintf("  have: %#v", have.MapIndex(k)))
					diffs = append(diffs, "  want: not present")
				}
			}
		}

	case reflect.Ptr:
		newdiffs := t.deepEqual(
			desc, want.Elem(), have.Elem(), visited)
		diffs = append(diffs, newdiffs...)

	case reflect.Slice:
		if !checkNil() && !checkLen() {
			for i := 0; i < want.Len(); i++ {
				newdiffs := t.deepEqual(
					fmt.Sprintf("%s[%d]", desc, i),
					want.Index(i), have.Index(i), visited)
				diffs = append(diffs, newdiffs...)
			}
		}

	case reflect.String:
		// We know the underlying type is a string so calling String()
		// will return the underlying value. Trying to call Interface()
		// and assert to a string will panic.
		hstr := have.String()
		wstr := want.String()
		if len(hstr) != len(wstr) {
			return []string{
				fmt.Sprintf("%s: len(have) %d != len(want) %d.",
					desc, len(hstr), len(wstr)),
				fmt.Sprintf("  have: %#v", hstr),
				fmt.Sprintf("  want: %#v", wstr),
			}
		}
		for i := range hstr {
			if hstr[i] != wstr[i] {
				return []string{
					fmt.Sprintf("%s: difference at index %d.", desc, i),
					fmt.Sprintf("  have: %#v", hstr),
					fmt.Sprintf("  want: %#v", wstr),
				}
			}
		}

	case reflect.Struct:
		for i, n := 0, want.NumField(); i < n; i++ {
			name := want.Type().Field(i).Name
			// Make sure that we don't print a strange error if the
			// first object given to us is a struct.
			if desc == "" {
				newdiffs := t.deepEqual(
					name, want.Field(i), have.Field(i), visited)
				diffs = append(diffs, newdiffs...)
			} else {
				newdiffs := t.deepEqual(
					fmt.Sprintf("%s.%s", desc, name),
					want.Field(i), have.Field(i), visited)
				diffs = append(diffs, newdiffs...)
			}
		}

	case reflect.Uintptr:
		// Uintptr's work like UnsafePointers. We can't evaluate them or
		// do much with them so we have to cast them into a number and
		// compare them that way.
		havePtr := have.Uint()
		wantPtr := want.Uint()
		if havePtr != wantPtr {
			return []string{
				fmt.Sprintf("%s: not equal.", desc),
				fmt.Sprintf("  have: %#v", havePtr),
				fmt.Sprintf("  wantX: %#v", wantPtr),
			}
		}

	case reflect.UnsafePointer:
		// Unsafe pointers can cause us problems as they fall ill of the
		// Interface() restrictions. As such we have to special case them
		// and cast them as integers.
		havePtr := have.Pointer()
		wantPtr := want.Pointer()
		if havePtr != wantPtr {
			return []string{
				fmt.Sprintf("%s: not equal.", desc),
				fmt.Sprintf("  have: %#v", havePtr),
				fmt.Sprintf("  wantY: %#v", wantPtr),
			}
		}

	case reflect.Bool:
		haveBool := have.Bool()
		wantBool := want.Bool()
		if haveBool != wantBool {
			return []string{
				fmt.Sprintf("%s: not equal.", desc),
				fmt.Sprintf("  have: bool(%t)\n", haveBool),
				fmt.Sprintf("  want: bool(%t)\n", wantBool),
			}
		}

	case reflect.Int:
		fallthrough
	case reflect.Int8:
		fallthrough
	case reflect.Int16:
		fallthrough
	case reflect.Int32:
		fallthrough
	case reflect.Int64:
		// Basic integer types.
		haveInt := have.Int()
		wantInt := want.Int()
		if haveInt != wantInt {
			return []string{
				fmt.Sprintf("%s: not equal", desc),
				fmt.Sprintf("  have: %s(%d)\n", have.Type(), haveInt),
				fmt.Sprintf("  want: %s(%d)\n", want.Type(), wantInt),
			}
		}

	case reflect.Uint:
		fallthrough
	case reflect.Uint8:
		fallthrough
	case reflect.Uint16:
		fallthrough
	case reflect.Uint32:
		fallthrough
	case reflect.Uint64:
		// Basic unsigned integer types.
		haveUint := have.Uint()
		wantUint := want.Uint()
		if haveUint != wantUint {
			return []string{
				fmt.Sprintf("%s: not equal", desc),
				fmt.Sprintf("  have: %s(%d)\n", have.Type(), haveUint),
				fmt.Sprintf("  want: %s(%d)\n", want.Type(), wantUint),
			}
		}

	case reflect.Float32:
		fallthrough
	case reflect.Float64:
		// Float types.
		haveFloat := have.Float()
		wantFloat := want.Float()
		if haveFloat != wantFloat {
			return []string{
				fmt.Sprintf("%s: not equal", desc),
				fmt.Sprintf("  have: %s(%f)\n", have.Type(), haveFloat),
				fmt.Sprintf("  want: %s(%f)\n", want.Type(), wantFloat),
			}
		}

	default:
		// All other cases are primitive and therefor reflect.DeepEqual
		// actually handles them very well.
		fmt.Printf("%s   %s %s\n", desc, have.Type(), want.Type())
		if !reflect.DeepEqual(want.Interface(), have.Interface()) {
			return []string{
				fmt.Sprintf("%s: not equal.", desc),
				fmt.Sprintf("  have: %#v", have.Interface()),
				fmt.Sprintf("  wantZ: %#v", want.Interface()),
			}
		}
	}

	// This shouldn't ever be reached.
	return diffs
}
<commit_msg>More formatting clean ups<commit_after>// Copyright 2014 Brady Catherman
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package testlib

import (
	"fmt"
	"reflect"
	"strings"
)

// This file contains a super utility for checking the equality of structures
// or values. It is designed to compare anything to basically anything.

// Compares two values to ensure that they are equal to each other. This will
// deep inspect both values to ensure that the full structure tree is equal.
// It also walks through pointers ensuring that everything is equal.
func (t *T) Equal(have, want interface{}, desc ...string) {
	prefix := ""
	if len(desc) > 0 {
		prefix = strings.Join(desc, " ") + ": "
	}

	// Check to see if either value is nil and then verify that the are
	// either both nil, or fail if one is nil.
	haveNil := t.isNil(have)
	wantNil := t.isNil(want)
	if haveNil && wantNil {
		return
	} else if haveNil && !wantNil {
		t.Fatalf("%sExpected non nil, got nil.", prefix)
	} else if !haveNil && wantNil {
		t.Fatalf("%sExpected nil, got non nil.", prefix)
	}

	// Next we need to get the value of both objects so we can compare them.
	haveValue := reflect.ValueOf(have)
	wantValue := reflect.ValueOf(want)
	visited := make(map[uintptr]*visitedNode)
	reason := t.deepEqual("", haveValue, wantValue, visited)
	if len(reason) > 0 {
		t.Fatalf("%sNot Equal\n%s", prefix, strings.Join(reason, "\n"))
	}
}

// Like Equal() except that it asserts that the two values are not equal
// to each other.
func (t *T) NotEqual(have, want interface{}, desc ...string) {
	prefix := ""
	if len(desc) > 0 {
		prefix = strings.Join(desc, " ") + ": "
	}

	// Check to see if either value is nil and then verify that the are
	// either both nil, or fail if one is nil.
	haveNil := t.isNil(have)
	wantNil := t.isNil(want)
	if haveNil && wantNil {
		t.Fatalf("%sEquality not expected, have=nil", prefix)
	} else if haveNil || wantNil {
		return
	}

	// Next we need to get the value of both objects so we can compare them.
	haveValue := reflect.ValueOf(have)
	wantValue := reflect.ValueOf(want)
	visited := make(map[uintptr]*visitedNode)
	reason := t.deepEqual("", haveValue, wantValue, visited)
	if len(reason) == 0 {
		t.Fatalf("%sValues are not expected to be equal: %#v", prefix, have)
	}
}

// Tracks access to specific pointers so we do not recurse.
type visitedNode struct {
	a1   uintptr
	a2   uintptr
	typ  reflect.Type
	next *visitedNode
}

// Returns true if the underlying object is nil.
func (t *T) isNil(obj interface{}) bool {
	if obj == nil {
		return true
	}
	v := reflect.ValueOf(obj)
	switch v.Kind() {
	case reflect.Func:
	case reflect.Map:
	case reflect.Ptr:
	case reflect.Slice:
	default:
		return false
	}
	return v.IsNil()
}

// Deep comparison. This is based on golang 1.2's reflect.Equal functionality.
func (t *T) deepEqual(
	desc string, have, want reflect.Value, visited map[uintptr]*visitedNode,
) (diffs []string) {
	if !want.IsValid() && !have.IsValid() {
		return nil
	} else if !want.IsValid() && have.IsValid() {
		// This is rare, not sure how to document this better.
		return []string{
			fmt.Sprintf("%s: have invalid or nil object.", desc),
		}
	} else if want.IsValid() && !have.IsValid() {
		// This is rare, not sure how to document this better.
		return []string{
			fmt.Sprintf("%s: wanted a valid, non nil object.", desc),
		}
	} else if want.Type() != have.Type() {
		return []string{fmt.Sprintf(
			"%s: Not the same type have: '%s', want: '%s'",
			desc, have.Type(), want.Type())}
	}

	if want.CanAddr() && have.CanAddr() {
		addr1 := want.UnsafeAddr()
		addr2 := have.UnsafeAddr()
		if addr1 > addr2 {
			// Canonicalize order to reduce number of entries in visited.
			addr1, addr2 = addr2, addr1
		}

		// Short circuit if references are identical ...
		if addr1 == addr2 {
			return []string{}
		}

		// ... or already seen
		h := 17*addr1 + addr2
		seen := visited[h]
		typ := want.Type()
		for p := seen; p != nil; p = p.next {
			if p.a1 == addr1 && p.a2 == addr2 && p.typ == typ {
				return []string{}
			}
		}

		// Remember for later.
		visited[h] = &visitedNode{addr1, addr2, typ, seen}
	}

	// Checks to see if one value is nil, while the other is not.
	checkNil := func() bool {
		if want.IsNil() && !have.IsNil() {
			diffs = append(diffs, fmt.Sprintf("%s: not equal.", desc))
			diffs = append(diffs, fmt.Sprintf("  have: %#v", have.Interface()))
			diffs = append(diffs, "  wantA: nil")
			return true
		} else if !want.IsNil() && have.IsNil() {
			diffs = append(diffs, fmt.Sprintf("%s: not equal.", desc))
			diffs = append(diffs, "  have: nil")
			diffs = append(diffs, fmt.Sprintf("  wantB: %#v", want.Interface()))
			return true
		}
		return false
	}

	// Checks to see that the lengths of both objects are equal.
	checkLen := func() bool {
		if want.Len() != have.Len() {
			diffs = append(diffs, fmt.Sprintf(
				"%s: (len(have): %d, len(want): %d)",
				desc, have.Len(), want.Len()))
			diffs = append(diffs, fmt.Sprintf("  have: %#v", have.Interface()))
			diffs = append(diffs, fmt.Sprintf("  want: %#v", want.Interface()))
			return true
		}
		return false
	}

	switch want.Kind() {
	case reflect.Array:
		if !checkLen() {
			for i := 0; i < want.Len(); i++ {
				newdiffs := t.deepEqual(
					fmt.Sprintf("%s[%d]", desc, i),
					want.Index(i), have.Index(i), visited)
				diffs = append(diffs, newdiffs...)
			}
		}

	case reflect.Chan:
		// Channels are complex to compare so we rely on the existing type
		// checks to assert correctness, and then we add an additional
		// capacity check to assert buffer size.
		hcap := have.Cap()
		wcap := want.Cap()
		if hcap != wcap {
			diffs = append(diffs, fmt.Sprintf(
				"%sCapacities differ:\n  have: %d\n  want: %d",
				desc, hcap, wcap))
			return diffs
		}

	case reflect.Func:
		// Can't do better than this:
		checkNil()

	case reflect.Interface:
		if !checkNil() {
			newdiffs := t.deepEqual(
				desc, want.Elem(), have.Elem(), visited)
			diffs = append(diffs, newdiffs...)
		}

	case reflect.Map:
		if !checkNil() {
			// Check that the keys are present in both maps.
			for _, k := range want.MapKeys() {
				if !have.MapIndex(k).IsValid() {
					// Add the error.
					diffs = append(diffs, fmt.Sprintf(
						"%sExpected key [%q] is missing.", desc, k))
					diffs = append(diffs, "  have: not present")
					diffs = append(diffs, fmt.Sprintf("  want: %#v",
						want.MapIndex(k)))
					continue
				}
				newdiffs := t.deepEqual(
					fmt.Sprintf("%s[%q] ", desc, k),
					want.MapIndex(k), have.MapIndex(k), visited)
				diffs = append(diffs, newdiffs...)
			}
			for _, k := range have.MapKeys() {
				if !want.MapIndex(k).IsValid() {
					// Add the error.
					diffs = append(diffs, fmt.Sprintf(
						"%sUnexpected key [%q].", desc, k))
					diffs = append(diffs,
						fmt.Sprintf("  have: %#v", have.MapIndex(k)))
					diffs = append(diffs, "  want: not present")
				}
			}
		}

	case reflect.Ptr:
		newdiffs := t.deepEqual(
			desc, want.Elem(), have.Elem(), visited)
		diffs = append(diffs, newdiffs...)

	case reflect.Slice:
		if !checkNil() && !checkLen() {
			for i := 0; i < want.Len(); i++ {
				newdiffs := t.deepEqual(
					fmt.Sprintf("%s[%d]", desc, i),
					want.Index(i), have.Index(i), visited)
				diffs = append(diffs, newdiffs...)
			}
		}

	case reflect.String:
		// We know the underlying type is a string so calling String()
		// will return the underlying value. Trying to call Interface()
		// and assert to a string will panic.
		hstr := have.String()
		wstr := want.String()
		if len(hstr) != len(wstr) {
			return []string{
				fmt.Sprintf("%s: len(have) %d != len(want) %d.",
					desc, len(hstr), len(wstr)),
				fmt.Sprintf("  have: %#v", hstr),
				fmt.Sprintf("  want: %#v", wstr),
			}
		}
		for i := range hstr {
			if hstr[i] != wstr[i] {
				return []string{
					fmt.Sprintf("%s: difference at index %d.", desc, i),
					fmt.Sprintf("  have: %#v", hstr),
					fmt.Sprintf("  want: %#v", wstr),
				}
			}
		}

	case reflect.Struct:
		for i, n := 0, want.NumField(); i < n; i++ {
			name := want.Type().Field(i).Name
			// Make sure that we don't print a strange error if the
			// first object given to us is a struct.
			if desc == "" {
				newdiffs := t.deepEqual(
					name, want.Field(i), have.Field(i), visited)
				diffs = append(diffs, newdiffs...)
			} else {
				newdiffs := t.deepEqual(
					fmt.Sprintf("%s.%s", desc, name),
					want.Field(i), have.Field(i), visited)
				diffs = append(diffs, newdiffs...)
			}
		}

	case reflect.Uintptr:
		// Uintptr's work like UnsafePointers. We can't evaluate them or
		// do much with them so we have to cast them into a number and
		// compare them that way.
		havePtr := have.Uint()
		wantPtr := want.Uint()
		if havePtr != wantPtr {
			return []string{
				fmt.Sprintf("%s: not equal.", desc),
				fmt.Sprintf("  have: %#v", havePtr),
				fmt.Sprintf("  wantX: %#v", wantPtr),
			}
		}

	case reflect.UnsafePointer:
		// Unsafe pointers can cause us problems as they fall ill of the
		// Interface() restrictions. As such we have to special case them
		// and cast them as integers.
		havePtr := have.Pointer()
		wantPtr := want.Pointer()
		if havePtr != wantPtr {
			return []string{
				fmt.Sprintf("%s: not equal.", desc),
				fmt.Sprintf("  have: %#v", havePtr),
				fmt.Sprintf("  wantY: %#v", wantPtr),
			}
		}

	case reflect.Bool:
		haveBool := have.Bool()
		wantBool := want.Bool()
		if haveBool != wantBool {
			return []string{
				fmt.Sprintf("%s: not equal.", desc),
				fmt.Sprintf("  have: bool(%t)\n", haveBool),
				fmt.Sprintf("  want: bool(%t)\n", wantBool),
			}
		}

	case reflect.Int:
		fallthrough
	case reflect.Int8:
		fallthrough
	case reflect.Int16:
		fallthrough
	case reflect.Int32:
		fallthrough
	case reflect.Int64:
		// Basic integer types.
		haveInt := have.Int()
		wantInt := want.Int()
		if haveInt != wantInt {
			return []string{
				fmt.Sprintf("%s: not equal", desc),
				fmt.Sprintf("  have: %s(%d)", have.Type(), haveInt),
				fmt.Sprintf("  want: %s(%d)", want.Type(), wantInt),
			}
		}

	case reflect.Uint:
		fallthrough
	case reflect.Uint8:
		fallthrough
	case reflect.Uint16:
		fallthrough
	case reflect.Uint32:
		fallthrough
	case reflect.Uint64:
		// Basic unsigned integer types.
		haveUint := have.Uint()
		wantUint := want.Uint()
		if haveUint != wantUint {
			return []string{
				fmt.Sprintf("%s: not equal", desc),
				fmt.Sprintf("  have: %s(%d)", have.Type(), haveUint),
				fmt.Sprintf("  want: %s(%d)", want.Type(), wantUint),
			}
		}

	case reflect.Float32:
		fallthrough
	case reflect.Float64:
		// Float types.
		haveFloat := have.Float()
		wantFloat := want.Float()
		if haveFloat != wantFloat {
			return []string{
				fmt.Sprintf("%s: not equal", desc),
				fmt.Sprintf("  have: %s(%f)", have.Type(), haveFloat),
				fmt.Sprintf("  want: %s(%f)", want.Type(), wantFloat),
			}
		}

	default:
		// All other cases are primitive and therefor reflect.DeepEqual
		// actually handles them very well.
		fmt.Printf("%s   %s %s\n", desc, have.Type(), want.Type())
		if !reflect.DeepEqual(want.Interface(), have.Interface()) {
			return []string{
				fmt.Sprintf("%s: not equal.", desc),
				fmt.Sprintf("  have: %#v", have.Interface()),
				fmt.Sprintf("  wantZ: %#v", want.Interface()),
			}
		}
	}

	// This shouldn't ever be reached.
	return diffs
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package main

import (
	"encoding/json"
	"net/http"
	"strings"

	"github.com/labstack/echo"
	"github.com/nats-io/nats"
)

// ResponseError is
type ResponseError struct {
	Error     string          `json:"error"`
	HTTPError *echo.HTTPError `json:"-"`
}

func responseErr(msg *nats.Msg) *ResponseError {
	var e ResponseError

	err := json.Unmarshal(msg.Data, &e)
	if err != nil || e.Error == "" {
		return nil
	}

	e.HTTPError = echo.NewHTTPError(http.StatusInternalServerError, e.Error)

	if strings.Contains(e.Error, "not found") {
		e.HTTPError = ErrNotFound
	}

	return &e
}
<commit_msg>correcting uppercase on error<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package main

import (
	"encoding/json"
	"net/http"
	"strings"

	"github.com/labstack/echo"
	"github.com/nats-io/nats"
)

// ResponseError is
type ResponseError struct {
	Error     string          `json:"error"`
	HTTPError *echo.HTTPError `json:"-"`
}

func responseErr(msg *nats.Msg) *ResponseError {
	var e ResponseError

	err := json.Unmarshal(msg.Data, &e)
	if err != nil || e.Error == "" {
		return nil
	}

	e.HTTPError = echo.NewHTTPError(http.StatusInternalServerError, e.Error)

	if strings.Contains(e.Error, "Not found") {
		e.HTTPError = ErrNotFound
	}

	return &e
}
<|endoftext|>


<commit_before>package vangoh

import (
	"fmt"
	"net/http"
)

type AuthenticationError struct {
	c int
	s string
}

func (a *AuthenticationError) Error() string {
	return a.s
}

func (a *AuthenticationError) StatusCode() int {
	return a.c
}

func (a *AuthenticationError) WriteResponse(w http.ResponseWriter, debug bool) {
	w.WriteHeader(a.StatusCode())
	if debug {
		w.Header().Add("Content-Type", "text/plain")
		fmt.Fprintf(w, "%s", a)
	}
}

var ErrorAuthHeaderMissing = &AuthenticationError{
	c: http.StatusBadRequest,
	s: "Missing 'Authorization' header",
}

var ErrorAuthHeaderMalformed = &AuthenticationError{
	c: http.StatusBadRequest,
	s: "Authorization header does not match expected format",
}

var ErrorDateHeaderMissing = &AuthenticationError{
	c: http.StatusBadRequest,
	s: "Missing 'Date' header",
}

var ErrorDateHeaderMalformed = &AuthenticationError{
	c: http.StatusBadRequest,
	s: "Date header is not a valid format",
}

var ErrorDateHeaderTooFuture = &AuthenticationError{
	c: http.StatusForbidden,
	s: "Date header's value is in the future",
}

var ErrorDateHeaderTooSkewed = &AuthenticationError{
	c: http.StatusForbidden,
	s: "Date header's value is too old",
}

var ErrorAuthOrgUnknown = &AuthenticationError{
	c: http.StatusBadRequest,
	s: "Authentication organization is not recognized",
}

var ErrorInProviderKeyLookup = &AuthenticationError{
	c: http.StatusInternalServerError,
	s: "Unable to look up secret key",
}

var ErrorSecretNotFound = &AuthenticationError{
	c: http.StatusForbidden,
	s: "Authentication key is not recognized",
}

var ErrorHMACSignatureMismatch = &AuthenticationError{
	c: http.StatusForbidden,
	s: "HMAC signature does not match",
}
<commit_msg>Remove unused error.<commit_after>package vangoh

import (
	"fmt"
	"net/http"
)

type AuthenticationError struct {
	c int
	s string
}

func (a *AuthenticationError) Error() string {
	return a.s
}

func (a *AuthenticationError) StatusCode() int {
	return a.c
}

func (a *AuthenticationError) WriteResponse(w http.ResponseWriter, debug bool) {
	w.WriteHeader(a.StatusCode())
	if debug {
		w.Header().Add("Content-Type", "text/plain")
		fmt.Fprintf(w, "%s", a)
	}
}

var ErrorAuthHeaderMissing = &AuthenticationError{
	c: http.StatusBadRequest,
	s: "Missing 'Authorization' header",
}

var ErrorAuthHeaderMalformed = &AuthenticationError{
	c: http.StatusBadRequest,
	s: "Authorization header does not match expected format",
}

var ErrorDateHeaderMissing = &AuthenticationError{
	c: http.StatusBadRequest,
	s: "Missing 'Date' header",
}

var ErrorDateHeaderMalformed = &AuthenticationError{
	c: http.StatusBadRequest,
	s: "Date header is not a valid format",
}

var ErrorDateHeaderTooSkewed = &AuthenticationError{
	c: http.StatusForbidden,
	s: "Date header's value is too old",
}

var ErrorAuthOrgUnknown = &AuthenticationError{
	c: http.StatusBadRequest,
	s: "Authentication organization is not recognized",
}

var ErrorInProviderKeyLookup = &AuthenticationError{
	c: http.StatusInternalServerError,
	s: "Unable to look up secret key",
}

var ErrorSecretNotFound = &AuthenticationError{
	c: http.StatusForbidden,
	s: "Authentication key is not recognized",
}

var ErrorHMACSignatureMismatch = &AuthenticationError{
	c: http.StatusForbidden,
	s: "HMAC signature does not match",
}
<|endoftext|>