<commit_before>// Copyright 2015 Brian J. Downs
//
// 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 openweathermap

import (
	"errors"
	"net/http"
)

var errUnitUnavailable = errors.New("unit unavailable")
var errLangUnavailable = errors.New("language unavailable")
var errInvalidKey = errors.New("invalid api key")
var errInvalidOption = errors.New("invalid option")
var errInvalidHttpClient = errors.New("invalid http client")
var errForecastUnavailable = errors.New("forecast unavailable")

// DataUnits represents the character chosen to represent the temperature notation
var DataUnits = map[string]string{"C": "metric", "F": "imperial", "K": "internal"}
var (
	baseURL        = "http://api.openweathermap.org/data/2.5/weather?%s"
	iconURL        = "http://openweathermap.org/img/w/%s"
	stationURL     = "http://api.openweathermap.org/data/2.5/station?id=%d"
	forecast5Base  = "http://api.openweathermap.org/data/2.5/forecast?appid=%s&%s&mode=json&units=%s&lang=%s&cnt=%d"
	forecast16Base = "http://api.openweathermap.org/data/2.5/forecast/daily?appid=%s&%s&mode=json&units=%s&lang=%s&cnt=%d"
	historyURL     = "http://api.openweathermap.org/data/2.5/history/%s"
	pollutionURL   = "http://api.openweathermap.org/pollution/v1/co/"
	uvURL          = "http://api.openweathermap.org/data/2.5/"
	dataPostURL    = "http://openweathermap.org/data/post"
)

// LangCodes holds all supported languages to be used
// inspried and sourced from @bambocher (github.com/bambocher)
var LangCodes = map[string]string{
	"EN":    "English",
	"RU":    "Russian",
	"IT":    "Italian",
	"ES":    "Spanish",
	"SP":    "Spanish",
	"UK":    "Ukrainian",
	"UA":    "Ukrainian",
	"DE":    "German",
	"PT":    "Portuguese",
	"RO":    "Romanian",
	"PL":    "Polish",
	"FI":    "Finnish",
	"NL":    "Dutch",
	"FR":    "French",
	"BG":    "Bulgarian",
	"SV":    "Swedish",
	"SE":    "Swedish",
	"TR":    "Turkish",
	"HR":    "Croatian",
	"CA":    "Catalan",
	"ZH_TW": "Chinese Traditional",
	"ZH":    "Chinese Simplified",
	"ZH_CN": "Chinese Simplified",
}

// Config will hold default settings to be passed into the
// "NewCurrent, NewForecast, etc}" functions.
type Config struct {
	Mode     string // user choice of JSON or XML
	Unit     string // measurement for results to be displayed.  F, C, or K
	Lang     string // should reference a key in the LangCodes map
	APIKey   string // API Key for connecting to the OWM
	Username string // Username for posting data
	Password string // Pasword for posting data
}

// APIError returned on failed API calls.
type APIError struct {
	Message string `json:"message"`
	COD     string `json:"cod"`
}

// Coordinates struct holds longitude and latitude data in returned
// JSON or as parameter data for requests using longitude and latitude.
type Coordinates struct {
	Longitude float64 `json:"lon"`
	Latitude  float64 `json:"lat"`
}

// Sys struct contains general information about the request
// and the surrounding area for where the request was made.
type Sys struct {
	Type    int     `json:"type"`
	ID      int     `json:"id"`
	Message float64 `json:"message"`
	Country string  `json:"country"`
	Sunrise int     `json:"sunrise"`
	Sunset  int     `json:"sunset"`
}

// Wind struct contains the speed and degree of the wind.
type Wind struct {
	Speed float64 `json:"speed"`
	Deg   float64 `json:"deg"`
}

// Weather struct holds high-level, basic info on the returned
// data.
type Weather struct {
	ID          int    `json:"id"`
	Main        string `json:"main"`
	Description string `json:"description"`
	Icon        string `json:"icon"`
}

// Main struct contains the temperates, humidity, pressure for the request.
type Main struct {
	Temp      float64 `json:"temp"`
	TempMin   float64 `json:"temp_min"`
	TempMax   float64 `json:"temp_max"`
	Pressure  float64 `json:"pressure"`
	SeaLevel  float64 `json:"sea_level"`
	GrndLevel float64 `json:"grnd_level"`
	Humidity  int     `json:"humidity"`
}

// Clouds struct holds data regarding cloud cover.
type Clouds struct {
	All int `json:"all"`
}

// 	return key
// }
func setKey(key string) (string, error) {
	if err := ValidAPIKey(key); err != nil {
		return "", err
	}
	return key, nil
}

// ValidDataUnit makes sure the string passed in is an accepted
// unit of measure to be used for the return data.
func ValidDataUnit(u string) bool {
	for d := range DataUnits {
		if u == d {
			return true
		}
	}
	return false
}

// ValidLangCode makes sure the string passed in is an
// acceptable lang code.
func ValidLangCode(c string) bool {
	for d := range LangCodes {
		if c == d {
			return true
		}
	}
	return false
}

// ValidDataUnitSymbol makes sure the string passed in is an
// acceptable data unit symbol.
func ValidDataUnitSymbol(u string) bool {
	for _, d := range DataUnits {
		if u == d {
			return true
		}
	}
	return false
}

// ValidAPIKey makes sure that the key given is a valid one
func ValidAPIKey(key string) error {
	if len(key) == 32 {
		return errors.New("invalid key")
	}
	return nil
}

// CheckAPIKeyExists will see if an API key has been set.
func (c *Config) CheckAPIKeyExists() bool { return len(c.APIKey) > 1 }

// Settings holds the client settings
type Settings struct {
	client *http.Client
}

// NewSettings returns a new Setting pointer with default http client.
func NewSettings() *Settings {
	return &Settings{
		client: http.DefaultClient,
	}
}

// Optional client settings
type Option func(s *Settings) error

// WithHttpClient sets custom http client when creating a new Client.
func WithHttpClient(c *http.Client) Option {
	return func(s *Settings) error {
		if c == nil {
			return errInvalidHttpClient
		}
		s.client = c
		return nil
	}
}

// setOptions sets Optional client settings to the Settings pointer
func setOptions(settings *Settings, options []Option) error {
	for _, option := range options {
		if option == nil {
			return errInvalidOption
		}
		err := option(settings)
		if err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>Fix inverse logic of ValidAPIKey<commit_after>// Copyright 2015 Brian J. Downs
//
// 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 openweathermap

import (
	"errors"
	"net/http"
)

var errUnitUnavailable = errors.New("unit unavailable")
var errLangUnavailable = errors.New("language unavailable")
var errInvalidKey = errors.New("invalid api key")
var errInvalidOption = errors.New("invalid option")
var errInvalidHttpClient = errors.New("invalid http client")
var errForecastUnavailable = errors.New("forecast unavailable")

// DataUnits represents the character chosen to represent the temperature notation
var DataUnits = map[string]string{"C": "metric", "F": "imperial", "K": "internal"}
var (
	baseURL        = "http://api.openweathermap.org/data/2.5/weather?%s"
	iconURL        = "http://openweathermap.org/img/w/%s"
	stationURL     = "http://api.openweathermap.org/data/2.5/station?id=%d"
	forecast5Base  = "http://api.openweathermap.org/data/2.5/forecast?appid=%s&%s&mode=json&units=%s&lang=%s&cnt=%d"
	forecast16Base = "http://api.openweathermap.org/data/2.5/forecast/daily?appid=%s&%s&mode=json&units=%s&lang=%s&cnt=%d"
	historyURL     = "http://api.openweathermap.org/data/2.5/history/%s"
	pollutionURL   = "http://api.openweathermap.org/pollution/v1/co/"
	uvURL          = "http://api.openweathermap.org/data/2.5/"
	dataPostURL    = "http://openweathermap.org/data/post"
)

// LangCodes holds all supported languages to be used
// inspried and sourced from @bambocher (github.com/bambocher)
var LangCodes = map[string]string{
	"EN":    "English",
	"RU":    "Russian",
	"IT":    "Italian",
	"ES":    "Spanish",
	"SP":    "Spanish",
	"UK":    "Ukrainian",
	"UA":    "Ukrainian",
	"DE":    "German",
	"PT":    "Portuguese",
	"RO":    "Romanian",
	"PL":    "Polish",
	"FI":    "Finnish",
	"NL":    "Dutch",
	"FR":    "French",
	"BG":    "Bulgarian",
	"SV":    "Swedish",
	"SE":    "Swedish",
	"TR":    "Turkish",
	"HR":    "Croatian",
	"CA":    "Catalan",
	"ZH_TW": "Chinese Traditional",
	"ZH":    "Chinese Simplified",
	"ZH_CN": "Chinese Simplified",
}

// Config will hold default settings to be passed into the
// "NewCurrent, NewForecast, etc}" functions.
type Config struct {
	Mode     string // user choice of JSON or XML
	Unit     string // measurement for results to be displayed.  F, C, or K
	Lang     string // should reference a key in the LangCodes map
	APIKey   string // API Key for connecting to the OWM
	Username string // Username for posting data
	Password string // Pasword for posting data
}

// APIError returned on failed API calls.
type APIError struct {
	Message string `json:"message"`
	COD     string `json:"cod"`
}

// Coordinates struct holds longitude and latitude data in returned
// JSON or as parameter data for requests using longitude and latitude.
type Coordinates struct {
	Longitude float64 `json:"lon"`
	Latitude  float64 `json:"lat"`
}

// Sys struct contains general information about the request
// and the surrounding area for where the request was made.
type Sys struct {
	Type    int     `json:"type"`
	ID      int     `json:"id"`
	Message float64 `json:"message"`
	Country string  `json:"country"`
	Sunrise int     `json:"sunrise"`
	Sunset  int     `json:"sunset"`
}

// Wind struct contains the speed and degree of the wind.
type Wind struct {
	Speed float64 `json:"speed"`
	Deg   float64 `json:"deg"`
}

// Weather struct holds high-level, basic info on the returned
// data.
type Weather struct {
	ID          int    `json:"id"`
	Main        string `json:"main"`
	Description string `json:"description"`
	Icon        string `json:"icon"`
}

// Main struct contains the temperates, humidity, pressure for the request.
type Main struct {
	Temp      float64 `json:"temp"`
	TempMin   float64 `json:"temp_min"`
	TempMax   float64 `json:"temp_max"`
	Pressure  float64 `json:"pressure"`
	SeaLevel  float64 `json:"sea_level"`
	GrndLevel float64 `json:"grnd_level"`
	Humidity  int     `json:"humidity"`
}

// Clouds struct holds data regarding cloud cover.
type Clouds struct {
	All int `json:"all"`
}

// 	return key
// }
func setKey(key string) (string, error) {
	if err := ValidAPIKey(key); err != nil {
		return "", err
	}
	return key, nil
}

// ValidDataUnit makes sure the string passed in is an accepted
// unit of measure to be used for the return data.
func ValidDataUnit(u string) bool {
	for d := range DataUnits {
		if u == d {
			return true
		}
	}
	return false
}

// ValidLangCode makes sure the string passed in is an
// acceptable lang code.
func ValidLangCode(c string) bool {
	for d := range LangCodes {
		if c == d {
			return true
		}
	}
	return false
}

// ValidDataUnitSymbol makes sure the string passed in is an
// acceptable data unit symbol.
func ValidDataUnitSymbol(u string) bool {
	for _, d := range DataUnits {
		if u == d {
			return true
		}
	}
	return false
}

// ValidAPIKey makes sure that the key given is a valid one
func ValidAPIKey(key string) error {
	if len(key) != 32 {
		return errors.New("invalid key")
	}
	return nil
}

// CheckAPIKeyExists will see if an API key has been set.
func (c *Config) CheckAPIKeyExists() bool { return len(c.APIKey) > 1 }

// Settings holds the client settings
type Settings struct {
	client *http.Client
}

// NewSettings returns a new Setting pointer with default http client.
func NewSettings() *Settings {
	return &Settings{
		client: http.DefaultClient,
	}
}

// Optional client settings
type Option func(s *Settings) error

// WithHttpClient sets custom http client when creating a new Client.
func WithHttpClient(c *http.Client) Option {
	return func(s *Settings) error {
		if c == nil {
			return errInvalidHttpClient
		}
		s.client = c
		return nil
	}
}

// setOptions sets Optional client settings to the Settings pointer
func setOptions(settings *Settings, options []Option) error {
	for _, option := range options {
		if option == nil {
			return errInvalidOption
		}
		err := option(settings)
		if err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>// Package busy implements a dispatcher for BusyBox-style multi-call binaries.
package busy

import (
	"context"
	"fmt"
	"os"
	"path/filepath"
	"sort"

	"github.com/datawire/ambassador/pkg/dlog"
	"github.com/datawire/ambassador/pkg/environment"
)

type Command = func(ctx context.Context, version string, args ...string) error

func Main(binName, humanName string, version string, cmds map[string]Command) {
	name := filepath.Base(os.Args[0])
	if name == binName && len(os.Args) > 1 {
		name = os.Args[1]
		os.Args = os.Args[1:]
	}

	if name != "entrypoint" { // XXX: This is a layer-breaking hack
		environment.EnvironmentSetupEntrypoint()
	}

	if cmdFn, cmdFnOK := cmds[name]; cmdFnOK {
		ctx := context.Background()
		if err := cmdFn(ctx, version, os.Args[1:]...); err != nil {
			dlog.Errorf(ctx, "shut down with error error: %v", err)
			os.Exit(1)
		}
	} else {
		fmt.Printf("The %s main program is a multi-call binary that combines various\n", humanName)
		fmt.Println("support programs into one executable.")
		fmt.Println()
		fmt.Printf("Usage: %s <PROGRAM> [arguments]...\n", binName)
		fmt.Println("   or: <PROGRAM> [arguments]...")
		fmt.Println()
		cmdnames := make([]string, 0, len(cmds))
		for cmdname := range cmds {
			cmdnames = append(cmdnames, cmdname)
		}
		sort.Strings(cmdnames)
		fmt.Println("Available programs:", cmdnames)
		fmt.Println()
		fmt.Printf("Unknown program %q\n", name)
		// POSIX says the shell should set $?=127 for "command
		// not found", so non-shell programs that just run a
		// command for you (including busybox) tend to mimic
		// that and use exit code 127 to indicate "command not
		// found".
		os.Exit(127)
	}
}
<commit_msg>(from AES) Set up dlog from pkg/busy<commit_after>// Package busy implements a dispatcher for BusyBox-style multi-call binaries.
package busy

import (
	"context"
	"fmt"
	"os"
	"path/filepath"
	"sort"

	"github.com/sirupsen/logrus"

	"github.com/datawire/ambassador/pkg/dlog"
	"github.com/datawire/ambassador/pkg/environment"
)

type Command = func(ctx context.Context, version string, args ...string) error

var logrusLogger *logrus.Logger

func init() {
	logrusLogger = logrus.New()
	logrusFormatter := &logrus.TextFormatter{
		TimestampFormat: "2006-01-02 15:04:05",
		FullTimestamp:   true,
	}
	logrusLogger.SetFormatter(logrusFormatter)
	logrusLogger.SetReportCaller(true)
}

func SetLogLevel(lvl logrus.Level) {
	logrusLogger.SetLevel(lvl)
}

func GetLogLevel() logrus.Level {
	return logrusLogger.GetLevel()
}

func Main(binName, humanName string, version string, cmds map[string]Command) {
	name := filepath.Base(os.Args[0])
	if name == binName && len(os.Args) > 1 {
		name = os.Args[1]
		os.Args = os.Args[1:]
	}

	if name != "entrypoint" { // XXX: This is a layer-breaking hack
		environment.EnvironmentSetupEntrypoint()
	}

	logger := dlog.WrapLogrus(logrusLogger).
		WithField("PID", os.Getpid()).
		WithField("CMD", name)
	ctx := dlog.WithLogger(context.Background(), logger)
	dlog.SetFallbackLogger(logger.WithField("oops-i-did-not-pass-context-correctly", true))

	if cmdFn, cmdFnOK := cmds[name]; cmdFnOK {
		if err := cmdFn(ctx, version, os.Args[1:]...); err != nil {
			dlog.Errorf(ctx, "shut down with error error: %v", err)
			os.Exit(1)
		}
	} else {
		fmt.Printf("The %s main program is a multi-call binary that combines various\n", humanName)
		fmt.Println("support programs into one executable.")
		fmt.Println()
		fmt.Printf("Usage: %s <PROGRAM> [arguments]...\n", binName)
		fmt.Println("   or: <PROGRAM> [arguments]...")
		fmt.Println()
		cmdnames := make([]string, 0, len(cmds))
		for cmdname := range cmds {
			cmdnames = append(cmdnames, cmdname)
		}
		sort.Strings(cmdnames)
		fmt.Println("Available programs:", cmdnames)
		fmt.Println()
		fmt.Printf("Unknown program %q\n", name)
		// POSIX says the shell should set $?=127 for "command
		// not found", so non-shell programs that just run a
		// command for you (including busybox) tend to mimic
		// that and use exit code 127 to indicate "command not
		// found".
		os.Exit(127)
	}
}
<|endoftext|>


<commit_before>package dapp

import (
	"os"
	"path/filepath"
)

const (
	Version = "1.0.0-alpha"
)

var (
	tmpDir, homeDir string
)

func GetHomeDir() string {
	if homeDir == "" {
		panic("bug: init required!")
	}

	return homeDir
}

func GetTmpDir() string {
	if tmpDir == "" {
		panic("bug: init required!")
	}

	return tmpDir
}

func Init(tmpDirOption, homeDirOption string) error {
	if val, ok := os.LookupEnv("DAPP_TMP"); ok {
		tmpDir = val
	} else if tmpDirOption != "" {
		tmpDir = tmpDirOption
	} else {
		tmpDir = os.TempDir()
	}

	if val, ok := os.LookupEnv("DAPP_HOME"); ok {
		homeDir = val
	} else if homeDirOption != "" {
		homeDir = homeDirOption
	} else {
		homeDir = filepath.Join(os.Getenv("HOME"), ".dapp")
	}

	return nil
}

/* TODO: will be needed for single go-dapp binary
func Init() error {
		TmpDir, err = ioutil.TempDir("", "dapp-")
		if err != nil {
			return fmt.Errorf("cannot create temporary dir: %s", err)
		}

		interruptCh := make(chan os.Signal, 1)
		signal.Notify(interruptCh, syscall.SIGINT, syscall.SIGTERM)

		go func() {
			<-interruptCh
			err := Terminate()
			if err != nil {
				fmt.Fprintf(os.Stderr, "Error terminating dapp: %s", err)
			}
			fmt.Fprintf(os.Stderr, "Exiting")
			os.Exit(1)
		}()

	return nil
}

func Terminate() error {
		err := os.RemoveAll(TmpDir)
		if err != nil {
			return fmt.Errorf("cannot remove temporary dir: %s", err)
		}

	return nil
}
*/
<commit_msg>v1.0.0-alpha.1<commit_after>package dapp

import (
	"os"
	"path/filepath"
)

const (
	Version = "1.0.0-alpha.1"
)

var (
	tmpDir, homeDir string
)

func GetHomeDir() string {
	if homeDir == "" {
		panic("bug: init required!")
	}

	return homeDir
}

func GetTmpDir() string {
	if tmpDir == "" {
		panic("bug: init required!")
	}

	return tmpDir
}

func Init(tmpDirOption, homeDirOption string) error {
	if val, ok := os.LookupEnv("DAPP_TMP"); ok {
		tmpDir = val
	} else if tmpDirOption != "" {
		tmpDir = tmpDirOption
	} else {
		tmpDir = os.TempDir()
	}

	if val, ok := os.LookupEnv("DAPP_HOME"); ok {
		homeDir = val
	} else if homeDirOption != "" {
		homeDir = homeDirOption
	} else {
		homeDir = filepath.Join(os.Getenv("HOME"), ".dapp")
	}

	return nil
}

/* TODO: will be needed for single go-dapp binary
func Init() error {
		TmpDir, err = ioutil.TempDir("", "dapp-")
		if err != nil {
			return fmt.Errorf("cannot create temporary dir: %s", err)
		}

		interruptCh := make(chan os.Signal, 1)
		signal.Notify(interruptCh, syscall.SIGINT, syscall.SIGTERM)

		go func() {
			<-interruptCh
			err := Terminate()
			if err != nil {
				fmt.Fprintf(os.Stderr, "Error terminating dapp: %s", err)
			}
			fmt.Fprintf(os.Stderr, "Exiting")
			os.Exit(1)
		}()

	return nil
}

func Terminate() error {
		err := os.RemoveAll(TmpDir)
		if err != nil {
			return fmt.Errorf("cannot remove temporary dir: %s", err)
		}

	return nil
}
*/
<|endoftext|>


<commit_before>package httpd

import (
	"flag"
	"os"
	"http"
)

var (
	flagSet  = flag.NewFlagSet("httpd", flag.PanicOnError)
	addrFlag = flagSet.String("addr", ":8080", "Address to listen on")
	helpFlag = flagSet.Bool("help", false, "Show this help")
)

func Httpd(call []string) os.Error {
	e := flagSet.Parse(call[1:])
	if e != nil {
		return e
	}

	if flagSet.NArg() <= 0 || *helpFlag {
		println("`httpd` [options] <dir>")
		flagSet.PrintDefaults()
		return nil
	}

	return http.ListenAndServe(*addrFlag, http.FileServer(http.Dir(flagSet.Arg(0))))
}
<commit_msg>Httpd: Fixed parameter check<commit_after>package httpd

import (
	"flag"
	"os"
	"http"
)

var (
	flagSet  = flag.NewFlagSet("httpd", flag.PanicOnError)
	addrFlag = flagSet.String("addr", ":8080", "Address to listen on")
	helpFlag = flagSet.Bool("help", false, "Show this help")
)

func Httpd(call []string) os.Error {
	e := flagSet.Parse(call[1:])
	if e != nil {
		return e
	}

	if flagSet.NArg() != 1 || *helpFlag {
		println("`httpd` [options] <dir>")
		flagSet.PrintDefaults()
		return nil
	}

	return http.ListenAndServe(*addrFlag, http.FileServer(http.Dir(flagSet.Arg(0))))
}
<|endoftext|>


<commit_before>/*
 * Minio Client, (C) 2015, 2016 Minio, Inc.
 *
 * 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 main

import (
	"encoding/json"

	"github.com/fatih/color"
	"github.com/minio/cli"
	"github.com/minio/mc/pkg/console"
	"github.com/minio/minio/pkg/probe"
)

var (
	accessFlags = []cli.Flag{
		cli.BoolFlag{
			Name:  "help, h",
			Usage: "Help of access.",
		},
	}
)

// Set public access permissions.
var accessCmd = cli.Command{
	Name:   "access",
	Usage:  "Set public access permissions on bucket or prefix.",
	Action: mainAccess,
	Flags:  append(accessFlags, globalFlags...),
	CustomHelpTemplate: `Name:
   mc {{.Name}} - {{.Usage}}

USAGE:
   mc {{.Name}} [FLAGS] PERMISSION TARGET
   mc {{.Name}} [FLAGS] TARGET

PERMISSION:
   Allowed permissions are: [none, readonly, readwrite, writeonly].

FLAGS:
  {{range .Flags}}{{.}}
  {{end}}
EXAMPLES:
   1. Set bucket to "readonly" on Amazon S3 cloud storage.
      $ mc {{.Name}} readonly s3/burningman2011

   2. Set bucket to "readwrite" on Amazon S3 cloud storage.
      $ mc {{.Name}} readwrite s3/shared

   3. Set bucket to "writeonly" on Amazon S3 cloud storage.
      $ mc {{.Name}} writeonly s3/incoming

   4. Set a prefix to "readwrite" on Amazon S3 cloud storage.
      $ mc {{.Name}} readwrite s3/public-commons/images

   5. Get bucket permissions.
      $ mc {{.Name}} s3/shared

`,
}

// accessMessage is container for access command on bucket success and failure messages.
type accessMessage struct {
	Operation string      `json:"operation"`
	Status    string      `json:"status"`
	Bucket    string      `json:"bucket"`
	Perms     accessPerms `json:"permission"`
}

// String colorized access message.
func (s accessMessage) String() string {
	if s.Operation == "set" {
		return console.Colorize("Access",
			"Set access permission ‘"+string(s.Perms)+"’ updated successfully for ‘"+s.Bucket+"’")
	}
	if s.Operation == "get" {
		return console.Colorize("Access",
			"Access permission for ‘"+s.Bucket+"’"+" is ‘"+string(s.Perms)+"’")
	}
	// nothing to print
	return ""
}

// JSON jsonified access message.
func (s accessMessage) JSON() string {
	accessJSONBytes, e := json.Marshal(s)
	fatalIf(probe.NewError(e), "Unable to marshal into JSON.")

	return string(accessJSONBytes)
}

// checkAccessSyntax check for incoming syntax.
func checkAccessSyntax(ctx *cli.Context) {
	if !ctx.Args().Present() {
		cli.ShowCommandHelpAndExit(ctx, "access", 1) // last argument is exit code.
	}
	if len(ctx.Args()) > 2 {
		cli.ShowCommandHelpAndExit(ctx, "access", 1) // last argument is exit code.
	}
	if len(ctx.Args()) == 2 {
		perms := accessPerms(ctx.Args().Get(0))
		if !perms.isValidAccessPERM() {
			fatalIf(errDummy().Trace(),
				"Unrecognized permission ‘"+string(perms)+"’. Allowed values are [none, readonly, readwrite, writeonly].")
		}
	}
	if len(ctx.Args()) < 1 {
		cli.ShowCommandHelpAndExit(ctx, "access", 1) // last argument is exit code.
	}
}

// doSetAccess do set access.
func doSetAccess(targetURL string, targetPERMS accessPerms) *probe.Error {
	clnt, err := newClient(targetURL)
	if err != nil {
		return err.Trace(targetURL)
	}
	if err = clnt.SetAccess(string(targetPERMS)); err != nil {
		return err.Trace(targetURL, string(targetPERMS))
	}
	return nil
}

// doGetAccess do get access.
func doGetAccess(targetURL string) (perms accessPerms, err *probe.Error) {
	clnt, err := newClient(targetURL)
	if err != nil {
		return "", err.Trace(targetURL)
	}
	perm, err := clnt.GetAccess()
	if err != nil {
		return "", err.Trace(targetURL)
	}
	return accessPerms(perm), nil
}

func mainAccess(ctx *cli.Context) {
	// Set global flags from context.
	setGlobalsFromContext(ctx)

	// check 'access' cli arguments.
	checkAccessSyntax(ctx)

	// Additional command speific theme customization.
	console.SetColor("Access", color.New(color.FgGreen, color.Bold))

	perms := accessPerms(ctx.Args().First())
	if perms.isValidAccessPERM() {
		targetURL := ctx.Args().Last()
		err := doSetAccess(targetURL, perms)
		// Upon error exit.
		fatalIf(err.Trace(targetURL, string(perms)),
			"Unable to set access permission ‘"+string(perms)+"’ for ‘"+targetURL+"’.")
		printMsg(accessMessage{
			Status:    "success",
			Operation: "set",
			Bucket:    targetURL,
			Perms:     perms,
		})
	} else {
		targetURL := ctx.Args().First()
		perms, err := doGetAccess(targetURL)
		fatalIf(err.Trace(targetURL), "Unable to get access permission for ‘"+targetURL+"’.")
		printMsg(accessMessage{
			Status:    "success",
			Operation: "get",
			Bucket:    targetURL,
			Perms:     perms,
		})
	}
}
<commit_msg>access: Change set access perm message.<commit_after>/*
 * Minio Client, (C) 2015, 2016 Minio, Inc.
 *
 * 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 main

import (
	"encoding/json"

	"github.com/fatih/color"
	"github.com/minio/cli"
	"github.com/minio/mc/pkg/console"
	"github.com/minio/minio/pkg/probe"
)

var (
	accessFlags = []cli.Flag{
		cli.BoolFlag{
			Name:  "help, h",
			Usage: "Help of access.",
		},
	}
)

// Set public access permissions.
var accessCmd = cli.Command{
	Name:   "access",
	Usage:  "Set public access permissions on bucket or prefix.",
	Action: mainAccess,
	Flags:  append(accessFlags, globalFlags...),
	CustomHelpTemplate: `Name:
   mc {{.Name}} - {{.Usage}}

USAGE:
   mc {{.Name}} [FLAGS] PERMISSION TARGET
   mc {{.Name}} [FLAGS] TARGET

PERMISSION:
   Allowed permissions are: [none, readonly, readwrite, writeonly].

FLAGS:
  {{range .Flags}}{{.}}
  {{end}}
EXAMPLES:
   1. Set bucket to "readonly" on Amazon S3 cloud storage.
      $ mc {{.Name}} readonly s3/burningman2011

   2. Set bucket to "readwrite" on Amazon S3 cloud storage.
      $ mc {{.Name}} readwrite s3/shared

   3. Set bucket to "writeonly" on Amazon S3 cloud storage.
      $ mc {{.Name}} writeonly s3/incoming

   4. Set a prefix to "readwrite" on Amazon S3 cloud storage.
      $ mc {{.Name}} readwrite s3/public-commons/images

   5. Get bucket permissions.
      $ mc {{.Name}} s3/shared

`,
}

// accessMessage is container for access command on bucket success and failure messages.
type accessMessage struct {
	Operation string      `json:"operation"`
	Status    string      `json:"status"`
	Bucket    string      `json:"bucket"`
	Perms     accessPerms `json:"permission"`
}

// String colorized access message.
func (s accessMessage) String() string {
	if s.Operation == "set" {
		return console.Colorize("Access",
			"Access permission for ‘"+s.Bucket+"’ is set to ‘"+string(s.Perms)+"’")
	}
	if s.Operation == "get" {
		return console.Colorize("Access",
			"Access permission for ‘"+s.Bucket+"’"+" is ‘"+string(s.Perms)+"’")
	}
	// nothing to print
	return ""
}

// JSON jsonified access message.
func (s accessMessage) JSON() string {
	accessJSONBytes, e := json.Marshal(s)
	fatalIf(probe.NewError(e), "Unable to marshal into JSON.")

	return string(accessJSONBytes)
}

// checkAccessSyntax check for incoming syntax.
func checkAccessSyntax(ctx *cli.Context) {
	if !ctx.Args().Present() {
		cli.ShowCommandHelpAndExit(ctx, "access", 1) // last argument is exit code.
	}
	if len(ctx.Args()) > 2 {
		cli.ShowCommandHelpAndExit(ctx, "access", 1) // last argument is exit code.
	}
	if len(ctx.Args()) == 2 {
		perms := accessPerms(ctx.Args().Get(0))
		if !perms.isValidAccessPERM() {
			fatalIf(errDummy().Trace(),
				"Unrecognized permission ‘"+string(perms)+"’. Allowed values are [none, readonly, readwrite, writeonly].")
		}
	}
	if len(ctx.Args()) < 1 {
		cli.ShowCommandHelpAndExit(ctx, "access", 1) // last argument is exit code.
	}
}

// doSetAccess do set access.
func doSetAccess(targetURL string, targetPERMS accessPerms) *probe.Error {
	clnt, err := newClient(targetURL)
	if err != nil {
		return err.Trace(targetURL)
	}
	if err = clnt.SetAccess(string(targetPERMS)); err != nil {
		return err.Trace(targetURL, string(targetPERMS))
	}
	return nil
}

// doGetAccess do get access.
func doGetAccess(targetURL string) (perms accessPerms, err *probe.Error) {
	clnt, err := newClient(targetURL)
	if err != nil {
		return "", err.Trace(targetURL)
	}
	perm, err := clnt.GetAccess()
	if err != nil {
		return "", err.Trace(targetURL)
	}
	return accessPerms(perm), nil
}

func mainAccess(ctx *cli.Context) {
	// Set global flags from context.
	setGlobalsFromContext(ctx)

	// check 'access' cli arguments.
	checkAccessSyntax(ctx)

	// Additional command speific theme customization.
	console.SetColor("Access", color.New(color.FgGreen, color.Bold))

	perms := accessPerms(ctx.Args().First())
	if perms.isValidAccessPERM() {
		targetURL := ctx.Args().Last()
		err := doSetAccess(targetURL, perms)
		// Upon error exit.
		fatalIf(err.Trace(targetURL, string(perms)),
			"Unable to set access permission ‘"+string(perms)+"’ for ‘"+targetURL+"’.")
		printMsg(accessMessage{
			Status:    "success",
			Operation: "set",
			Bucket:    targetURL,
			Perms:     perms,
		})
	} else {
		targetURL := ctx.Args().First()
		perms, err := doGetAccess(targetURL)
		fatalIf(err.Trace(targetURL), "Unable to get access permission for ‘"+targetURL+"’.")
		printMsg(accessMessage{
			Status:    "success",
			Operation: "get",
			Bucket:    targetURL,
			Perms:     perms,
		})
	}
}
<|endoftext|>


<commit_before>package actions

import (
	"fmt"
	"strings"

	log "github.com/Sirupsen/logrus"
	"github.com/gaia-docker/tugbot/container"
	"github.com/samalba/dockerclient"
)

// Run looks at Docker containers to see if any of the images
// used to start those containers is a test container.
// For each test container it'll create and start a new container according
// to tugbots' labels.
func Run(client container.Client, names []string, e *dockerclient.Event) error {
	var ret []string
	if !container.IsSwarmTask(e) && !container.IsCreatedByTugbot(e) {
		candidates, err := client.ListContainers(containerFilter(names))
		if err != nil {
			return err
		}
		for _, candidate := range candidates {
			if candidate.IsEventListener(e) {
				if err := client.StartContainerFrom(candidate); err != nil {
					log.Error(err)
					ret = append(ret, err.Error())
				}
			}
		}
	}

	return fmt.Errorf(strings.Join(ret, "\n"))
}

func containerFilter(names []string) container.Filter {

	return func(c container.Container) bool {
		return nameFilter(names)(c) && c.IsTugbotCandidate()
	}
}

func nameFilter(names []string) container.Filter {

	if len(names) == 0 {
		// all containers
		return func(container.Container) bool {
			return true
		}
	}

	return func(c container.Container) bool {
		for _, name := range names {
			if (name == c.Name()) || (name == c.Name()[1:]) {
				return true
			}
		}
		return false
	}
}
<commit_msg>fix build;<commit_after>package actions

import (
	"fmt"
	"strings"

	log "github.com/Sirupsen/logrus"
	"github.com/gaia-docker/tugbot/container"
	"github.com/samalba/dockerclient"
)

// Run looks at Docker containers to see if any of the images
// used to start those containers is a test container.
// For each test container it'll create and start a new container according
// to tugbots' labels.
func Run(client container.Client, names []string, e *dockerclient.Event) error {
	var ret []string
	if !container.IsSwarmTask(e) && !container.IsCreatedByTugbot(e) {
		candidates, err := client.ListContainers(containerFilter(names))
		if err != nil {
			return err
		}
		for _, candidate := range candidates {
			if candidate.IsEventListener(e) {
				if err := client.StartContainerFrom(candidate); err != nil {
					log.Error(err)
					ret = append(ret, err.Error())
				}
			}
		}
	}

	return getError(ret)
}

func getError(errors []string) error {
	var ret error
	if len(errors) > 0 {
		ret = fmt.Errorf(strings.Join(errors, "\n"))
	}

	return ret
}

func containerFilter(names []string) container.Filter {

	return func(c container.Container) bool {
		return nameFilter(names)(c) && c.IsTugbotCandidate()
	}
}

func nameFilter(names []string) container.Filter {

	if len(names) == 0 {
		// all containers
		return func(container.Container) bool {
			return true
		}
	}

	return func(c container.Container) bool {
		for _, name := range names {
			if (name == c.Name()) || (name == c.Name()[1:]) {
				return true
			}
		}
		return false
	}
}
<|endoftext|>


<commit_before>package gomega

import (
	"errors"
	. "github.com/onsi/ginkgo"
)

type fakeMatcher struct {
	receivedActual  interface{}
	matchesToReturn bool
	messageToReturn string
	errToReturn     error
}

func (matcher *fakeMatcher) Match(actual interface{}) (bool, string, error) {
	matcher.receivedActual = actual

	return matcher.matchesToReturn, matcher.messageToReturn, matcher.errToReturn
}

func init() {
	Describe("Actual", func() {
		var (
			a                 *actual
			failureMessage    string
			failureCallerSkip int
			matcher           *fakeMatcher
		)

		input := "The thing I'm testing"

		var fakeFailHandler = func(message string, callerSkip ...int) {
			failureMessage = message
			if len(callerSkip) == 1 {
				failureCallerSkip = callerSkip[0]
			}
		}

		BeforeEach(func() {
			matcher = &fakeMatcher{}
			failureMessage = ""
			failureCallerSkip = 0
			a = newActual(input, fakeFailHandler)
		})

		Context("when called", func() {
			It("should pass the provided input value to the matcher", func() {
				a.Should(matcher)

				Ω(matcher.receivedActual).Should(Equal(input))
				matcher.receivedActual = ""

				a.ShouldNot(matcher)

				Ω(matcher.receivedActual).Should(Equal(input))
				matcher.receivedActual = ""

				a.To(matcher)

				Ω(matcher.receivedActual).Should(Equal(input))
				matcher.receivedActual = ""

				a.ToNot(matcher)

				Ω(matcher.receivedActual).Should(Equal(input))
				matcher.receivedActual = ""

				a.NotTo(matcher)

				Ω(matcher.receivedActual).Should(Equal(input))
			})
		})

		Context("when the matcher succeeds", func() {
			BeforeEach(func() {
				matcher.matchesToReturn = true
				matcher.messageToReturn = "The negative failure message"
				matcher.errToReturn = nil
			})

			Context("and a positive assertion is being made", func() {
				It("should not call the failure callback", func() {
					a.Should(matcher)
					Ω(failureMessage).Should(Equal(""))
				})
			})

			Context("and a negative assertion is being made", func() {
				It("should call the failure callback", func() {
					a.ShouldNot(matcher)
					Ω(failureMessage).Should(Equal("The negative failure message"))
				})
			})
		})

		Context("when the matcher fails", func() {
			BeforeEach(func() {
				matcher.matchesToReturn = false
				matcher.messageToReturn = "The positive failure message"
				matcher.errToReturn = nil
			})

			Context("and a positive assertion is being made", func() {
				It("should call the failure callback", func() {
					a.Should(matcher)
					Ω(failureMessage).Should(Equal("The positive failure message"))
				})
			})

			Context("and a negative assertion is being made", func() {
				It("should not call the failure callback", func() {
					a.ShouldNot(matcher)
					Ω(failureMessage).Should(Equal(""))
				})
			})
		})

		Context("When reporting a failure", func() {
			BeforeEach(func() {
				matcher.matchesToReturn = false
				matcher.messageToReturn = "The positive failure message"
				matcher.errToReturn = nil
			})

			Context("and there is an optional description", func() {
				It("should append the description to the failure message", func() {
					a.Should(matcher, "A description")
					Ω(failureMessage).Should(Equal("A description\nThe positive failure message"))
				})
			})

			Context("and there are multiple arguments to the optional description", func() {
				It("should append the formatted description to the failure message", func() {
					a.Should(matcher, "A description of [%d]", 3)
					Ω(failureMessage).Should(Equal("A description of [3]\nThe positive failure message"))
				})
			})
		})

		Context("When the matcher returns an error", func() {
			BeforeEach(func() {
				matcher.errToReturn = errors.New("Kaboom!")
			})

			Context("and a positive assertion is being made", func() {
				It("should call the failure callback", func() {
					matcher.matchesToReturn = true
					matcher.messageToReturn = "Ignore me"
					a.Should(matcher)
					Ω(failureMessage).Should(Equal("Kaboom!"))
				})
			})

			Context("and a negative assertion is being made", func() {
				It("should call the failure callback", func() {
					matcher.matchesToReturn = false
					matcher.messageToReturn = "Ignore me"
					a.ShouldNot(matcher)
					Ω(failureMessage).Should(Equal("Kaboom!"))
				})
			})
		})
	})
}
<commit_msg>added test coverage for call skip<commit_after>package gomega

import (
	"errors"
	. "github.com/onsi/ginkgo"
)

type fakeMatcher struct {
	receivedActual  interface{}
	matchesToReturn bool
	messageToReturn string
	errToReturn     error
}

func (matcher *fakeMatcher) Match(actual interface{}) (bool, string, error) {
	matcher.receivedActual = actual

	return matcher.matchesToReturn, matcher.messageToReturn, matcher.errToReturn
}

func init() {
	Describe("Actual", func() {
		var (
			a                 *actual
			failureMessage    string
			failureCallerSkip int
			matcher           *fakeMatcher
		)

		input := "The thing I'm testing"

		var fakeFailHandler = func(message string, callerSkip ...int) {
			failureMessage = message
			if len(callerSkip) == 1 {
				failureCallerSkip = callerSkip[0]
			}
		}

		BeforeEach(func() {
			matcher = &fakeMatcher{}
			failureMessage = ""
			failureCallerSkip = 0
			a = newActual(input, fakeFailHandler)
		})

		Context("when called", func() {
			It("should pass the provided input value to the matcher", func() {
				a.Should(matcher)

				Ω(matcher.receivedActual).Should(Equal(input))
				matcher.receivedActual = ""

				a.ShouldNot(matcher)

				Ω(matcher.receivedActual).Should(Equal(input))
				matcher.receivedActual = ""

				a.To(matcher)

				Ω(matcher.receivedActual).Should(Equal(input))
				matcher.receivedActual = ""

				a.ToNot(matcher)

				Ω(matcher.receivedActual).Should(Equal(input))
				matcher.receivedActual = ""

				a.NotTo(matcher)

				Ω(matcher.receivedActual).Should(Equal(input))
			})
		})

		Context("when the matcher succeeds", func() {
			BeforeEach(func() {
				matcher.matchesToReturn = true
				matcher.messageToReturn = "The negative failure message"
				matcher.errToReturn = nil
			})

			Context("and a positive assertion is being made", func() {
				It("should not call the failure callback", func() {
					a.Should(matcher)
					Ω(failureMessage).Should(Equal(""))
				})
			})

			Context("and a negative assertion is being made", func() {
				It("should call the failure callback", func() {
					a.ShouldNot(matcher)
					Ω(failureMessage).Should(Equal("The negative failure message"))
					Ω(failureCallerSkip).Should(Equal(2))
				})
			})
		})

		Context("when the matcher fails", func() {
			BeforeEach(func() {
				matcher.matchesToReturn = false
				matcher.messageToReturn = "The positive failure message"
				matcher.errToReturn = nil
			})

			Context("and a positive assertion is being made", func() {
				It("should call the failure callback", func() {
					a.Should(matcher)
					Ω(failureMessage).Should(Equal("The positive failure message"))
					Ω(failureCallerSkip).Should(Equal(2))
				})
			})

			Context("and a negative assertion is being made", func() {
				It("should not call the failure callback", func() {
					a.ShouldNot(matcher)
					Ω(failureMessage).Should(Equal(""))
				})
			})
		})

		Context("When reporting a failure", func() {
			BeforeEach(func() {
				matcher.matchesToReturn = false
				matcher.messageToReturn = "The positive failure message"
				matcher.errToReturn = nil
			})

			Context("and there is an optional description", func() {
				It("should append the description to the failure message", func() {
					a.Should(matcher, "A description")
					Ω(failureMessage).Should(Equal("A description\nThe positive failure message"))
					Ω(failureCallerSkip).Should(Equal(2))
				})
			})

			Context("and there are multiple arguments to the optional description", func() {
				It("should append the formatted description to the failure message", func() {
					a.Should(matcher, "A description of [%d]", 3)
					Ω(failureMessage).Should(Equal("A description of [3]\nThe positive failure message"))
					Ω(failureCallerSkip).Should(Equal(2))
				})
			})
		})

		Context("When the matcher returns an error", func() {
			BeforeEach(func() {
				matcher.errToReturn = errors.New("Kaboom!")
			})

			Context("and a positive assertion is being made", func() {
				It("should call the failure callback", func() {
					matcher.matchesToReturn = true
					matcher.messageToReturn = "Ignore me"
					a.Should(matcher)
					Ω(failureMessage).Should(Equal("Kaboom!"))
					Ω(failureCallerSkip).Should(Equal(2))
				})
			})

			Context("and a negative assertion is being made", func() {
				It("should call the failure callback", func() {
					matcher.matchesToReturn = false
					matcher.messageToReturn = "Ignore me"
					a.ShouldNot(matcher)
					Ω(failureMessage).Should(Equal("Kaboom!"))
					Ω(failureCallerSkip).Should(Equal(2))
				})
			})
		})
	})
}
<|endoftext|>


<commit_before>package admin

import (
	"errors"

	"github.com/Alienero/Rambo/meta"
)

var (
	errInvalidUser = errors.New("invalid user")
	errDBExisted   = errors.New("db is arlready existed")
)

// Admin provide some method to manage database
type Admin struct {
	isLogin bool
}

// AddUser add a database user
func (Admin) AddUser(user, password string) error {
	return meta.Meta.AddUser(user, password)
}

// AddDatabase a database for user, db is the database name,
// n is create how many partition database will create.
func (m *Admin) AddDatabase(db, user string, n int) error {
	if !m.isLogin {
		return errInvalidUser
	}
	isExist, err := meta.Meta.IsDBExist(db)
	if err != nil {
		return err
	}
	if isExist {
		return errDBExisted
	}
	// create database.
	// get backends.
	return nil
}

// AddTable add a table of a database.
func (m *Admin) AddTable(tableName, dbName string) {}

// Login check the user.
func (m *Admin) Login(user, password string) bool {
	m.isLogin = meta.Meta.CheckUserDirect(user, password)
	return m.isLogin
}
<commit_msg>style<admin>: fix style<commit_after>package admin

import (
	"errors"

	"github.com/Alienero/Rambo/meta"
)

var (
	errInvalidUser = errors.New("invalid user")
	errDBExisted   = errors.New("db is arlready existed")
)

// Admin provide some method to manage database
type Admin struct {
	isLogin bool
}

// AddUser add a database user
func (Admin) AddUser(user, password string) error {
	return meta.Meta.AddUser(user, password)
}

// AddDatabase a database for user, db is the database name,
// n is create how many partition database will create.
func (m *Admin) AddDatabase(db, user string, n int) error {
	if !m.isLogin {
		return errInvalidUser
	}
	isExist, err := meta.Meta.IsDBExist(db)
	if err != nil {
		return err
	}
	if isExist {
		return errDBExisted
	}
	// TODO:
	// create database.
	// get backends.
	return nil
}

// AddTable add a table of a database.
func (m *Admin) AddTable(tableName, dbName string) {}

// Login check the user.
func (m *Admin) Login(user, password string) bool {
	m.isLogin = meta.Meta.CheckUserDirect(user, password)
	return m.isLogin
}
<|endoftext|>


<commit_before>package admin

import (
	"html/template"
	"net/http"

	"github.com/qor/qor"
	"github.com/qor/qor/resource"
	"github.com/qor/qor/roles"
)

type Admin struct {
	Config    *qor.Config
	Resources map[string]*Resource
	auth      Auth
	router    *Router
	funcMaps  template.FuncMap
}

func New(config *qor.Config) *Admin {
	admin := Admin{
		Resources: map[string]*Resource{},
		funcMaps:  make(template.FuncMap),
		Config:    config,
		router:    newRouter(),
	}
	return &admin
}

func NewResource(value interface{}, names ...string) *Resource {
	res := resource.New(value, names...)
	return &Resource{
		Resource:    *res,
		cachedMetas: &map[string][]*resource.Meta{},
		scopes:      map[string]*Scope{},
		filters:     map[string]*Filter{},
		actions:     map[string]*Action{},
	}
}

func (admin *Admin) NewResource(value interface{}, names ...string) *Resource {
	res := NewResource(value, names...)
	admin.Resources[res.Name] = res
	return res
}

func (admin *Admin) GetResource(name string) *Resource {
	return admin.Resources[name]
}

func (admin *Admin) UseResource(res *Resource) {
	admin.Resources[res.Name] = res
}

func (admin *Admin) SetAuth(auth Auth) {
	admin.auth = auth
}

func (admin *Admin) GetRouter() *Router {
	return admin.router
}

func (admin *Admin) NewContext(w http.ResponseWriter, r *http.Request) *Context {
	var currentUser *qor.CurrentUser
	context := Context{Context: &qor.Context{Config: admin.Config, Request: r}, Writer: w, Admin: admin}
	if admin.auth != nil {
		currentUser = admin.auth.GetCurrentUser(&context)
	}
	context.Roles = roles.MatchedRoles(r, currentUser)

	return &context
}

func (admin *Admin) RegisterFuncMap(name string, fc interface{}) {
	admin.funcMaps[name] = fc
}
<commit_msg>Allow inject for qor admin package<commit_after>package admin

import (
	"html/template"
	"net/http"

	"github.com/qor/qor"
	"github.com/qor/qor/resource"
	"github.com/qor/qor/roles"
)

type Admin struct {
	Config    *qor.Config
	Resources map[string]*Resource
	auth      Auth
	router    *Router
	funcMaps  template.FuncMap
}

func New(config *qor.Config) *Admin {
	admin := Admin{
		Resources: map[string]*Resource{},
		funcMaps:  make(template.FuncMap),
		Config:    config,
		router:    newRouter(),
	}
	return &admin
}

func NewResource(value interface{}, names ...string) *Resource {
	res := resource.New(value, names...)
	return &Resource{
		Resource:    *res,
		cachedMetas: &map[string][]*resource.Meta{},
		scopes:      map[string]*Scope{},
		filters:     map[string]*Filter{},
		actions:     map[string]*Action{},
	}
}

type Injector interface {
	InjectQorAdmin(*Admin)
}

func (admin *Admin) NewResource(value interface{}, names ...string) *Resource {
	res := NewResource(value, names...)
	admin.Resources[res.Name] = res

	if injector, ok := value.(Injector); ok {
		injector.InjectQorAdmin(admin)
	}
	return res
}

func (admin *Admin) GetResource(name string) *Resource {
	return admin.Resources[name]
}

func (admin *Admin) UseResource(res *Resource) {
	admin.Resources[res.Name] = res
}

func (admin *Admin) SetAuth(auth Auth) {
	admin.auth = auth
}

func (admin *Admin) GetRouter() *Router {
	return admin.router
}

func (admin *Admin) NewContext(w http.ResponseWriter, r *http.Request) *Context {
	var currentUser *qor.CurrentUser
	context := Context{Context: &qor.Context{Config: admin.Config, Request: r}, Writer: w, Admin: admin}
	if admin.auth != nil {
		currentUser = admin.auth.GetCurrentUser(&context)
	}
	context.Roles = roles.MatchedRoles(r, currentUser)

	return &context
}

func (admin *Admin) RegisterFuncMap(name string, fc interface{}) {
	admin.funcMaps[name] = fc
}
<|endoftext|>


<commit_before>//This utility validates Time Zone dataset against google maps api, double check the results, sometimes false positives
package main

import (
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/url"
	"os"
	"sort"
	"strconv"
	"time"

	c "github.com/ugjka/newyearsbot/common"
)

//Set target year
var target = func() time.Time {
	tmp := time.Now().UTC()
	if tmp.Month() == time.January && tmp.Day() < 2 {
		return time.Date(tmp.Year()-1, time.January, 1, 0, 0, 0, 0, time.UTC)
	}
	return time.Date(tmp.Year()+1, time.January, 1, 0, 0, 0, 0, time.UTC)
}()

func main() {
	tzdatapath := flag.String("tzpath", "../tz.json", "path to tz.json")
	//Check if tz.json exists
	if _, err := os.Stat(*tzdatapath); os.IsNotExist(err) {
		fmt.Fprintf(os.Stderr, "Error: file %s does not exist\n", *tzdatapath)
		os.Exit(1)
	}
	var zones c.TZS
	file, err := os.Open(*tzdatapath)
	if err != nil {
		log.Fatal(err)
	}
	content, err := ioutil.ReadAll(file)
	if err != nil {
		log.Fatal(err)
	}
	if err := json.Unmarshal(content, &zones); err != nil {
		log.Fatal(err)
	}
	//print target to be sure
	fmt.Println("Target:", target)
	sort.Sort(sort.Reverse(zones))
	for _, k := range zones {
		fmt.Println("Zone:", k.Offset)
		for _, k2 := range k.Countries {
			if len(k2.Cities) == 0 {
				res, err := getTimeZone(k2.Name)
				time.Sleep(time.Second * 2)
				if err != nil {
					log.Println(err)
				} else {
					res, _ := strconv.ParseFloat(res, 64)
					koff, _ := strconv.ParseFloat(k.Offset, 64)
					if res != koff {
						fmt.Println(k2.Name, k.Offset, res)
					}
				}
			}
			for _, k3 := range k2.Cities {
				res, err := getTimeZone(k2.Name + " " + k3)
				time.Sleep(time.Second * 2)
				if err != nil {
					log.Println(err)
				} else {
					res, _ := strconv.ParseFloat(res, 64)
					koff, _ := strconv.ParseFloat(k.Offset, 64)
					if res != koff {
						fmt.Println(k2.Name, k3, k.Offset, res)
					}
				}
			}
		}
	}
}

func getTimeZone(loc string) (string, error) {
	maps := url.Values{}
	maps.Add("address", loc)
	maps.Add("sensor", "false")
	maps.Add("language", "en")
	data, err := c.Getter(c.Geocode + maps.Encode())
	if err != nil {
		return "", err
	}
	var mapj c.Gmap
	if err = json.Unmarshal(data, &mapj); err != nil {
		return "", err
	}
	if mapj.Status != "OK" {
		return "", errors.New(loc + " Status not OK")
	}
	location := fmt.Sprintf("%.7f,%.7f", mapj.Results[0].Geometry.Location.Lat, mapj.Results[0].Geometry.Location.Lng)
	tmzone := url.Values{}
	tmzone.Add("location", location)
	tmzone.Add("timestamp", fmt.Sprintf("%d", target.Unix()))
	tmzone.Add("sensor", "false")
	data, err = c.Getter(c.Timezone + tmzone.Encode())
	if err != nil {
		return "", err
	}
	var timej c.Gtime
	if err = json.Unmarshal(data, &timej); err != nil {
		return "", err
	}
	if timej.Status != "OK" {
		return "", errors.New(loc + " Couldn't get timezone info.")
	}
	var offset float64
	offset = (float64(timej.RawOffset) + float64(timej.DstOffset)) / 3600.0
	return fmt.Sprintf("%f", offset), nil
}
<commit_msg>off by one error<commit_after>//This utility validates Time Zone dataset against google maps api, double check the results, sometimes false positives
package main

import (
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/url"
	"os"
	"sort"
	"strconv"
	"time"

	c "github.com/ugjka/newyearsbot/common"
)

//Set target year
var target = func() time.Time {
	tmp := time.Now().UTC()
	if tmp.Month() == time.January && tmp.Day() < 2 {
		return time.Date(tmp.Year(), time.January, 1, 0, 0, 0, 0, time.UTC)
	}
	return time.Date(tmp.Year()+1, time.January, 1, 0, 0, 0, 0, time.UTC)
}()

func main() {
	tzdatapath := flag.String("tzpath", "../tz.json", "path to tz.json")
	//Check if tz.json exists
	if _, err := os.Stat(*tzdatapath); os.IsNotExist(err) {
		fmt.Fprintf(os.Stderr, "Error: file %s does not exist\n", *tzdatapath)
		os.Exit(1)
	}
	var zones c.TZS
	file, err := os.Open(*tzdatapath)
	if err != nil {
		log.Fatal(err)
	}
	content, err := ioutil.ReadAll(file)
	if err != nil {
		log.Fatal(err)
	}
	if err := json.Unmarshal(content, &zones); err != nil {
		log.Fatal(err)
	}
	//print target to be sure
	fmt.Println("Target:", target)
	sort.Sort(sort.Reverse(zones))
	for _, k := range zones {
		fmt.Println("Zone:", k.Offset)
		for _, k2 := range k.Countries {
			if len(k2.Cities) == 0 {
				res, err := getTimeZone(k2.Name)
				time.Sleep(time.Second * 2)
				if err != nil {
					log.Println(err)
				} else {
					res, _ := strconv.ParseFloat(res, 64)
					koff, _ := strconv.ParseFloat(k.Offset, 64)
					if res != koff {
						fmt.Println(k2.Name, k.Offset, res)
					}
				}
			}
			for _, k3 := range k2.Cities {
				res, err := getTimeZone(k2.Name + " " + k3)
				time.Sleep(time.Second * 2)
				if err != nil {
					log.Println(err)
				} else {
					res, _ := strconv.ParseFloat(res, 64)
					koff, _ := strconv.ParseFloat(k.Offset, 64)
					if res != koff {
						fmt.Println(k2.Name, k3, k.Offset, res)
					}
				}
			}
		}
	}
}

func getTimeZone(loc string) (string, error) {
	maps := url.Values{}
	maps.Add("address", loc)
	maps.Add("sensor", "false")
	maps.Add("language", "en")
	data, err := c.Getter(c.Geocode + maps.Encode())
	if err != nil {
		return "", err
	}
	var mapj c.Gmap
	if err = json.Unmarshal(data, &mapj); err != nil {
		return "", err
	}
	if mapj.Status != "OK" {
		return "", errors.New(loc + " Status not OK")
	}
	location := fmt.Sprintf("%.7f,%.7f", mapj.Results[0].Geometry.Location.Lat, mapj.Results[0].Geometry.Location.Lng)
	tmzone := url.Values{}
	tmzone.Add("location", location)
	tmzone.Add("timestamp", fmt.Sprintf("%d", target.Unix()))
	tmzone.Add("sensor", "false")
	data, err = c.Getter(c.Timezone + tmzone.Encode())
	if err != nil {
		return "", err
	}
	var timej c.Gtime
	if err = json.Unmarshal(data, &timej); err != nil {
		return "", err
	}
	if timej.Status != "OK" {
		return "", errors.New(loc + " Couldn't get timezone info.")
	}
	var offset float64
	offset = (float64(timej.RawOffset) + float64(timej.DstOffset)) / 3600.0
	return fmt.Sprintf("%f", offset), nil
}
<|endoftext|>


<commit_before>package collector

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"strings"
	"sync"
	"time"

	grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
	"github.com/karimra/gnmic/outputs"
	"github.com/openconfig/gnmi/proto/gnmi"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"google.golang.org/grpc"
)

// Config is the collector config
type Config struct {
	PrometheusAddress string
	Debug             bool
}

// Collector //
type Collector struct {
	Config        *Config
	Subscriptions map[string]*SubscriptionConfig
	Outputs       map[string][]outputs.Output
	DialOpts      []grpc.DialOption
	//
	m             *sync.Mutex
	Targets       map[string]*Target
	Logger        *log.Logger
	httpServer    *http.Server
	defaultOutput io.Writer
	ctx           context.Context
	cancelFn      context.CancelFunc
}

// NewCollector //
func NewCollector(ctx context.Context,
	config *Config,
	targetConfigs map[string]*TargetConfig,
	subscriptions map[string]*SubscriptionConfig,
	outputs map[string][]outputs.Output,
	dialOpts []grpc.DialOption,
	logger *log.Logger,
) *Collector {
	nctx, cancel := context.WithCancel(ctx)
	grpcMetrics := grpc_prometheus.NewClientMetrics()
	reg := prometheus.NewRegistry()
	reg.MustRegister(prometheus.NewGoCollector())
	grpcMetrics.EnableClientHandlingTimeHistogram()
	reg.MustRegister(grpcMetrics)
	httpServer := &http.Server{
		Handler: promhttp.HandlerFor(reg, promhttp.HandlerOpts{}),
		Addr:    config.PrometheusAddress,
	}
	dialOpts = append(dialOpts, grpc.WithStreamInterceptor(grpcMetrics.StreamClientInterceptor()))
	c := &Collector{
		Config:        config,
		Subscriptions: subscriptions,
		Outputs:       outputs,
		DialOpts:      dialOpts,
		m:             new(sync.Mutex),
		Targets:       make(map[string]*Target),
		Logger:        logger,
		httpServer:    httpServer,
		defaultOutput: os.Stdout,
		ctx:           nctx,
		cancelFn:      cancel,
	}
	wg := new(sync.WaitGroup)
	wg.Add(len(targetConfigs))
	for _, tc := range targetConfigs {
		go func(tc *TargetConfig) {
			defer wg.Done()
			err := c.InitTarget(tc)
			if err == context.DeadlineExceeded {
				c.Logger.Printf("failed to initialize target '%s' timeout (%s) reached: %v", tc.Name, tc.Timeout, err)
				return
			}
			if err != nil {
				c.Logger.Printf("failed to initialize target '%s': %v", tc.Name, err)
				return
			}
			c.Logger.Printf("target '%s' initialized", tc.Name)
		}(tc)
	}
	wg.Wait()
	return c
}

// InitTarget initializes a target based on *TargetConfig
func (c *Collector) InitTarget(tc *TargetConfig) error {
	t := NewTarget(tc)
	//
	t.Subscriptions = make([]*SubscriptionConfig, 0, len(tc.Subscriptions))
	for _, subName := range tc.Subscriptions {
		if sub, ok := c.Subscriptions[subName]; ok {
			t.Subscriptions = append(t.Subscriptions, sub)
		}
	}
	if len(t.Subscriptions) == 0 {
		t.Subscriptions = make([]*SubscriptionConfig, 0, len(c.Subscriptions))
		for _, sub := range c.Subscriptions {
			t.Subscriptions = append(t.Subscriptions, sub)
		}
	}
	//
	t.Outputs = make([]outputs.Output, 0, len(tc.Outputs))
	for _, outName := range tc.Outputs {
		if outs, ok := c.Outputs[outName]; ok {
			t.Outputs = append(t.Outputs, outs...)
		}
	}
	if len(t.Outputs) == 0 {
		t.Outputs = make([]outputs.Output, 0, len(c.Outputs))
		for _, o := range c.Outputs {
			t.Outputs = append(t.Outputs, o...)
		}
	}
	//
	err := t.CreateGNMIClient(c.ctx, c.DialOpts...)
	if err != nil {
		return err
	}
	t.ctx, t.cancelFn = context.WithCancel(c.ctx)
	c.m.Lock()
	defer c.m.Unlock()
	c.Targets[t.Config.Name] = t
	return nil
}

// Subscribe //
func (c *Collector) Subscribe(tName string) error {
	if t, ok := c.Targets[tName]; ok {
		for _, sc := range t.Subscriptions {
			req, err := sc.CreateSubscribeRequest()
			if err != nil {
				return err
			}
			go t.Subscribe(c.ctx, req, sc.Name)
		}
		return nil
	}
	return fmt.Errorf("unknown target name: %s", tName)
}

// Start start the prometheus server as well as a goroutine per target selecting on the response chan, the error chan and the ctx.Done() chan
func (c *Collector) Start() {
	go func() {
		if err := c.httpServer.ListenAndServe(); err != nil {
			c.Logger.Printf("Unable to start prometheus http server: %v", err)
			return
		}
	}()
	wg := new(sync.WaitGroup)
	wg.Add(len(c.Targets))
	for _, t := range c.Targets {
		go func(t *Target) {
			defer wg.Done()
			numOnceSubscriptions := t.numberOfOnceSubscriptions()
			remainingOnceSubscriptions := numOnceSubscriptions
			numSubscriptions := len(t.Subscriptions)
			for {
				select {
				case rsp := <-t.SubscribeResponses:
					m := make(map[string]interface{})
					m["subscription-name"] = rsp.SubscriptionName
					m["source"] = t.Config.Name
					b, err := c.FormatMsg(m, rsp.Response)
					if err != nil {
						c.Logger.Printf("failed formatting msg from target '%s': %v", t.Config.Name, err)
						continue
					}
					go t.Export(b, outputs.Meta{"source": t.Config.Name})
					if remainingOnceSubscriptions > 0 {
						if c.subscriptionMode(rsp.SubscriptionName) == "ONCE" {
							switch rsp.Response.Response.(type) {
							case *gnmi.SubscribeResponse_SyncResponse:
								remainingOnceSubscriptions--
							}
						}
					}
					if remainingOnceSubscriptions == 0 && numSubscriptions == numOnceSubscriptions {
						return
					}
				case err := <-t.Errors:
					if err == io.EOF {
						c.Logger.Printf("target '%s' closed stream(EOF)", t.Config.Name)
						return
					}
					c.Logger.Printf("target '%s' error: %v", t.Config.Name, err)
				case <-t.ctx.Done():
					return
				}
			}
		}(t)
	}
	wg.Wait()
}

// FormatMsg formats the gnmi.SubscribeResponse and returns a []byte and an error
func (c *Collector) FormatMsg(meta map[string]interface{}, rsp *gnmi.SubscribeResponse) ([]byte, error) {
	if rsp == nil {
		return nil, nil
	}
	switch rsp := rsp.Response.(type) {
	case *gnmi.SubscribeResponse_Update:
		msg := new(msg)
		msg.Timestamp = rsp.Update.Timestamp
		t := time.Unix(0, rsp.Update.Timestamp)
		msg.Time = &t
		if meta == nil {
			meta = make(map[string]interface{})
		}
		msg.Prefix = gnmiPathToXPath(rsp.Update.Prefix)
		var ok bool
		if _, ok = meta["source"]; ok {
			msg.Source = fmt.Sprintf("%s", meta["source"])
		}
		if _, ok = meta["system-name"]; ok {
			msg.SystemName = fmt.Sprintf("%s", meta["system-name"])
		}
		if _, ok = meta["subscription-name"]; ok {
			msg.SubscriptionName = fmt.Sprintf("%s", meta["subscription-name"])
		}
		for i, upd := range rsp.Update.Update {
			pathElems := make([]string, 0, len(upd.Path.Elem))
			for _, pElem := range upd.Path.Elem {
				pathElems = append(pathElems, pElem.GetName())
			}
			value, err := getValue(upd.Val)
			if err != nil {
				c.Logger.Println(err)
			}
			msg.Updates = append(msg.Updates,
				&update{
					Path:   gnmiPathToXPath(upd.Path),
					Values: make(map[string]interface{}),
				})
			msg.Updates[i].Values[strings.Join(pathElems, "/")] = value
		}
		for _, del := range rsp.Update.Delete {
			msg.Deletes = append(msg.Deletes, gnmiPathToXPath(del))
		}
		data, err := json.Marshal(msg)
		if err != nil {
			return nil, err
		}
		return data, nil
	}
	return nil, nil
}

// TargetPoll sends a gnmi.SubscribeRequest_Poll to targetName and returns the response and an error,
// it uses the targetName and the subscriptionName strings to find the gnmi.GNMI_SubscribeClient
func (c *Collector) TargetPoll(targetName, subscriptionName string) (*gnmi.SubscribeResponse, error) {
	if sub, ok := c.Subscriptions[subscriptionName]; ok {
		if strings.ToUpper(sub.Mode) != "POLL" {
			return nil, fmt.Errorf("subscription '%s' is not a POLL subscription", subscriptionName)
		}
		if t, ok := c.Targets[targetName]; ok {
			if subClient, ok := t.SubscribeClients[subscriptionName]; ok {
				err := subClient.Send(&gnmi.SubscribeRequest{
					Request: &gnmi.SubscribeRequest_Poll{
						Poll: &gnmi.Poll{},
					},
				})
				if err != nil {
					return nil, err
				}
				return subClient.Recv()
			}
		}
		return nil, fmt.Errorf("unknown target name '%s'", targetName)
	}
	return nil, fmt.Errorf("unknown subscription name '%s'", subscriptionName)
}

// PolledSubscriptionsTargets returns a map of target name to a list of subscription names that have Mode == POLL
func (c *Collector) PolledSubscriptionsTargets() map[string][]string {
	result := make(map[string][]string)
	for tn, target := range c.Targets {
		for _, sub := range target.Subscriptions {
			if strings.ToUpper(sub.Mode) == "POLL" {
				if result[tn] == nil {
					result[tn] = make([]string, 0)
				}
				result[tn] = append(result[tn], sub.Name)
			}
		}
	}
	return result
}

func (c *Collector) subscriptionMode(name string) string {
	if sub, ok := c.Subscriptions[name]; ok {
		return strings.ToUpper(sub.Mode)
	}
	return ""
}
<commit_msg>move prometheus endpoint to /metrics<commit_after>package collector

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"strings"
	"sync"
	"time"

	grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
	"github.com/karimra/gnmic/outputs"
	"github.com/openconfig/gnmi/proto/gnmi"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"google.golang.org/grpc"
)

// Config is the collector config
type Config struct {
	PrometheusAddress string
	Debug             bool
}

// Collector //
type Collector struct {
	Config        *Config
	Subscriptions map[string]*SubscriptionConfig
	Outputs       map[string][]outputs.Output
	DialOpts      []grpc.DialOption
	//
	m             *sync.Mutex
	Targets       map[string]*Target
	Logger        *log.Logger
	httpServer    *http.Server
	defaultOutput io.Writer
	ctx           context.Context
	cancelFn      context.CancelFunc
}

// NewCollector //
func NewCollector(ctx context.Context,
	config *Config,
	targetConfigs map[string]*TargetConfig,
	subscriptions map[string]*SubscriptionConfig,
	outputs map[string][]outputs.Output,
	dialOpts []grpc.DialOption,
	logger *log.Logger,
) *Collector {
	nctx, cancel := context.WithCancel(ctx)
	grpcMetrics := grpc_prometheus.NewClientMetrics()
	reg := prometheus.NewRegistry()
	reg.MustRegister(prometheus.NewGoCollector())
	grpcMetrics.EnableClientHandlingTimeHistogram()
	reg.MustRegister(grpcMetrics)
	handler := http.NewServeMux()
	handler.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{}))
	httpServer := &http.Server{
		Handler: handler,
		Addr:    config.PrometheusAddress,
	}
	dialOpts = append(dialOpts, grpc.WithStreamInterceptor(grpcMetrics.StreamClientInterceptor()))
	c := &Collector{
		Config:        config,
		Subscriptions: subscriptions,
		Outputs:       outputs,
		DialOpts:      dialOpts,
		m:             new(sync.Mutex),
		Targets:       make(map[string]*Target),
		Logger:        logger,
		httpServer:    httpServer,
		defaultOutput: os.Stdout,
		ctx:           nctx,
		cancelFn:      cancel,
	}
	wg := new(sync.WaitGroup)
	wg.Add(len(targetConfigs))
	for _, tc := range targetConfigs {
		go func(tc *TargetConfig) {
			defer wg.Done()
			err := c.InitTarget(tc)
			if err == context.DeadlineExceeded {
				c.Logger.Printf("failed to initialize target '%s' timeout (%s) reached: %v", tc.Name, tc.Timeout, err)
				return
			}
			if err != nil {
				c.Logger.Printf("failed to initialize target '%s': %v", tc.Name, err)
				return
			}
			c.Logger.Printf("target '%s' initialized", tc.Name)
		}(tc)
	}
	wg.Wait()
	return c
}

// InitTarget initializes a target based on *TargetConfig
func (c *Collector) InitTarget(tc *TargetConfig) error {
	t := NewTarget(tc)
	//
	t.Subscriptions = make([]*SubscriptionConfig, 0, len(tc.Subscriptions))
	for _, subName := range tc.Subscriptions {
		if sub, ok := c.Subscriptions[subName]; ok {
			t.Subscriptions = append(t.Subscriptions, sub)
		}
	}
	if len(t.Subscriptions) == 0 {
		t.Subscriptions = make([]*SubscriptionConfig, 0, len(c.Subscriptions))
		for _, sub := range c.Subscriptions {
			t.Subscriptions = append(t.Subscriptions, sub)
		}
	}
	//
	t.Outputs = make([]outputs.Output, 0, len(tc.Outputs))
	for _, outName := range tc.Outputs {
		if outs, ok := c.Outputs[outName]; ok {
			t.Outputs = append(t.Outputs, outs...)
		}
	}
	if len(t.Outputs) == 0 {
		t.Outputs = make([]outputs.Output, 0, len(c.Outputs))
		for _, o := range c.Outputs {
			t.Outputs = append(t.Outputs, o...)
		}
	}
	//
	err := t.CreateGNMIClient(c.ctx, c.DialOpts...)
	if err != nil {
		return err
	}
	t.ctx, t.cancelFn = context.WithCancel(c.ctx)
	c.m.Lock()
	defer c.m.Unlock()
	c.Targets[t.Config.Name] = t
	return nil
}

// Subscribe //
func (c *Collector) Subscribe(tName string) error {
	if t, ok := c.Targets[tName]; ok {
		for _, sc := range t.Subscriptions {
			req, err := sc.CreateSubscribeRequest()
			if err != nil {
				return err
			}
			go t.Subscribe(c.ctx, req, sc.Name)
		}
		return nil
	}
	return fmt.Errorf("unknown target name: %s", tName)
}

// Start start the prometheus server as well as a goroutine per target selecting on the response chan, the error chan and the ctx.Done() chan
func (c *Collector) Start() {
	go func() {
		if err := c.httpServer.ListenAndServe(); err != nil {
			c.Logger.Printf("Unable to start prometheus http server: %v", err)
			return
		}
	}()
	wg := new(sync.WaitGroup)
	wg.Add(len(c.Targets))
	for _, t := range c.Targets {
		go func(t *Target) {
			defer wg.Done()
			numOnceSubscriptions := t.numberOfOnceSubscriptions()
			remainingOnceSubscriptions := numOnceSubscriptions
			numSubscriptions := len(t.Subscriptions)
			for {
				select {
				case rsp := <-t.SubscribeResponses:
					m := make(map[string]interface{})
					m["subscription-name"] = rsp.SubscriptionName
					m["source"] = t.Config.Name
					b, err := c.FormatMsg(m, rsp.Response)
					if err != nil {
						c.Logger.Printf("failed formatting msg from target '%s': %v", t.Config.Name, err)
						continue
					}
					go t.Export(b, outputs.Meta{"source": t.Config.Name})
					if remainingOnceSubscriptions > 0 {
						if c.subscriptionMode(rsp.SubscriptionName) == "ONCE" {
							switch rsp.Response.Response.(type) {
							case *gnmi.SubscribeResponse_SyncResponse:
								remainingOnceSubscriptions--
							}
						}
					}
					if remainingOnceSubscriptions == 0 && numSubscriptions == numOnceSubscriptions {
						return
					}
				case err := <-t.Errors:
					if err == io.EOF {
						c.Logger.Printf("target '%s' closed stream(EOF)", t.Config.Name)
						return
					}
					c.Logger.Printf("target '%s' error: %v", t.Config.Name, err)
				case <-t.ctx.Done():
					return
				}
			}
		}(t)
	}
	wg.Wait()
}

// FormatMsg formats the gnmi.SubscribeResponse and returns a []byte and an error
func (c *Collector) FormatMsg(meta map[string]interface{}, rsp *gnmi.SubscribeResponse) ([]byte, error) {
	if rsp == nil {
		return nil, nil
	}
	switch rsp := rsp.Response.(type) {
	case *gnmi.SubscribeResponse_Update:
		msg := new(msg)
		msg.Timestamp = rsp.Update.Timestamp
		t := time.Unix(0, rsp.Update.Timestamp)
		msg.Time = &t
		if meta == nil {
			meta = make(map[string]interface{})
		}
		msg.Prefix = gnmiPathToXPath(rsp.Update.Prefix)
		var ok bool
		if _, ok = meta["source"]; ok {
			msg.Source = fmt.Sprintf("%s", meta["source"])
		}
		if _, ok = meta["system-name"]; ok {
			msg.SystemName = fmt.Sprintf("%s", meta["system-name"])
		}
		if _, ok = meta["subscription-name"]; ok {
			msg.SubscriptionName = fmt.Sprintf("%s", meta["subscription-name"])
		}
		for i, upd := range rsp.Update.Update {
			pathElems := make([]string, 0, len(upd.Path.Elem))
			for _, pElem := range upd.Path.Elem {
				pathElems = append(pathElems, pElem.GetName())
			}
			value, err := getValue(upd.Val)
			if err != nil {
				c.Logger.Println(err)
			}
			msg.Updates = append(msg.Updates,
				&update{
					Path:   gnmiPathToXPath(upd.Path),
					Values: make(map[string]interface{}),
				})
			msg.Updates[i].Values[strings.Join(pathElems, "/")] = value
		}
		for _, del := range rsp.Update.Delete {
			msg.Deletes = append(msg.Deletes, gnmiPathToXPath(del))
		}
		data, err := json.Marshal(msg)
		if err != nil {
			return nil, err
		}
		return data, nil
	}
	return nil, nil
}

// TargetPoll sends a gnmi.SubscribeRequest_Poll to targetName and returns the response and an error,
// it uses the targetName and the subscriptionName strings to find the gnmi.GNMI_SubscribeClient
func (c *Collector) TargetPoll(targetName, subscriptionName string) (*gnmi.SubscribeResponse, error) {
	if sub, ok := c.Subscriptions[subscriptionName]; ok {
		if strings.ToUpper(sub.Mode) != "POLL" {
			return nil, fmt.Errorf("subscription '%s' is not a POLL subscription", subscriptionName)
		}
		if t, ok := c.Targets[targetName]; ok {
			if subClient, ok := t.SubscribeClients[subscriptionName]; ok {
				err := subClient.Send(&gnmi.SubscribeRequest{
					Request: &gnmi.SubscribeRequest_Poll{
						Poll: &gnmi.Poll{},
					},
				})
				if err != nil {
					return nil, err
				}
				return subClient.Recv()
			}
		}
		return nil, fmt.Errorf("unknown target name '%s'", targetName)
	}
	return nil, fmt.Errorf("unknown subscription name '%s'", subscriptionName)
}

// PolledSubscriptionsTargets returns a map of target name to a list of subscription names that have Mode == POLL
func (c *Collector) PolledSubscriptionsTargets() map[string][]string {
	result := make(map[string][]string)
	for tn, target := range c.Targets {
		for _, sub := range target.Subscriptions {
			if strings.ToUpper(sub.Mode) == "POLL" {
				if result[tn] == nil {
					result[tn] = make([]string, 0)
				}
				result[tn] = append(result[tn], sub.Name)
			}
		}
	}
	return result
}

func (c *Collector) subscriptionMode(name string) string {
	if sub, ok := c.Subscriptions[name]; ok {
		return strings.ToUpper(sub.Mode)
	}
	return ""
}
<|endoftext|>


<commit_before>package command

import (
	"fmt"
	"github.com/buildkite/agent/buildkite"
	"github.com/buildkite/agent/buildkite/logger"
	"github.com/codegangsta/cli"
	"os"
	"time"
)

func AgentStartCommandAction(c *cli.Context) {
	// For display purposes, come up with what the name of the agent is.
	// agentName, err := buildkite.MachineHostname()
	// if c.String("name") != "" {
	// 	agentName = c.String("name")
	// }

	// Toggle colors
	if c.Bool("no-color") {
		logger.SetColors(false)
	}

	welcomeMessage :=
		"\n" +
			"\x1b[32m  _           _ _     _ _    _ _                                _\n" +
			" | |         (_) |   | | |  (_) |                              | |\n" +
			" | |__  _   _ _| | __| | | ___| |_ ___    __ _  __ _  ___ _ __ | |_\n" +
			" | '_ \\| | | | | |/ _` | |/ / | __/ _ \\  / _` |/ _` |/ _ \\ '_ \\| __|\n" +
			" | |_) | |_| | | | (_| |   <| | ||  __/ | (_| | (_| |  __/ | | | |_\n" +
			" |_.__/ \\__,_|_|_|\\__,_|_|\\_\\_|\\__\\___|  \\__,_|\\__, |\\___|_| |_|\\__|\n" +
			"                                                __/ |\n" +
			" http://buildkite.com/agent                    |___/\n\x1b[0m\n"

	fmt.Printf(welcomeMessage)

	logger.Notice("Starting buildkite-agent v%s with PID: %s", buildkite.Version(), fmt.Sprintf("%d", os.Getpid()))
	logger.Notice("Copyright (c) 2014-%d, Buildkite Pty Ltd. See LICENSE and for more details.", time.Now().Year())
	logger.Notice("For questions and support, email us at: hello@buildkite.com")

	// Init debugging
	if c.Bool("debug") {
		logger.SetLevel(logger.DEBUG)
	}

	// Create the agent
	if c.String("access-token") != "" {
		fmt.Println("buildkite-agent: use of --access-token is now deprecated\nSee 'buildkite-agent start --help'")
		os.Exit(1)
	}

	agentRegistrationToken := c.String("token")
	if agentRegistrationToken == "" {
		fmt.Println("buildkite-agent: missing token\nSee 'buildkite-agent start --help'")
		os.Exit(1)
	}

	// Expand the envionment variable.
	bootstrapScript := os.ExpandEnv(c.String("bootstrap-script"))

	// Make sure the boostrap script exists.
	if _, err := os.Stat(bootstrapScript); os.IsNotExist(err) {
		fmt.Printf("buildkite-agent: could not find bootstrap script %s\n", bootstrapScript)
		os.Exit(1)
	}

	logger.Debug("Bootstrap script: %s", bootstrapScript)

	// Expand the build path. We don't bother checking to see if it can be
	// written to, because it'll show up in the agent logs if it doesn't
	// work.
	buildPath := os.ExpandEnv(c.String("build-path"))
	logger.Debug("Build path: %s", buildPath)

	// Expand the hooks path that is used by the bootstrap script
	hooksPath := os.ExpandEnv(c.String("hooks-path"))
	logger.Debug("Hooks directory: %s", hooksPath)

	// Create a client so we can register the agent
	var client buildkite.Client
	client.AuthorizationToken = agentRegistrationToken
	client.URL = c.String("endpoint")

	agentMetaData := c.StringSlice("meta-data")

	// Should we try and grab the ec2 tags as well?
	if c.Bool("meta-data-ec2-tags") {
		tags, err := buildkite.EC2InstanceTags()

		if err != nil {
			// Don't blow up if we can't find them, just show a nasty error.
			logger.Error(fmt.Sprintf("Failed to find EC2 Tags: %s", err.Error()))
		} else {
			for tag, value := range tags {
				agentMetaData = append(agentMetaData, fmt.Sprintf("%s=%s", tag, value))
			}
		}
	}

	// Set the agent options
	var agent buildkite.Agent
	agent.BootstrapScript = bootstrapScript
	agent.BuildPath = buildPath
	agent.HooksPath = hooksPath

	if buildkite.MachineIsWindows() {
		agent.RunInPty = false
	} else {
		agent.RunInPty = !c.Bool("no-pty")
	}

	agent.AutoSSHFingerprintVerification = !c.Bool("no-automatic-ssh-fingerprint-verification")
	agent.ScriptEval = !c.Bool("no-script-eval")

	if !agent.ScriptEval {
		logger.Info("Evaluating scripts has been disabled for this agent")
	}

	// Register the agent
	agentAccessToken, err := client.AgentRegister(c.String("name"), c.String("priority"), agentMetaData, agent.ScriptEval)
	if err != nil {
		logger.Fatal("%s", err)
	}

	// Client specific options
	agent.Client.AuthorizationToken = agentAccessToken
	agent.Client.URL = c.String("endpoint")

	// Setup the agent
	agent.Setup()

	// Setup signal monitoring
	agent.MonitorSignals()

	// Start the agent
	agent.Start()
}
<commit_msg>Simplified error handling.<commit_after>package command

import (
	"fmt"
	"github.com/buildkite/agent/buildkite"
	"github.com/buildkite/agent/buildkite/logger"
	"github.com/codegangsta/cli"
	"os"
	"time"
)

func AgentStartCommandAction(c *cli.Context) {
	// For display purposes, come up with what the name of the agent is.
	// agentName, err := buildkite.MachineHostname()
	// if c.String("name") != "" {
	// 	agentName = c.String("name")
	// }

	// Toggle colors
	if c.Bool("no-color") {
		logger.SetColors(false)
	}

	welcomeMessage :=
		"\n" +
			"\x1b[32m  _           _ _     _ _    _ _                                _\n" +
			" | |         (_) |   | | |  (_) |                              | |\n" +
			" | |__  _   _ _| | __| | | ___| |_ ___    __ _  __ _  ___ _ __ | |_\n" +
			" | '_ \\| | | | | |/ _` | |/ / | __/ _ \\  / _` |/ _` |/ _ \\ '_ \\| __|\n" +
			" | |_) | |_| | | | (_| |   <| | ||  __/ | (_| | (_| |  __/ | | | |_\n" +
			" |_.__/ \\__,_|_|_|\\__,_|_|\\_\\_|\\__\\___|  \\__,_|\\__, |\\___|_| |_|\\__|\n" +
			"                                                __/ |\n" +
			" http://buildkite.com/agent                    |___/\n\x1b[0m\n"

	fmt.Printf(welcomeMessage)

	logger.Notice("Starting buildkite-agent v%s with PID: %s", buildkite.Version(), fmt.Sprintf("%d", os.Getpid()))
	logger.Notice("Copyright (c) 2014-%d, Buildkite Pty Ltd. See LICENSE and for more details.", time.Now().Year())
	logger.Notice("For questions and support, email us at: hello@buildkite.com")

	// Init debugging
	if c.Bool("debug") {
		logger.SetLevel(logger.DEBUG)
	}

	// Create the agent
	if c.String("access-token") != "" {
		fmt.Println("buildkite-agent: use of --access-token is now deprecated\nSee 'buildkite-agent start --help'")
		os.Exit(1)
	}

	agentRegistrationToken := c.String("token")
	if agentRegistrationToken == "" {
		logger.Fatal("Missing --token. See 'buildkite-agent start --help'")
	}

	// Expand the envionment variable.
	bootstrapScript := os.ExpandEnv(c.String("bootstrap-script"))

	// Make sure the boostrap script exists.
	if _, err := os.Stat(bootstrapScript); os.IsNotExist(err) {
		logger.Fatal("Could not find a bootstrap script located at: %s", bootstrapScript)
	}

	logger.Debug("Bootstrap script: %s", bootstrapScript)

	// Expand the build path. We don't bother checking to see if it can be
	// written to, because it'll show up in the agent logs if it doesn't
	// work.
	buildPath := os.ExpandEnv(c.String("build-path"))
	logger.Debug("Build path: %s", buildPath)

	// Expand the hooks path that is used by the bootstrap script
	hooksPath := os.ExpandEnv(c.String("hooks-path"))
	logger.Debug("Hooks directory: %s", hooksPath)

	// Create a client so we can register the agent
	var client buildkite.Client
	client.AuthorizationToken = agentRegistrationToken
	client.URL = c.String("endpoint")

	agentMetaData := c.StringSlice("meta-data")

	// Should we try and grab the ec2 tags as well?
	if c.Bool("meta-data-ec2-tags") {
		tags, err := buildkite.EC2InstanceTags()

		if err != nil {
			// Don't blow up if we can't find them, just show a nasty error.
			logger.Error(fmt.Sprintf("Failed to find EC2 Tags: %s", err.Error()))
		} else {
			for tag, value := range tags {
				agentMetaData = append(agentMetaData, fmt.Sprintf("%s=%s", tag, value))
			}
		}
	}

	// Set the agent options
	var agent buildkite.Agent
	agent.BootstrapScript = bootstrapScript
	agent.BuildPath = buildPath
	agent.HooksPath = hooksPath

	if buildkite.MachineIsWindows() {
		agent.RunInPty = false
	} else {
		agent.RunInPty = !c.Bool("no-pty")
	}

	agent.AutoSSHFingerprintVerification = !c.Bool("no-automatic-ssh-fingerprint-verification")
	agent.ScriptEval = !c.Bool("no-script-eval")

	if !agent.ScriptEval {
		logger.Info("Evaluating scripts has been disabled for this agent")
	}

	// Register the agent
	agentAccessToken, err := client.AgentRegister(c.String("name"), c.String("priority"), agentMetaData, agent.ScriptEval)
	if err != nil {
		logger.Fatal("%s", err)
	}

	// Client specific options
	agent.Client.AuthorizationToken = agentAccessToken
	agent.Client.URL = c.String("endpoint")

	// Setup the agent
	agent.Setup()

	// Setup signal monitoring
	agent.MonitorSignals()

	// Start the agent
	agent.Start()
}
<|endoftext|>


<commit_before>package command

import (
	"testing"
	"fmt"
)

type OutputTest struct {
	XMLName    string           `json:"-"           xml:"test"`
	TestString string           `json:"test_string" xml:"test_string"`
	TestInt    int              `json:"test_int"    xml:"test_int"`
	TestNil    []byte           `json:"test_nil"    xml:"test_nil"`
	TestNested OutputTestNested `json:"nested"      xml:"nested"`
}

type OutputTestNested struct {
	NestKey string `json:"nest_key" xml:"nest_key"`
}

func (o OutputTest) String() string {
	return fmt.Sprintf("%s    %d    %s", o.TestString, o.TestInt, o.TestNil)
}

func TestCommandOutput(t *testing.T) {
	var formatted []byte
	result := OutputTest{
		TestString: "woooo a string",
		TestInt:    77,
		TestNil:    nil,
		TestNested: OutputTestNested{
			NestKey: "nest_value",
		},
	}

	json_expected := `{
  "test_string": "woooo a string",
  "test_int": 77,
  "test_nil": null,
  "nested": {
    "nest_key": "nest_value"
  }
}`
	formatted, _ = formatOutput(result, "json")
	if string(formatted) != json_expected {
		t.Fatalf("bad json:\n%s\n\nexpected:\n%s", formatted, json_expected)
	}

	text_expected := "woooo a string    77"
	formatted, _ = formatOutput(result, "text")
	if string(formatted) != text_expected {
		t.Fatalf("bad output:\n\"%s\"\n\nexpected:\n\"%s\"", formatted, text_expected)
	}

	error_expected := `Invalid output format "boo"`
	_, err := formatOutput(result, "boo")
	if err.Error() != error_expected {
		t.Fatalf("bad output:\n\"%s\"\n\nexpected:\n\"%s\"", err.Error(), error_expected)
	}
}
<commit_msg>Removed xml tags from test structs in output_test.go<commit_after>package command

import (
	"testing"
	"fmt"
)

type OutputTest struct {
	XMLName    string           `json:"-"`
	TestString string           `json:"test_string"`
	TestInt    int              `json:"test_int"`
	TestNil    []byte           `json:"test_nil"`
	TestNested OutputTestNested `json:"nested"`
}

type OutputTestNested struct {
	NestKey string `json:"nest_key"`
}

func (o OutputTest) String() string {
	return fmt.Sprintf("%s    %d    %s", o.TestString, o.TestInt, o.TestNil)
}

func TestCommandOutput(t *testing.T) {
	var formatted []byte
	result := OutputTest{
		TestString: "woooo a string",
		TestInt:    77,
		TestNil:    nil,
		TestNested: OutputTestNested{
			NestKey: "nest_value",
		},
	}

	json_expected := `{
  "test_string": "woooo a string",
  "test_int": 77,
  "test_nil": null,
  "nested": {
    "nest_key": "nest_value"
  }
}`
	formatted, _ = formatOutput(result, "json")
	if string(formatted) != json_expected {
		t.Fatalf("bad json:\n%s\n\nexpected:\n%s", formatted, json_expected)
	}

	text_expected := "woooo a string    77"
	formatted, _ = formatOutput(result, "text")
	if string(formatted) != text_expected {
		t.Fatalf("bad output:\n\"%s\"\n\nexpected:\n\"%s\"", formatted, text_expected)
	}

	error_expected := `Invalid output format "boo"`
	_, err := formatOutput(result, "boo")
	if err.Error() != error_expected {
		t.Fatalf("bad output:\n\"%s\"\n\nexpected:\n\"%s\"", err.Error(), error_expected)
	}
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"

	"github.com/hashicorp/terraform/flatmap"
	"github.com/hashicorp/terraform/helper/diff"
	"github.com/hashicorp/terraform/terraform"
	"github.com/mitchellh/goamz/elb"
)

func resource_aws_elb_create(
	s *terraform.ResourceState,
	d *terraform.ResourceDiff,
	meta interface{}) (*terraform.ResourceState, error) {
	p := meta.(*ResourceProvider)
	elbconn := p.elbconn

	// Merge the diff into the state so that we have all the attributes
	// properly.
	rs := s.MergeDiff(d)

	// The name specified for the ELB. This is also our unique ID
	// we save to state if the creation is succesful (amazon verifies
	// it is unique)
	elbName := rs.Attributes["name"]

	// Expand the "listener" array to goamz compat []elb.Listener
	v := flatmap.Expand(rs.Attributes, "listener").([]interface{})
	listeners := expandListeners(v)

	v = flatmap.Expand(rs.Attributes, "availability_zones").([]interface{})
	zones := expandStringList(v)

	// Provision the elb
	elbOpts := &elb.CreateLoadBalancer{
		LoadBalancerName: elbName,
		Listeners:        listeners,
		AvailZone:        zones,
	}

	log.Printf("[DEBUG] ELB create configuration: %#v", elbOpts)

	_, err := elbconn.CreateLoadBalancer(elbOpts)
	if err != nil {
		return nil, fmt.Errorf("Error creating ELB: %s", err)
	}

	// Assign the elb's unique identifer for use later
	rs.ID = elbName
	log.Printf("[INFO] ELB ID: %s", elbName)

	// If we have any instances, we need to register them
	v = flatmap.Expand(rs.Attributes, "instances").([]interface{})
	instances := expandStringList(v)

	if len(instances) > 0 {
		registerInstancesOpts := elb.RegisterInstancesWithLoadBalancer{
			LoadBalancerName: elbName,
			Instances:        instances,
		}

		_, err := elbconn.RegisterInstancesWithLoadBalancer(&registerInstancesOpts)

		if err != nil {
			return nil, fmt.Errorf("Failure registering instances: %s", err)
		}
	}

	describeElbOpts := &elb.DescribeLoadBalancer{
		Names: []string{elbName},
	}

	// Retrieve the ELB properties for updating the state
	describeResp, err := elbconn.DescribeLoadBalancers(describeElbOpts)
	if err != nil {
		return nil, fmt.Errorf("Error retrieving ELB: %s", err)
	}

	loadBalancer := describeResp.LoadBalancers[0]

	// Verify AWS returned our ELB
	if len(describeResp.LoadBalancers) != 1 ||
		describeResp.LoadBalancers[0].LoadBalancerName != elbName {
		if err != nil {
			return nil, fmt.Errorf("Unable to find ELB: %#v", describeResp.LoadBalancers)
		}
	}

	return resource_aws_elb_update_state(rs, &loadBalancer)
}

func resource_aws_elb_update(
	s *terraform.ResourceState,
	d *terraform.ResourceDiff,
	meta interface{}) (*terraform.ResourceState, error) {
	// p := meta.(*ResourceProvider)
	// elbconn := p.elbconn

	// Merge the diff into the state so that we have all the attributes
	// properly.
	// rs := s.MergeDiff(d)

	return nil, nil
}

func resource_aws_elb_destroy(
	s *terraform.ResourceState,
	meta interface{}) error {

	return nil
}

func resource_aws_elb_refresh(
	s *terraform.ResourceState,
	meta interface{}) (*terraform.ResourceState, error) {

	loadBalancer := &elb.LoadBalancer{}

	return resource_aws_elb_update_state(s, loadBalancer)
}

func resource_aws_elb_diff(
	s *terraform.ResourceState,
	c *terraform.ResourceConfig,
	meta interface{}) (*terraform.ResourceDiff, error) {

	b := &diff.ResourceBuilder{
		Attrs: map[string]diff.AttrType{
			"name":              diff.AttrTypeCreate,
			"availability_zone": diff.AttrTypeCreate,
			"listener":          diff.AttrTypeCreate,
			"instances":         diff.AttrTypeUpdate,
		},

		ComputedAttrs: []string{
			"dns_name",
		},
	}

	return b.Diff(s, c)
}

func resource_aws_elb_update_state(
	s *terraform.ResourceState,
	balancer *elb.LoadBalancer) (*terraform.ResourceState, error) {
	s.Attributes["name"] = balancer.LoadBalancerName
	s.Attributes["dns_name"] = balancer.DNSName
	return s, nil
}
<commit_msg>providers/aws: elb destroy<commit_after>package aws

import (
	"fmt"
	"log"

	"github.com/hashicorp/terraform/flatmap"
	"github.com/hashicorp/terraform/helper/diff"
	"github.com/hashicorp/terraform/terraform"
	"github.com/mitchellh/goamz/elb"
)

func resource_aws_elb_create(
	s *terraform.ResourceState,
	d *terraform.ResourceDiff,
	meta interface{}) (*terraform.ResourceState, error) {
	p := meta.(*ResourceProvider)
	elbconn := p.elbconn

	// Merge the diff into the state so that we have all the attributes
	// properly.
	rs := s.MergeDiff(d)

	// The name specified for the ELB. This is also our unique ID
	// we save to state if the creation is succesful (amazon verifies
	// it is unique)
	elbName := rs.Attributes["name"]

	// Expand the "listener" array to goamz compat []elb.Listener
	v := flatmap.Expand(rs.Attributes, "listener").([]interface{})
	listeners := expandListeners(v)

	v = flatmap.Expand(rs.Attributes, "availability_zones").([]interface{})
	zones := expandStringList(v)

	// Provision the elb
	elbOpts := &elb.CreateLoadBalancer{
		LoadBalancerName: elbName,
		Listeners:        listeners,
		AvailZone:        zones,
	}

	log.Printf("[DEBUG] ELB create configuration: %#v", elbOpts)

	_, err := elbconn.CreateLoadBalancer(elbOpts)
	if err != nil {
		return nil, fmt.Errorf("Error creating ELB: %s", err)
	}

	// Assign the elb's unique identifer for use later
	rs.ID = elbName
	log.Printf("[INFO] ELB ID: %s", elbName)

	// If we have any instances, we need to register them
	v = flatmap.Expand(rs.Attributes, "instances").([]interface{})
	instances := expandStringList(v)

	if len(instances) > 0 {
		registerInstancesOpts := elb.RegisterInstancesWithLoadBalancer{
			LoadBalancerName: elbName,
			Instances:        instances,
		}

		_, err := elbconn.RegisterInstancesWithLoadBalancer(&registerInstancesOpts)

		if err != nil {
			return nil, fmt.Errorf("Failure registering instances: %s", err)
		}
	}

	describeElbOpts := &elb.DescribeLoadBalancer{
		Names: []string{elbName},
	}

	// Retrieve the ELB properties for updating the state
	describeResp, err := elbconn.DescribeLoadBalancers(describeElbOpts)
	if err != nil {
		return nil, fmt.Errorf("Error retrieving ELB: %s", err)
	}

	loadBalancer := describeResp.LoadBalancers[0]

	// Verify AWS returned our ELB
	if len(describeResp.LoadBalancers) != 1 ||
		describeResp.LoadBalancers[0].LoadBalancerName != elbName {
		if err != nil {
			return nil, fmt.Errorf("Unable to find ELB: %#v", describeResp.LoadBalancers)
		}
	}

	return resource_aws_elb_update_state(rs, &loadBalancer)
}

func resource_aws_elb_update(
	s *terraform.ResourceState,
	d *terraform.ResourceDiff,
	meta interface{}) (*terraform.ResourceState, error) {
	// p := meta.(*ResourceProvider)
	// elbconn := p.elbconn

	rs := s.MergeDiff(d)
	log.Printf("ResourceDiff: %s", d)
	log.Printf("ResourceState: %s", s)
	log.Printf("Merged: %s", rs)

	// If we have any instances, we need to register them
	v := flatmap.Expand(rs.Attributes, "instances").([]interface{})
	instances := expandStringList(v)

	log.Println(instances)

	return nil, fmt.Errorf("Did not update")
}

func resource_aws_elb_destroy(
	s *terraform.ResourceState,
	meta interface{}) error {
	p := meta.(*ResourceProvider)
	elbconn := p.elbconn

	log.Printf("[INFO] Deleting ELB: %s", s.ID)

	// Destroy the load balancer
	deleteElbOpts := elb.DeleteLoadBalancer{
		LoadBalancerName: s.ID,
	}
	_, err := elbconn.DeleteLoadBalancer(&deleteElbOpts)

	if err != nil {
		return fmt.Errorf("Error deleting ELB: %s", err)
	}

	return nil
}

func resource_aws_elb_refresh(
	s *terraform.ResourceState,
	meta interface{}) (*terraform.ResourceState, error) {

	loadBalancer := &elb.LoadBalancer{}

	return resource_aws_elb_update_state(s, loadBalancer)
}

func resource_aws_elb_diff(
	s *terraform.ResourceState,
	c *terraform.ResourceConfig,
	meta interface{}) (*terraform.ResourceDiff, error) {

	b := &diff.ResourceBuilder{
		Attrs: map[string]diff.AttrType{
			"name":              diff.AttrTypeCreate,
			"availability_zone": diff.AttrTypeCreate,
			"listener":          diff.AttrTypeCreate,
			"instances":         diff.AttrTypeUpdate,
		},

		ComputedAttrs: []string{
			"dns_name",
		},
	}

	return b.Diff(s, c)
}

func resource_aws_elb_update_state(
	s *terraform.ResourceState,
	balancer *elb.LoadBalancer) (*terraform.ResourceState, error) {
	s.Attributes["name"] = balancer.LoadBalancerName
	s.Attributes["dns_name"] = balancer.DNSName
	return s, nil
}
<|endoftext|>


<commit_before>package trello

import (
	"encoding/json"
	"errors"
	"fmt"
	"io"
)

type Member struct {
	Id       string
	FullName string
	Username string
}

var minimalFields = [...]ModelField{FullName, Username}

func (m Member) MinimalFields() []ModelField {
	return minimalFields[:]
}

// Get Member model of authenticated user
func (_ *Member) Me(_context interface{}, params *ModelParams) <-chan *TrelloResponse {
	trc := make(chan *TrelloResponse)
	context := _context.(*context)
	go func() {
		if context.token == "" {
			trc <- &TrelloResponse{Error: errors.New("Cannot request members/me without user token.")}
		}

		req := MakeGetRequest(context, "members/me", fmt.Sprintf("fields=%v", params.FieldsQueryParameter()))

		resp, err := context.client.Do(req)
		if err != nil {
			trc <- &TrelloResponse{Error: err}
			return
		}
		defer resp.Body.Close()

		if resp.StatusCode < 200 || resp.StatusCode >= 400 {
			trc <- &TrelloResponse{Error: errors.New(resp.Status)}
			return
		}

		var m Member
		decoder := json.NewDecoder(resp.Body)
		if err = decoder.Decode(&m); err == io.EOF {
			trc <- &TrelloResponse{}
		} else if err != nil {
			trc <- &TrelloResponse{Error: err}
			return
		}

		trc <- &TrelloResponse{Model: m}
	}()

	return trc
}
<commit_msg>emit more expressive errors when error http codes are encountered<commit_after>package trello

import (
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
)

type Member struct {
	Id       string
	FullName string
	Username string
}

var minimalFields = [...]ModelField{FullName, Username}

func (m Member) MinimalFields() []ModelField {
	return minimalFields[:]
}

// Get Member model of authenticated user
func (_ *Member) Me(_context interface{}, params *ModelParams) <-chan *TrelloResponse {
	trc := make(chan *TrelloResponse)
	context := _context.(*context)
	go func() {
		if context.token == "" {
			trc <- &TrelloResponse{Error: errors.New("Cannot request members/me without user token.")}
		}

		req := MakeGetRequest(context, "members/me", fmt.Sprintf("fields=%v", params.FieldsQueryParameter()))

		resp, err := context.client.Do(req)
		if err != nil {
			trc <- &TrelloResponse{Error: err}
			return
		}
		defer resp.Body.Close()

		if resp.StatusCode < 200 || resp.StatusCode >= 400 {
			errorBody, _ := ioutil.ReadAll(resp.Body)
			trc <- &TrelloResponse{Error: errors.New(fmt.Sprintf("%s: %s", resp.Status, errorBody)}
			return
		}

		var m Member
		decoder := json.NewDecoder(resp.Body)
		if err = decoder.Decode(&m); err == io.EOF {
			trc <- &TrelloResponse{}
		} else if err != nil {
			trc <- &TrelloResponse{Error: err}
			return
		}

		trc <- &TrelloResponse{Model: m}
	}()

	return trc
}
<|endoftext|>