<commit_before>// Copyright 2012 Charles Banning. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file
/*
	Unmarshal an arbitrary XML document to a map or a JSON string.

	DocToMap() returns an intermediate result with the XML doc unmarshal'd to a map
	of type map[string]interface{}. It is analogous to unmarshal'ng a JSON string to
	a map using json.Unmarshal(). (This was the original purpose of this library.)

	DocToTree()/WriteTree() let you examine the parsed XML doc.

	XML values are all type 'string'. The optional argument 'recast' for DocToJson()
	and DocToMap() will convert element values to JSON data types - 'float64' and 'bool' -
	if possible.  This, however, should be done with caution as it will recast ALL numeric
	and boolean string values, even those that are meant to be of type 'string'.
 */
package x2j

import (
	"bytes"
	"encoding/json"
	"encoding/xml"
	"errors"
	"fmt"
	"regexp"
	"strconv"
	"strings"
)

type node struct {
	dup bool
	key string
	val string
	nodes []*node
}

// DocToJson - return an XML doc as a JSON string.
//	If the optional argument 'recast' is 'true', then values will be converted to boolean or float64 if possible.
func DocToJson(doc string,recast ...bool) (string,error) {
	var r bool
	if len(recast) == 1 {
		r = recast[0]
	}
	m,merr := DocToMap(doc,r)
	if m == nil || merr != nil {
		return "",merr
	}

	b, berr := json.Marshal(m)
	if berr != nil {
		return "",berr
	}

	return string(b),nil
}

// DocToJsonIndent - return an XML doc as a prettified JSON string.
//	If the optional argument 'recast' is 'true', then values will be converted to boolean or float64 if possible.
func DocToJsonIndent(doc string,recast ...bool) (string,error) {
	var r bool
	if len(recast) == 1 {
		r = recast[0]
	}
	m,merr := DocToMap(doc,r)
	if m == nil || merr != nil {
		return "",merr
	}

	b, berr := json.MarshalIndent(m,"","  ")
	if berr != nil {
		return "",berr
	}

	return string(b),nil
}

// DocToMap - convert an XML doc into a map[string]interface{}.
// (This is analogous to unmarshalling a JSON string to map[string]interface{} using json.Unmarshal().)
//	If the optional argument 'recast' is 'true', then values will be converted to boolean or float64 if possible.
func DocToMap(doc string,recast ...bool) (map[string]interface{},error) {
	var r bool
	if len(recast) == 1 {
		r = recast[0]
	}
	n,err := DocToTree(doc)
	if err != nil {
		return nil,err
	}

	m := make(map[string]interface{})
	m[n.key] = treeToMap(n,r)

	return m,nil
}

// DocToTree - convert an XML doc into a tree of nodes.
func DocToTree(doc string) (*node, error) {
	// xml.Decoder doesn't properly handle whitespace in some doc
	// see songTextString.xml test case ...
	reg,_ := regexp.Compile("[ \t]*<")
	doc = reg.ReplaceAllString(doc,"<")
	r := strings.NewReplacer("\n","","\r","","\t","")
	doc = r.Replace(doc)

	b := bytes.NewBufferString(doc)
	p := xml.NewDecoder(b)
	n, berr := xmlToTree("",nil,p)
	if berr != nil {
		return nil, berr
	}

	return n,nil
}

// WriteTree - convert a tree of nodes into a printable string.
//	'indent' is the starting indentation count; typically: WriteTree(0,n).
func WriteTree(indent int,n *node) string {
	var s string
	if n.val != "" {
		for i := 0 ; i < indent ; i++ {
			s += "  "
		}
		s += n.key+" : "+n.val+"\n"
	} else {
		for i := 0 ; i < indent ; i++ {
			s += "  "
		}
		s += n.key+" :"+"\n"
		for _,v := range n.nodes {
			s += WriteTree(indent+1,v)
		}
	}
	return s
}

// xmlToTree - load a 'clean' XML doc into a tree of *node.
func xmlToTree(skey string,a []xml.Attr,p *xml.Decoder) (*node, error) {
	n := new(node)
	n.nodes = make([]*node,0)

	if skey != "" {
		n.key = skey
		if len(a) > 0 {
			for _,v := range a {
				na := new(node)
				na.key = `-`+v.Name.Local
				na.val = v.Value
				n.nodes = append(n.nodes,na)
			}
		}
	}
	for {
		t,err := p.Token()
		if err != nil {
			return nil, err
		}
		switch t.(type) {
			case xml.StartElement:
				tt := t.(xml.StartElement)
				// handle root
				if n.key == "" {
					n.key = tt.Name.Local
					if len(tt.Attr) > 0 {
						for _,v := range tt.Attr {
							na := new(node)
							na.key = `-`+v.Name.Local
							na.val = v.Value
							n.nodes = append(n.nodes,na)
						}
					}
				} else {
					nn, nnerr := xmlToTree(tt.Name.Local,tt.Attr,p)
					if nnerr != nil {
						return nil, nnerr
					}
					n.nodes = append(n.nodes,nn)
				}
			case xml.EndElement:
				// scan v.nodes for duplicate v.key values
				markDuplicateKeys(n)
				return n, nil
			case xml.CharData:
				tt := string(t.(xml.CharData))
				if len(n.nodes) > 0 {
					nn := new(node)
					nn.key = "#text"
					nn.val = tt
					n.nodes = append(n.nodes,nn)
				} else {
					n.val = tt
				}
			default:
				// noop
		}
	}
	return nil, errors.New("EndElement not found for: "+n.key)
}

// markDuplicateKeys - set node.dup flag for loading map[string]interface{}.
func markDuplicateKeys(n *node) {
	l := len(n.nodes)
	for i := 0 ; i < l ; i++ {
		if n.nodes[i].dup {
			continue
		}
		for j := i+1 ; j < l ; j++ {
			if n.nodes[i].key == n.nodes[j].key {
				n.nodes[i].dup = true
				n.nodes[j].dup = true
			}
		}
	}
}

// treeToMap - convert a tree of nodes into a map[string]interface{}.
//	(Parses to map that is structurally the same as from json.Unmarshal().)
// Note: root is not instantiated; call with: "m[n.key] = treeToMap()".
func treeToMap(n *node,r bool) interface{} {
	if len(n.nodes) == 0 {
		return recast(n.val,r)
	}

	m := make(map[string]interface{},0)
	for _,v := range n.nodes {
		// just a value
		if !v.dup && len(v.nodes) == 0 {
			m[v.key] = recast(v.val,r)
			continue
		}

		// a list of values
		if v.dup {
			var a []interface{}
			if vv,ok := m[v.key]; ok {
				a = vv.([]interface{})
			} else {
				a = make([]interface{},0)
			}
			a = append(a,treeToMap(v,r))
			m[v.key] = interface{}(a)
			continue
		}

		// it's a unique key
		m[v.key] = treeToMap(v,r)
	}

	return interface{}(m)
}

// recast - try to cast string values to bool or float64
func recast(s string,r bool) interface{} {
	if r {
		// handle numeric strings ahead of boolean
		if f, err := strconv.ParseFloat(s,64); err == nil {
			return interface{}(f)
		}
		// ParseBool treats "1"==true & "0"==false
		if b, err := strconv.ParseBool(s); err == nil {
			return interface{}(b)
		}
	}
	return interface{}(s)
}

// WriteMap - dumps the map[string]interface{} for examination.
//	'indent' is initial indentation count; typically: WriteMap(0,m).
//	NOTE: with XML all element types are 'string'.
//	But code written as generic for use with maps[string]interface{} values from json.Unmarshal().
func WriteMap(indent int,m interface{}) string {
	var s string
	switch m.(type) {
		case nil:
			return "[nil] nil"
		case string:
			return "[string] "+m.(string)
		case float64:
			return "[float64] "+strconv.FormatFloat(m.(float64),'e',2,64)
		case bool:
			return "[bool] "+strconv.FormatBool(m.(bool))
		case []interface{}:
			s += "[[]interface{}]"
			for i,v := range m.([]interface{}) {
				s += "\n"
				for i := 0 ; i < indent ; i++ {
					s += "  "
				}
				s += "item: "+strconv.FormatInt(int64(i),10)
				switch v.(type) {
					case string,float64,bool:
						s += "\n"
					default:
						// noop
				}
				for i := 0 ; i < indent ; i++ {
					s += "  "
				}
				s += WriteMap(indent+1,v)
			}
		case map[string]interface{}:
			for k,v := range m.(map[string]interface{}) {
				s += "\n"
				for i := 0 ; i < indent ; i++ {
					s += "  "
				}
				s += "[map[string]interface{}] "+k+" :"+WriteMap(indent+1,v)
		}
		default:
			// shouldn't ever be here ...
			s += fmt.Sprintf("unknown type for: %v",m)
	}
	return s
}
<commit_msg>v1.0.1<commit_after>// Copyright 2012 Charles Banning. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file
/*
	Unmarshal an arbitrary XML doc to a map[string]interface{} or a JSON string.

	DocToMap() returns an intermediate result with the XML doc unmarshal'd to a map
	of type map[string]interface{}. It is analogous to unmarshal'ng a JSON string to
	a map using json.Unmarshal(). (This was the original purpose of this library.)

	DocToTree()/WriteTree() let you examine the parsed XML doc.

	XML values are all type 'string'. The optional argument 'recast' for DocToJson()
	and DocToMap() will convert element values to JSON data types - 'float64' and 'bool' -
	if possible.  This, however, should be done with caution as it will recast ALL numeric
	and boolean string values, even those that are meant to be of type 'string'.
 */
package x2j

import (
	"bytes"
	"encoding/json"
	"encoding/xml"
	"errors"
	"fmt"
	"regexp"
	"strconv"
)

type node struct {
	dup bool
	key string
	val string
	nodes []*node
}

// DocToJson - return an XML doc as a JSON string.
//	If the optional argument 'recast' is 'true', then values will be converted to boolean or float64 if possible.
func DocToJson(doc string,recast ...bool) (string,error) {
	var r bool
	if len(recast) == 1 {
		r = recast[0]
	}
	m,merr := DocToMap(doc,r)
	if m == nil || merr != nil {
		return "",merr
	}

	b, berr := json.Marshal(m)
	if berr != nil {
		return "",berr
	}

	return string(b),nil
}

// DocToJsonIndent - return an XML doc as a prettified JSON string.
//	If the optional argument 'recast' is 'true', then values will be converted to boolean or float64 if possible.
func DocToJsonIndent(doc string,recast ...bool) (string,error) {
	var r bool
	if len(recast) == 1 {
		r = recast[0]
	}
	m,merr := DocToMap(doc,r)
	if m == nil || merr != nil {
		return "",merr
	}

	b, berr := json.MarshalIndent(m,"","  ")
	if berr != nil {
		return "",berr
	}

	return string(b),nil
}

// DocToMap - convert an XML doc into a map[string]interface{}.
// (This is analogous to unmarshalling a JSON string to map[string]interface{} using json.Unmarshal().)
//	If the optional argument 'recast' is 'true', then values will be converted to boolean or float64 if possible.
func DocToMap(doc string,recast ...bool) (map[string]interface{},error) {
	var r bool
	if len(recast) == 1 {
		r = recast[0]
	}
	n,err := DocToTree(doc)
	if err != nil {
		return nil,err
	}

	m := make(map[string]interface{})
	m[n.key] = treeToMap(n,r)

	return m,nil
}

// DocToTree - convert an XML doc into a tree of nodes.
func DocToTree(doc string) (*node, error) {
	// xml.Decoder doesn't properly handle whitespace in some doc
	// see songTextString.xml test case ...
	reg,_ := regexp.Compile("[ \t\n\r]*<")
	doc = reg.ReplaceAllString(doc,"<")

	b := bytes.NewBufferString(doc)
	p := xml.NewDecoder(b)
	n, berr := xmlToTree("",nil,p)
	if berr != nil {
		return nil, berr
	}

	return n,nil
}

// WriteTree - convert a tree of nodes into a printable string.
//	'indent' is the starting indentation count; typically: WriteTree(0,n).
func WriteTree(indent int,n *node) string {
	var s string
	if n.val != "" {
		for i := 0 ; i < indent ; i++ {
			s += "  "
		}
		s += n.key+" : "+n.val+"\n"
	} else {
		for i := 0 ; i < indent ; i++ {
			s += "  "
		}
		s += n.key+" :"+"\n"
		for _,v := range n.nodes {
			s += WriteTree(indent+1,v)
		}
	}
	return s
}

// xmlToTree - load a 'clean' XML doc into a tree of *node.
func xmlToTree(skey string,a []xml.Attr,p *xml.Decoder) (*node, error) {
	n := new(node)
	n.nodes = make([]*node,0)

	if skey != "" {
		n.key = skey
		if len(a) > 0 {
			for _,v := range a {
				na := new(node)
				na.key = `-`+v.Name.Local
				na.val = v.Value
				n.nodes = append(n.nodes,na)
			}
		}
	}
	for {
		t,err := p.Token()
		if err != nil {
			return nil, err
		}
		switch t.(type) {
			case xml.StartElement:
				tt := t.(xml.StartElement)
				// handle root
				if n.key == "" {
					n.key = tt.Name.Local
					if len(tt.Attr) > 0 {
						for _,v := range tt.Attr {
							na := new(node)
							na.key = `-`+v.Name.Local
							na.val = v.Value
							n.nodes = append(n.nodes,na)
						}
					}
				} else {
					nn, nnerr := xmlToTree(tt.Name.Local,tt.Attr,p)
					if nnerr != nil {
						return nil, nnerr
					}
					n.nodes = append(n.nodes,nn)
				}
			case xml.EndElement:
				// scan v.nodes for duplicate v.key values
				markDuplicateKeys(n)
				return n, nil
			case xml.CharData:
				tt := string(t.(xml.CharData))
				if len(n.nodes) > 0 {
					nn := new(node)
					nn.key = "#text"
					nn.val = tt
					n.nodes = append(n.nodes,nn)
				} else {
					n.val = tt
				}
			default:
				// noop
		}
	}
	return nil, errors.New("EndElement not found for: "+n.key)
}

// markDuplicateKeys - set node.dup flag for loading map[string]interface{}.
func markDuplicateKeys(n *node) {
	l := len(n.nodes)
	for i := 0 ; i < l ; i++ {
		if n.nodes[i].dup {
			continue
		}
		for j := i+1 ; j < l ; j++ {
			if n.nodes[i].key == n.nodes[j].key {
				n.nodes[i].dup = true
				n.nodes[j].dup = true
			}
		}
	}
}

// treeToMap - convert a tree of nodes into a map[string]interface{}.
//	(Parses to map that is structurally the same as from json.Unmarshal().)
// Note: root is not instantiated; call with: "m[n.key] = treeToMap()".
func treeToMap(n *node,r bool) interface{} {
	if len(n.nodes) == 0 {
		return recast(n.val,r)
	}

	m := make(map[string]interface{},0)
	for _,v := range n.nodes {
		// just a value
		if !v.dup && len(v.nodes) == 0 {
			m[v.key] = recast(v.val,r)
			continue
		}

		// a list of values
		if v.dup {
			var a []interface{}
			if vv,ok := m[v.key]; ok {
				a = vv.([]interface{})
			} else {
				a = make([]interface{},0)
			}
			a = append(a,treeToMap(v,r))
			m[v.key] = interface{}(a)
			continue
		}

		// it's a unique key
		m[v.key] = treeToMap(v,r)
	}

	return interface{}(m)
}

// recast - try to cast string values to bool or float64
func recast(s string,r bool) interface{} {
	if r {
		// handle numeric strings ahead of boolean
		if f, err := strconv.ParseFloat(s,64); err == nil {
			return interface{}(f)
		}
		// ParseBool treats "1"==true & "0"==false
		if b, err := strconv.ParseBool(s); err == nil {
			return interface{}(b)
		}
	}
	return interface{}(s)
}

// WriteMap - dumps the map[string]interface{} for examination.
//	'indent' is initial indentation count; typically: WriteMap(0,m).
//	NOTE: with XML all element types are 'string'.
//	But code written as generic for use with maps[string]interface{} values from json.Unmarshal().
func WriteMap(indent int,m interface{}) string {
	var s string
	switch m.(type) {
		case nil:
			return "[nil] nil"
		case string:
			return "[string] "+m.(string)
		case float64:
			return "[float64] "+strconv.FormatFloat(m.(float64),'e',2,64)
		case bool:
			return "[bool] "+strconv.FormatBool(m.(bool))
		case []interface{}:
			s += "[[]interface{}]"
			for i,v := range m.([]interface{}) {
				s += "\n"
				for i := 0 ; i < indent ; i++ {
					s += "  "
				}
				s += "item: "+strconv.FormatInt(int64(i),10)
				switch v.(type) {
					case string,float64,bool:
						s += "\n"
					default:
						// noop
				}
				for i := 0 ; i < indent ; i++ {
					s += "  "
				}
				s += WriteMap(indent+1,v)
			}
		case map[string]interface{}:
			for k,v := range m.(map[string]interface{}) {
				s += "\n"
				for i := 0 ; i < indent ; i++ {
					s += "  "
				}
				s += "[map[string]interface{}] "+k+" :"+WriteMap(indent+1,v)
		}
		default:
			// shouldn't ever be here ...
			s += fmt.Sprintf("unknown type for: %v",m)
	}
	return s
}
<|endoftext|>


<commit_before>package benchmark

import (
	"fmt"
	"strings"
	"sync"
	"time"

	"github.com/lxc/lxd/client"
	"github.com/lxc/lxd/lxc/config"
	"github.com/lxc/lxd/shared/api"
	"github.com/lxc/lxd/shared/version"
)

const userConfigKey = "user.lxd-benchmark"

// PrintServerInfo prints out information about the server.
func PrintServerInfo(c lxd.ContainerServer) error {
	server, _, err := c.GetServer()
	if err != nil {
		return err
	}
	env := server.Environment
	fmt.Printf("Test environment:\n")
	fmt.Printf("  Server backend: %s\n", env.Server)
	fmt.Printf("  Server version: %s\n", env.ServerVersion)
	fmt.Printf("  Kernel: %s\n", env.Kernel)
	fmt.Printf("  Kernel architecture: %s\n", env.KernelArchitecture)
	fmt.Printf("  Kernel version: %s\n", env.KernelVersion)
	fmt.Printf("  Storage backend: %s\n", env.Storage)
	fmt.Printf("  Storage version: %s\n", env.StorageVersion)
	fmt.Printf("  Container backend: %s\n", env.Driver)
	fmt.Printf("  Container version: %s\n", env.DriverVersion)
	fmt.Printf("\n")
	return nil
}

// LaunchContainers launches a set of containers.
func LaunchContainers(c lxd.ContainerServer, count int, parallel int, image string, privileged bool, start bool, freeze bool) (time.Duration, error) {
	var duration time.Duration

	batchSize, err := getBatchSize(parallel)
	if err != nil {
		return duration, err
	}

	printTestConfig(count, batchSize, image, privileged, freeze)

	fingerprint, err := ensureImage(c, image)
	if err != nil {
		return duration, err
	}

	startContainer := func(index int, wg *sync.WaitGroup) {
		defer wg.Done()

		name := getContainerName(count, index)

		err := createContainer(c, fingerprint, name, privileged)
		if err != nil {
			logf("Failed to launch container '%s': %s", name, err)
			return
		}

		if start {
			err := startContainer(c, name)
			if err != nil {
				logf("Failed to start container '%s': %s", name, err)
				return
			}

			if freeze {
				err := freezeContainer(c, name)
				if err != nil {
					logf("Failed to freeze container '%s': %s", name, err)
					return
				}
			}
		}
	}

	duration = processBatch(count, batchSize, startContainer)
	return duration, nil
}

// CreateContainers create the specified number of containers.
func CreateContainers(c lxd.ContainerServer, count int, parallel int, fingerprint string, privileged bool) (time.Duration, error) {
	var duration time.Duration

	batchSize, err := getBatchSize(parallel)
	if err != nil {
		return duration, err
	}

	createContainer := func(index int, wg *sync.WaitGroup) {
		defer wg.Done()

		name := getContainerName(count, index)

		err := createContainer(c, fingerprint, name, privileged)
		if err != nil {
			logf("Failed to launch container '%s': %s", name, err)
			return
		}
	}

	duration = processBatch(count, batchSize, createContainer)

	return duration, nil
}

// GetContainers returns containers created by the benchmark.
func GetContainers(c lxd.ContainerServer) ([]api.Container, error) {
	containers := []api.Container{}

	allContainers, err := c.GetContainers()
	if err != nil {
		return containers, err
	}

	for _, container := range allContainers {
		if container.Config[userConfigKey] == "true" {
			containers = append(containers, container)
		}
	}

	return containers, nil
}

// StartContainers starts containers created by the benchmark.
func StartContainers(c lxd.ContainerServer, containers []api.Container, parallel int) (time.Duration, error) {
	var duration time.Duration

	batchSize, err := getBatchSize(parallel)
	if err != nil {
		return duration, err
	}

	count := len(containers)
	logf("Starting %d containers", count)

	startContainer := func(index int, wg *sync.WaitGroup) {
		defer wg.Done()

		container := containers[index]
		if !container.IsActive() {
			err := startContainer(c, container.Name)
			if err != nil {
				logf("Failed to start container '%s': %s", container.Name, err)
				return
			}
		}
	}

	duration = processBatch(count, batchSize, startContainer)
	return duration, nil
}

// StopContainers stops containers created by the benchmark.
func StopContainers(c lxd.ContainerServer, containers []api.Container, parallel int) (time.Duration, error) {
	var duration time.Duration

	batchSize, err := getBatchSize(parallel)
	if err != nil {
		return duration, err
	}

	count := len(containers)
	logf("Stopping %d containers", count)

	stopContainer := func(index int, wg *sync.WaitGroup) {
		defer wg.Done()

		container := containers[index]
		if container.IsActive() {
			err := stopContainer(c, container.Name)
			if err != nil {
				logf("Failed to stop container '%s': %s", container.Name, err)
				return
			}
		}
	}

	duration = processBatch(count, batchSize, stopContainer)
	return duration, nil
}

// DeleteContainers removes containers created by the benchmark.
func DeleteContainers(c lxd.ContainerServer, containers []api.Container, parallel int) (time.Duration, error) {
	var duration time.Duration

	batchSize, err := getBatchSize(parallel)
	if err != nil {
		return duration, err
	}

	count := len(containers)
	logf("Deleting %d containers", count)

	deleteContainer := func(index int, wg *sync.WaitGroup) {
		defer wg.Done()

		container := containers[index]
		name := container.Name
		if container.IsActive() {
			err := stopContainer(c, name)
			if err != nil {
				logf("Failed to stop container '%s': %s", name, err)
				return
			}
		}

		err = deleteContainer(c, name)
		if err != nil {
			logf("Failed to delete container: %s", name)
			return
		}
	}

	duration = processBatch(count, batchSize, deleteContainer)
	return duration, nil
}

func ensureImage(c lxd.ContainerServer, image string) (string, error) {
	var fingerprint string

	if strings.Contains(image, ":") {
		defaultConfig := config.NewConfig("", true)
		defaultConfig.UserAgent = version.UserAgent

		remote, fp, err := defaultConfig.ParseRemote(image)
		if err != nil {
			return "", err
		}
		fingerprint = fp

		imageServer, err := defaultConfig.GetImageServer(remote)
		if err != nil {
			return "", err
		}

		if fingerprint == "" {
			fingerprint = "default"
		}

		alias, _, err := imageServer.GetImageAlias(fingerprint)
		if err == nil {
			fingerprint = alias.Target
		}

		_, _, err = c.GetImage(fingerprint)
		if err != nil {
			logf("Importing image into local store: %s", fingerprint)
			image, _, err := imageServer.GetImage(fingerprint)
			if err != nil {
				logf("Failed to import image: %s", err)
				return "", err
			}

			err = copyImage(c, imageServer, *image)
			if err != nil {
				logf("Failed to import image: %s", err)
				return "", err
			}
		}
	} else {
		fingerprint = image
		alias, _, err := c.GetImageAlias(image)
		if err == nil {
			fingerprint = alias.Target
		} else {
			_, _, err = c.GetImage(image)
		}

		if err != nil {
			logf("Image not found in local store: %s", image)
			return "", err
		}
	}

	logf("Found image in local store: %s", fingerprint)
	return fingerprint, nil
}
<commit_msg>lxd-benchmark: Fix new go vet warnings<commit_after>package benchmark

import (
	"fmt"
	"strings"
	"sync"
	"time"

	"github.com/lxc/lxd/client"
	"github.com/lxc/lxd/lxc/config"
	"github.com/lxc/lxd/shared/api"
	"github.com/lxc/lxd/shared/version"
)

const userConfigKey = "user.lxd-benchmark"

// PrintServerInfo prints out information about the server.
func PrintServerInfo(c lxd.ContainerServer) error {
	server, _, err := c.GetServer()
	if err != nil {
		return err
	}
	env := server.Environment
	fmt.Printf("Test environment:\n")
	fmt.Printf("  Server backend: %s\n", env.Server)
	fmt.Printf("  Server version: %s\n", env.ServerVersion)
	fmt.Printf("  Kernel: %s\n", env.Kernel)
	fmt.Printf("  Kernel architecture: %s\n", env.KernelArchitecture)
	fmt.Printf("  Kernel version: %s\n", env.KernelVersion)
	fmt.Printf("  Storage backend: %s\n", env.Storage)
	fmt.Printf("  Storage version: %s\n", env.StorageVersion)
	fmt.Printf("  Container backend: %s\n", env.Driver)
	fmt.Printf("  Container version: %s\n", env.DriverVersion)
	fmt.Printf("\n")
	return nil
}

// LaunchContainers launches a set of containers.
func LaunchContainers(c lxd.ContainerServer, count int, parallel int, image string, privileged bool, start bool, freeze bool) (time.Duration, error) {
	var duration time.Duration

	batchSize, err := getBatchSize(parallel)
	if err != nil {
		return duration, err
	}

	printTestConfig(count, batchSize, image, privileged, freeze)

	fingerprint, err := ensureImage(c, image)
	if err != nil {
		return duration, err
	}

	batchStart := func(index int, wg *sync.WaitGroup) {
		defer wg.Done()

		name := getContainerName(count, index)

		err := createContainer(c, fingerprint, name, privileged)
		if err != nil {
			logf("Failed to launch container '%s': %s", name, err)
			return
		}

		if start {
			err := startContainer(c, name)
			if err != nil {
				logf("Failed to start container '%s': %s", name, err)
				return
			}

			if freeze {
				err := freezeContainer(c, name)
				if err != nil {
					logf("Failed to freeze container '%s': %s", name, err)
					return
				}
			}
		}
	}

	duration = processBatch(count, batchSize, batchStart)
	return duration, nil
}

// CreateContainers create the specified number of containers.
func CreateContainers(c lxd.ContainerServer, count int, parallel int, fingerprint string, privileged bool) (time.Duration, error) {
	var duration time.Duration

	batchSize, err := getBatchSize(parallel)
	if err != nil {
		return duration, err
	}

	batchCreate := func(index int, wg *sync.WaitGroup) {
		defer wg.Done()

		name := getContainerName(count, index)

		err := createContainer(c, fingerprint, name, privileged)
		if err != nil {
			logf("Failed to launch container '%s': %s", name, err)
			return
		}
	}

	duration = processBatch(count, batchSize, batchCreate)

	return duration, nil
}

// GetContainers returns containers created by the benchmark.
func GetContainers(c lxd.ContainerServer) ([]api.Container, error) {
	containers := []api.Container{}

	allContainers, err := c.GetContainers()
	if err != nil {
		return containers, err
	}

	for _, container := range allContainers {
		if container.Config[userConfigKey] == "true" {
			containers = append(containers, container)
		}
	}

	return containers, nil
}

// StartContainers starts containers created by the benchmark.
func StartContainers(c lxd.ContainerServer, containers []api.Container, parallel int) (time.Duration, error) {
	var duration time.Duration

	batchSize, err := getBatchSize(parallel)
	if err != nil {
		return duration, err
	}

	count := len(containers)
	logf("Starting %d containers", count)

	batchStart := func(index int, wg *sync.WaitGroup) {
		defer wg.Done()

		container := containers[index]
		if !container.IsActive() {
			err := startContainer(c, container.Name)
			if err != nil {
				logf("Failed to start container '%s': %s", container.Name, err)
				return
			}
		}
	}

	duration = processBatch(count, batchSize, batchStart)
	return duration, nil
}

// StopContainers stops containers created by the benchmark.
func StopContainers(c lxd.ContainerServer, containers []api.Container, parallel int) (time.Duration, error) {
	var duration time.Duration

	batchSize, err := getBatchSize(parallel)
	if err != nil {
		return duration, err
	}

	count := len(containers)
	logf("Stopping %d containers", count)

	batchStop := func(index int, wg *sync.WaitGroup) {
		defer wg.Done()

		container := containers[index]
		if container.IsActive() {
			err := stopContainer(c, container.Name)
			if err != nil {
				logf("Failed to stop container '%s': %s", container.Name, err)
				return
			}
		}
	}

	duration = processBatch(count, batchSize, batchStop)
	return duration, nil
}

// DeleteContainers removes containers created by the benchmark.
func DeleteContainers(c lxd.ContainerServer, containers []api.Container, parallel int) (time.Duration, error) {
	var duration time.Duration

	batchSize, err := getBatchSize(parallel)
	if err != nil {
		return duration, err
	}

	count := len(containers)
	logf("Deleting %d containers", count)

	batchDelete := func(index int, wg *sync.WaitGroup) {
		defer wg.Done()

		container := containers[index]
		name := container.Name
		if container.IsActive() {
			err := stopContainer(c, name)
			if err != nil {
				logf("Failed to stop container '%s': %s", name, err)
				return
			}
		}

		err = deleteContainer(c, name)
		if err != nil {
			logf("Failed to delete container: %s", name)
			return
		}
	}

	duration = processBatch(count, batchSize, batchDelete)
	return duration, nil
}

func ensureImage(c lxd.ContainerServer, image string) (string, error) {
	var fingerprint string

	if strings.Contains(image, ":") {
		defaultConfig := config.NewConfig("", true)
		defaultConfig.UserAgent = version.UserAgent

		remote, fp, err := defaultConfig.ParseRemote(image)
		if err != nil {
			return "", err
		}
		fingerprint = fp

		imageServer, err := defaultConfig.GetImageServer(remote)
		if err != nil {
			return "", err
		}

		if fingerprint == "" {
			fingerprint = "default"
		}

		alias, _, err := imageServer.GetImageAlias(fingerprint)
		if err == nil {
			fingerprint = alias.Target
		}

		_, _, err = c.GetImage(fingerprint)
		if err != nil {
			logf("Importing image into local store: %s", fingerprint)
			image, _, err := imageServer.GetImage(fingerprint)
			if err != nil {
				logf("Failed to import image: %s", err)
				return "", err
			}

			err = copyImage(c, imageServer, *image)
			if err != nil {
				logf("Failed to import image: %s", err)
				return "", err
			}
		}
	} else {
		fingerprint = image
		alias, _, err := c.GetImageAlias(image)
		if err == nil {
			fingerprint = alias.Target
		} else {
			_, _, err = c.GetImage(image)
		}

		if err != nil {
			logf("Image not found in local store: %s", image)
			return "", err
		}
	}

	logf("Found image in local store: %s", fingerprint)
	return fingerprint, nil
}
<|endoftext|>


<commit_before>// Copyright (c) 2016, Janoš Guljaš <janos@resenje.org>
// All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package httputils

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"net"
	"net/http"
	"strings"
)

const basicAuthScheme string = "Basic "

// AuthHandler is a net/http Handler that can be configured to check credentials from
// custom Key and Secret HTTP headers, or Basic auth from Authorization header.
// Depending on configuration of BasicAuthRealm, KeyHeaderName or SecretHeaderName,
// it can be used as"
//  - Basic auth handler - only BasicAuthRealm is set
//  - single API key auth handler - only KeyHeaderName is set
//  - single API key auth handler with Basic auth support - BasicAuthRealm and KeyHeaderName are set
//  - public/secret API key auth handler - KeyHeaderName and SecretHeaderName are set
//  - public/secret API key auth handler with Basic auth support - all three are set
// By setting AuthorizedNetworks, this handler can authorize requests based only on
// RemoteAddr address.
type AuthHandler struct {
	KeyHeaderName    string
	SecretHeaderName string
	BasicAuthRealm   string

	// Handler will be used if AuthFunc is successful.
	Handler http.Handler
	// UnauthorizedHandler will be used if AuthFunc is not successful.
	UnauthorizedHandler http.Handler
	// ErrorHandler will be used if there is an error. If it is nil, a panic will occur.
	ErrorHandler func(w http.ResponseWriter, r *http.Request, err error)

	// AuthFunc validates credentials.
	AuthFunc func(r *http.Request, key, secret string) (valid bool, err error)
	// PostAuthFunc is a hook to log, set request context or preform any other action
	// after credentials check.
	PostAuthFunc func(w http.ResponseWriter, r *http.Request, key, secret string, valid bool) (rr *http.Request, err error)

	// AuthorizeAll will bypass all methods and authorize all requests.
	AuthorizeAll bool
	// AuthorizedNetworks are network ranges from where requests are authorized
	// without credentials check. Only address from request's RemoteAddr will be
	// checked.
	AuthorizedNetworks []net.IPNet
}

// ServeHTTP serves an HTTP response for a request.
func (h AuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	key, secret, valid, err := h.authenticate(r)
	if err != nil {
		h.error(w, r, err)
		return
	}
	if h.PostAuthFunc != nil {
		rr, err := h.PostAuthFunc(w, r, key, secret, valid)
		if err != nil {
			h.error(w, r, err)
			return
		}
		if rr != nil {
			r = rr
		}
	}
	if !valid {
		h.unauthorized(w, r)
		return
	}

	h.Handler.ServeHTTP(w, r)
}

func (h AuthHandler) authenticate(r *http.Request) (key, secret string, valid bool, err error) {
	if h.AuthorizeAll {
		valid = true
		return
	}

	if len(h.AuthorizedNetworks) > 0 {
		var host string
		host, _, err = net.SplitHostPort(r.RemoteAddr)
		if err != nil {
			return
		}
		ip := net.ParseIP(host)
		for _, network := range h.AuthorizedNetworks {
			if network.Contains(ip) {
				valid = true
				return
			}
		}
	}

	if h.AuthFunc != nil {
		if h.KeyHeaderName != "" || h.SecretHeaderName != "" {
			if h.KeyHeaderName != "" {
				key = r.Header.Get(h.KeyHeaderName)
			}
			if h.SecretHeaderName != "" {
				secret = r.Header.Get(h.SecretHeaderName)
			}
			// Call AuthFunc and return only if there are provided data in headers.
			// If not, auth data from Authorization header should be validated.
			if key != "" || secret != "" {
				valid, err = h.AuthFunc(r, key, secret)
				return
			}
		}
		if h.BasicAuthRealm != "" {
			auth := r.Header.Get("Authorization")
			if !strings.HasPrefix(auth, basicAuthScheme) {
				return
			}

			var decoded []byte
			decoded, err = base64.StdEncoding.DecodeString(auth[len(basicAuthScheme):])
			if err != nil {
				return
			}

			creds := bytes.SplitN(decoded, []byte(":"), 2)
			if len(creds) != 2 {
				return
			}
			key = string(creds[0])
			secret = string(creds[1])

			// This is the last auth method, so there is no need to check any values here,
			// they will be returned ath the and of a function.
			valid, err = h.AuthFunc(r, key, secret)
		}
	}

	return
}

func (h AuthHandler) error(w http.ResponseWriter, r *http.Request, err error) {
	if h.ErrorHandler == nil {
		panic(err)
	}
	h.ErrorHandler(w, r, err)
}

func (h AuthHandler) unauthorized(w http.ResponseWriter, r *http.Request) {
	if h.BasicAuthRealm != "" {
		w.Header().Set("WWW-Authenticate", fmt.Sprintf("Basic realm=%q", h.BasicAuthRealm))
	}
	if h.UnauthorizedHandler != nil {
		h.UnauthorizedHandler.ServeHTTP(w, r)
		return
	}
	http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
}
<commit_msg>Call Handler only if it is set in AuthHandler<commit_after>// Copyright (c) 2016, Janoš Guljaš <janos@resenje.org>
// All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package httputils

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"net"
	"net/http"
	"strings"
)

const basicAuthScheme string = "Basic "

// AuthHandler is a net/http Handler that can be configured to check credentials from
// custom Key and Secret HTTP headers, or Basic auth from Authorization header.
// Depending on configuration of BasicAuthRealm, KeyHeaderName or SecretHeaderName,
// it can be used as"
//  - Basic auth handler - only BasicAuthRealm is set
//  - single API key auth handler - only KeyHeaderName is set
//  - single API key auth handler with Basic auth support - BasicAuthRealm and KeyHeaderName are set
//  - public/secret API key auth handler - KeyHeaderName and SecretHeaderName are set
//  - public/secret API key auth handler with Basic auth support - all three are set
// By setting AuthorizedNetworks, this handler can authorize requests based only on
// RemoteAddr address.
type AuthHandler struct {
	KeyHeaderName    string
	SecretHeaderName string
	BasicAuthRealm   string

	// Handler will be used if AuthFunc is successful.
	Handler http.Handler
	// UnauthorizedHandler will be used if AuthFunc is not successful.
	UnauthorizedHandler http.Handler
	// ErrorHandler will be used if there is an error. If it is nil, a panic will occur.
	ErrorHandler func(w http.ResponseWriter, r *http.Request, err error)

	// AuthFunc validates credentials.
	AuthFunc func(r *http.Request, key, secret string) (valid bool, err error)
	// PostAuthFunc is a hook to log, set request context or preform any other action
	// after credentials check.
	PostAuthFunc func(w http.ResponseWriter, r *http.Request, key, secret string, valid bool) (rr *http.Request, err error)

	// AuthorizeAll will bypass all methods and authorize all requests.
	AuthorizeAll bool
	// AuthorizedNetworks are network ranges from where requests are authorized
	// without credentials check. Only address from request's RemoteAddr will be
	// checked.
	AuthorizedNetworks []net.IPNet
}

// ServeHTTP serves an HTTP response for a request.
func (h AuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	key, secret, valid, err := h.authenticate(r)
	if err != nil {
		h.error(w, r, err)
		return
	}
	if h.PostAuthFunc != nil {
		rr, err := h.PostAuthFunc(w, r, key, secret, valid)
		if err != nil {
			h.error(w, r, err)
			return
		}
		if rr != nil {
			r = rr
		}
	}
	if !valid {
		h.unauthorized(w, r)
		return
	}

	if h.Handler != nil {
		h.Handler.ServeHTTP(w, r)
	}
}

func (h AuthHandler) authenticate(r *http.Request) (key, secret string, valid bool, err error) {
	if h.AuthorizeAll {
		valid = true
		return
	}

	if len(h.AuthorizedNetworks) > 0 {
		var host string
		host, _, err = net.SplitHostPort(r.RemoteAddr)
		if err != nil {
			return
		}
		ip := net.ParseIP(host)
		for _, network := range h.AuthorizedNetworks {
			if network.Contains(ip) {
				valid = true
				return
			}
		}
	}

	if h.AuthFunc != nil {
		if h.KeyHeaderName != "" || h.SecretHeaderName != "" {
			if h.KeyHeaderName != "" {
				key = r.Header.Get(h.KeyHeaderName)
			}
			if h.SecretHeaderName != "" {
				secret = r.Header.Get(h.SecretHeaderName)
			}
			// Call AuthFunc and return only if there are provided data in headers.
			// If not, auth data from Authorization header should be validated.
			if key != "" || secret != "" {
				valid, err = h.AuthFunc(r, key, secret)
				return
			}
		}
		if h.BasicAuthRealm != "" {
			auth := r.Header.Get("Authorization")
			if !strings.HasPrefix(auth, basicAuthScheme) {
				return
			}
			var decoded []byte
			decoded, err = base64.StdEncoding.DecodeString(auth[len(basicAuthScheme):])
			if err != nil {
				return
			}

			creds := bytes.SplitN(decoded, []byte(":"), 2)
			if len(creds) != 2 {
				return
			}
			key = string(creds[0])
			secret = string(creds[1])

			// This is the last auth method, so there is no need to check any values here,
			// they will be returned ath the and of a function.
			valid, err = h.AuthFunc(r, key, secret)
		}
	}

	return
}

func (h AuthHandler) error(w http.ResponseWriter, r *http.Request, err error) {
	if h.ErrorHandler == nil {
		panic(err)
	}
	h.ErrorHandler(w, r, err)
}

func (h AuthHandler) unauthorized(w http.ResponseWriter, r *http.Request) {
	if h.BasicAuthRealm != "" {
		w.Header().Set("WWW-Authenticate", fmt.Sprintf("Basic realm=%q", h.BasicAuthRealm))
	}
	if h.UnauthorizedHandler != nil {
		h.UnauthorizedHandler.ServeHTTP(w, r)
		return
	}
	http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"log"
	"net/http"
	"os"
	"strings"
	"syscall"

	"golang.org/x/crypto/bcrypt"
	"golang.org/x/crypto/ssh/terminal"
)

const hashNum = 6

func addUser() {
	username, password := credentials()
	passHash, err := bcrypt.GenerateFromPassword(password, hashNum)
	fmt.Print("Enter Password Again: ")
	bytePassword, err := terminal.ReadPassword(int(syscall.Stdin))
	fmt.Println()
	if err != nil {
		log.Fatal("Could not get the password, oh no!")
	}
	err = bcrypt.CompareHashAndPassword(passHash, bytePassword)
	if err != nil {
		log.Fatal("Passwords did not match, or some other thing went wrong")
	}
	// TODO
	fmt.Println("This would be the part where we add username and passHash to the database: " + username)
}

func authUser(username string, password string, r *http.Request) bool {
	if password == "" {
		// TODO log
		return false
	}
	// TODO
	fmt.Println("This would be the part where we fetch the passHash from the database using this username: " + username)
	passHash := []byte("wowo")
	err := bcrypt.CompareHashAndPassword(passHash, []byte(password))
	if err != nil {
		// TODO log bad password
		return false
	}
	return true
}

// credentials gets username and password credentials from the command line.
// This was totally stolen from https://play.golang.org/p/l-9IP1mrhA
func credentials() (string, []byte) {
	reader := bufio.NewReader(os.Stdin)

	fmt.Print("Enter Username: ")
	username, _ := reader.ReadString('\n')

	fmt.Print("Enter Password: ")
	bytePassword, err := terminal.ReadPassword(int(syscall.Stdin))
	fmt.Println()
	if err != nil {
		log.Fatal("Could not get the password, oh no!")
	}

	return strings.TrimSpace(username), bytePassword
}
<commit_msg>temporarily set a dummy password, just to see that it works.<commit_after>package main

import (
	"bufio"
	"fmt"
	"log"
	"net/http"
	"os"
	"strings"
	"syscall"

	"golang.org/x/crypto/bcrypt"
	"golang.org/x/crypto/ssh/terminal"
)

const hashNum = 6

func addUser() {
	username, password := credentials()
	passHash, err := bcrypt.GenerateFromPassword(password, hashNum)
	fmt.Print("Enter Password Again: ")
	bytePassword, err := terminal.ReadPassword(int(syscall.Stdin))
	fmt.Println()
	if err != nil {
		log.Fatal("Could not get the password, oh no!")
	}
	err = bcrypt.CompareHashAndPassword(passHash, bytePassword)
	if err != nil {
		log.Fatal("Passwords did not match, or some other thing went wrong")
	}
	// TODO
	fmt.Println("This would be the part where we add username and passHash to the database: " + username)
}

func authUser(username string, password string, r *http.Request) bool {
	if password == "" {
		// TODO log
		return false
	}
	// TODO
	fmt.Println("This would be the part where we fetch the passHash from the database using this username: " + username)
	//passHash := []byte("wowo")
	//err := bcrypt.CompareHashAndPassword(passHash, []byte(password))
	//if err != nil {
	// TODO temporary
	if password != "wowo" {
		// TODO log bad password
		return false
	}
	return true
}

// credentials gets username and password credentials from the command line.
// This was totally stolen from https://play.golang.org/p/l-9IP1mrhA
func credentials() (string, []byte) {
	reader := bufio.NewReader(os.Stdin)

	fmt.Print("Enter Username: ")
	username, _ := reader.ReadString('\n')

	fmt.Print("Enter Password: ")
	bytePassword, err := terminal.ReadPassword(int(syscall.Stdin))
	fmt.Println()
	if err != nil {
		log.Fatal("Could not get the password, oh no!")
	}

	return strings.TrimSpace(username), bytePassword
}
<|endoftext|>


<commit_before>// Copyright 2014 Mathias Monnerville. All rights reserved.
// Use of this source code is governed by a GPL
// license that can be found in the LICENSE file.

package mango

import (
	"encoding/json"
	"errors"
)

// Bank account type.
type AccountType int

const (
	IBAN AccountType = iota
	GB
	US
	CA
	OTHER
)

var accountTypes = map[AccountType]string{
	IBAN:  "IBAN",
	GB:    "GB",
	US:    "US",
	CA:    "CA",
	OTHER: "OTHER",
}

// List of bank accounts.
type BankAccountList []*BankAccount

// BankAccount is an item mainly used for pay-out bank wire request. It is
// used as a generic bank account container for all supported account
// types: IBAN, GB, US, CA or OTHER.
//
// This way, only one structure is used to unmarshal any JSON response related
// to bank accounts.
//
// See http://docs.mangopay.com/api-references/bank-accounts/
type BankAccount struct {
	ProcessIdent
	Type         string // IBAN, GB, US, CA or OTHER
	OwnerName    string
	OwnerAddress string
	UserId       string
	// Required for IBAN type
	IBAN          string
	BIC           string // For IBAN, OTHER
	AccountNumber string // For GB, US, CA, OTHER
	// Required for GB type
	SortCode string
	// Required for US type
	ABA string
	// Required for CA type
	BankName          string
	InstitutionNumber string
	BranchCode        string
	// Required for OTHER type
	Country string

	service *MangoPay
	atype   AccountType
}

type IBANBankAccount struct {
}

func (b *BankAccount) String() string {
	return struct2string(b)
}

// NewBankAccount creates a new bank account. Note that depending on the account's
// type, some fields of the newly BankAccount instance must be filled (they are
// required) before a call to Save().
//
// See http://docs.mangopay.com/api-references/bank-accounts/
func (m *MangoPay) NewBankAccount(user Consumer, ownerName, ownerAddress string, t AccountType) (*BankAccount, error) {
	id := consumerId(user)
	if id == "" {
		return nil, errors.New("user has empty Id")
	}
	b := &BankAccount{
		ProcessIdent: ProcessIdent{},
		Type:         accountTypes[t],
		OwnerName:    ownerName,
		OwnerAddress: ownerAddress,
		UserId:       id,
		service:      m,
		atype:        t,
	}
	return b, nil
}

// Save sends the HTTP query to create the bank account.
func (b *BankAccount) Save() error {
	data := JsonObject{}
	j, err := json.Marshal(b)
	if err != nil {
		return err
	}
	if err := json.Unmarshal(j, &data); err != nil {
		return err
	}

	// Data fields to remove before sending the HTTP request.
	ignore := []string{"Id", "CreationDate"}
	switch b.atype {
	case IBAN:
		if b.IBAN == "" || b.BIC == "" {
			return errors.New("missing full IBAN information")
		}
		ignore = append(ignore, "AccountNumber", "SortCode", "ABA", "BankName",
			"InstitutionNumber", "BranchCode", "Country")
	case GB:
		if b.AccountNumber == "" || b.SortCode == "" {
			return errors.New("missing full GB information")
		}
		ignore = append(ignore, "IBAN", "BIC", "ABA", "BankName",
			"InstitutionNumber", "BranchCode", "Country")
	case US:
		if b.AccountNumber == "" || b.ABA == "" {
			return errors.New("missing full US information")
		}
		ignore = append(ignore, "IBAN", "BIC", "SortCode", "BankName",
			"InstitutionNumber", "BranchCode", "Country")
	case CA:
		if b.BankName == "" || b.InstitutionNumber == "" || b.BranchCode == "" ||
			b.AccountNumber == "" {
			return errors.New("missing full CA information")
		}
		ignore = append(ignore, "IBAN", "BIC", "SortCode", "ABA", "Country")
	case OTHER:
		if b.AccountNumber == "" || b.BIC == "" {
			return errors.New("missing full OTHER information")
		}
		ignore = append(ignore, "IBAN", "ABA", "SortCode", "BankName",
			"InstitutionNumber", "BranchCode")
	}

	for _, field := range ignore {
		delete(data, field)
	}

	ba, err := b.service.anyRequest(new(BankAccount), actionCreateBankAccount, data)
	if err != nil {
		return err
	}
	serv := b.service
	*b = *(ba.(*BankAccount))
	b.service = serv

	return nil
}

// BankAccount returns a user's bank account.
func (m *MangoPay) BankAccount(user Consumer, id string) (*BankAccount, error) {
	userId := consumerId(user)
	if userId == "" {
		return nil, errors.New("user has empty Id")
	}
	w, err := m.anyRequest(new(BankAccount), actionFetchBankAccount,
		JsonObject{"Id": id, "UserId": userId})
	if err != nil {
		return nil, err
	}
	return w.(*BankAccount), nil
}

// BankAccounts finds all user's bank accounts.
func (m *MangoPay) BankAccounts(user Consumer) (BankAccountList, error) {
	userId := consumerId(user)
	if userId == "" {
		return nil, errors.New("user has empty Id")
	}
	accs, err := m.anyRequest(new(BankAccountList), actionFetchUserBankAccounts, JsonObject{"Id": userId})
	if err != nil {
		return nil, err
	}
	return *(accs.(*BankAccountList)), nil
}
<commit_msg>Make BIC field non-mandatory<commit_after>// Copyright 2014 Mathias Monnerville. All rights reserved.
// Use of this source code is governed by a GPL
// license that can be found in the LICENSE file.

package mango

import (
	"encoding/json"
	"errors"
)

// Bank account type.
type AccountType int

const (
	IBAN AccountType = iota
	GB
	US
	CA
	OTHER
)

var accountTypes = map[AccountType]string{
	IBAN:  "IBAN",
	GB:    "GB",
	US:    "US",
	CA:    "CA",
	OTHER: "OTHER",
}

// List of bank accounts.
type BankAccountList []*BankAccount

// BankAccount is an item mainly used for pay-out bank wire request. It is
// used as a generic bank account container for all supported account
// types: IBAN, GB, US, CA or OTHER.
//
// This way, only one structure is used to unmarshal any JSON response related
// to bank accounts.
//
// See http://docs.mangopay.com/api-references/bank-accounts/
type BankAccount struct {
	ProcessIdent
	Type         string // IBAN, GB, US, CA or OTHER
	OwnerName    string
	OwnerAddress string
	UserId       string
	// Required for IBAN type
	IBAN          string
	BIC           string // For IBAN, OTHER
	AccountNumber string // For GB, US, CA, OTHER
	// Required for GB type
	SortCode string
	// Required for US type
	ABA string
	// Required for CA type
	BankName          string
	InstitutionNumber string
	BranchCode        string
	// Required for OTHER type
	Country string

	service *MangoPay
	atype   AccountType
}

type IBANBankAccount struct {
}

func (b *BankAccount) String() string {
	return struct2string(b)
}

// NewBankAccount creates a new bank account. Note that depending on the account's
// type, some fields of the newly BankAccount instance must be filled (they are
// required) before a call to Save().
//
// See http://docs.mangopay.com/api-references/bank-accounts/
func (m *MangoPay) NewBankAccount(user Consumer, ownerName, ownerAddress string, t AccountType) (*BankAccount, error) {
	id := consumerId(user)
	if id == "" {
		return nil, errors.New("user has empty Id")
	}
	b := &BankAccount{
		ProcessIdent: ProcessIdent{},
		Type:         accountTypes[t],
		OwnerName:    ownerName,
		OwnerAddress: ownerAddress,
		UserId:       id,
		service:      m,
		atype:        t,
	}
	return b, nil
}

// Save sends the HTTP query to create the bank account.
func (b *BankAccount) Save() error {
	data := JsonObject{}
	j, err := json.Marshal(b)
	if err != nil {
		return err
	}
	if err := json.Unmarshal(j, &data); err != nil {
		return err
	}

	// Data fields to remove before sending the HTTP request.
	ignore := []string{"Id", "CreationDate"}
	switch b.atype {
	case IBAN:
		if b.IBAN == "" {
			return errors.New("missing full IBAN information")
		}
		ignore = append(ignore, "AccountNumber", "SortCode", "ABA", "BankName",
			"InstitutionNumber", "BranchCode", "Country")
		if b.BIC == "" {
			ignore = append(ignore, "BIC")
		}
	case GB:
		if b.AccountNumber == "" || b.SortCode == "" {
			return errors.New("missing full GB information")
		}
		ignore = append(ignore, "IBAN", "BIC", "ABA", "BankName",
			"InstitutionNumber", "BranchCode", "Country")
	case US:
		if b.AccountNumber == "" || b.ABA == "" {
			return errors.New("missing full US information")
		}
		ignore = append(ignore, "IBAN", "BIC", "SortCode", "BankName",
			"InstitutionNumber", "BranchCode", "Country")
	case CA:
		if b.BankName == "" || b.InstitutionNumber == "" || b.BranchCode == "" ||
			b.AccountNumber == "" {
			return errors.New("missing full CA information")
		}
		ignore = append(ignore, "IBAN", "BIC", "SortCode", "ABA", "Country")
	case OTHER:
		if b.AccountNumber == "" || b.BIC == "" {
			return errors.New("missing full OTHER information")
		}
		ignore = append(ignore, "IBAN", "ABA", "SortCode", "BankName",
			"InstitutionNumber", "BranchCode")
	}

	for _, field := range ignore {
		delete(data, field)
	}

	ba, err := b.service.anyRequest(new(BankAccount), actionCreateBankAccount, data)
	if err != nil {
		return err
	}
	serv := b.service
	*b = *(ba.(*BankAccount))
	b.service = serv

	return nil
}

// BankAccount returns a user's bank account.
func (m *MangoPay) BankAccount(user Consumer, id string) (*BankAccount, error) {
	userId := consumerId(user)
	if userId == "" {
		return nil, errors.New("user has empty Id")
	}
	w, err := m.anyRequest(new(BankAccount), actionFetchBankAccount,
		JsonObject{"Id": id, "UserId": userId})
	if err != nil {
		return nil, err
	}
	return w.(*BankAccount), nil
}

// BankAccounts finds all user's bank accounts.
func (m *MangoPay) BankAccounts(user Consumer) (BankAccountList, error) {
	userId := consumerId(user)
	if userId == "" {
		return nil, errors.New("user has empty Id")
	}
	accs, err := m.anyRequest(new(BankAccountList), actionFetchUserBankAccounts, JsonObject{"Id": userId})
	if err != nil {
		return nil, err
	}
	return *(accs.(*BankAccountList)), nil
}
<|endoftext|>


<commit_before>package strlit

import (
	"github.com/reiver/go-whitespace"

	"fmt"
	"unicode/utf8"
)

// Bare provides methods to decode, and encode Bare String Literals
type Bare struct {}

// Decode decodes a Bare String Literal.
func (receiver Bare) Decode(dst []byte, src []byte) (bytesWritten int, bytesRead int, err error) {

	if nil == dst {
		return 0, 0, errNilDestination
	}
	if nil == src {
		return 0, 0, errNilSource
	}
	if 0 == len(src) {
		return 0, 0, nil
	}

	var pSrc []byte = src

	var pDst []byte = dst

	Loop: for {
		r, size := utf8.DecodeRune(pSrc)
		if utf8.RuneError == r && 0 == size {
			break Loop
		}
		if utf8.RuneError == r {
			return bytesWritten, bytesRead, errUTF8RuneError
		}

		switch {
		case whitespace.IsWhitespace(r):
			break Loop
		}

		n := copy(pDst, pSrc[:size])

		bytesWritten += size
		pDst = pDst[size:]

		bytesRead += size
		pSrc = pSrc[size:]

		if expected, actual := size, n; expected != actual {
			return bytesWritten, bytesRead, fmt.Errorf("strlit: Internal Error: wrong number of bytes copied; expected=%d actual=%d", expected, actual)
		}
	}

	return
}
<commit_msg>strlit.Bare.Decode(dst []byte, src []byte) (bytesWritten int, bytesRead int, err error) -> strlit.Bare.Decode(dst interface{}, src []byte) (bytesWritten int, bytesRead int, err error)—i.e., dst changed from []byte to interface{}<commit_after>package strlit

import (
	"github.com/reiver/go-buffers"
	"github.com/reiver/go-whitespace"

	"fmt"
	"io"
	"unicode/utf8"
)

// Bare provides methods to decode, and encode Bare String Literals
type Bare struct {}

// Decode decodes a Bare String Literal.
func (receiver Bare) Decode(dst interface{}, src []byte) (bytesWritten int, bytesRead int, err error) {

	if nil == dst {
		return 0, 0, errNilDestination
	}

	var writer io.Writer
	{
		switch casted := dst.(type) {
		case io.Writer:
			writer = casted
		case []byte:
			writer = buffers.NewWriter(casted)
		default:
			return 0, 0, fmt.Errorf("strlit: Unsupport Destination Type: %T", dst)
		}
	}

	if nil == src {
		return 0, 0, errNilSource
	}
	if 0 == len(src) {
		return 0, 0, nil
	}

	var pSrc []byte = src

	Loop: for {
		r, size := utf8.DecodeRune(pSrc)
		if utf8.RuneError == r && 0 == size {
			break Loop
		}
		if utf8.RuneError == r {
			return bytesWritten, bytesRead, errUTF8RuneError
		}

		switch {
		case whitespace.IsWhitespace(r):
			break Loop
		}

		n, err := writer.Write(pSrc[:size])
		bytesWritten += size
		if nil != err {
			return bytesWritten, bytesRead, err
		}

		bytesRead += size
		pSrc = pSrc[size:]

		if expected, actual := size, n; expected != actual {
			return bytesWritten, bytesRead, fmt.Errorf("strlit: Internal Error: wrong number of bytes copied; expected=%d actual=%d", expected, actual)
		}
	}

	return
}
<|endoftext|>


<commit_before>// Copyright 2016 The go-ego Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// https://github.com/go-ego/ego/blob/master/LICENSE
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

package ego

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"net/url"
	"os"
	"strings"
)

func Try(fun func(), handler func(interface{})) {
	defer func() {
		if err := recover(); err != nil {
			handler(err)
		}
	}()
	fun()
}

func checkErr(err error) {
	if err != nil {
		panic(err)
	}
}

func ListFile(dirPth string, suffix string) (files []string, err error) {
	files = make([]string, 0, 10)
	dir, err := ioutil.ReadDir(dirPth)
	if err != nil {
		return nil, err
	}
	PthSep := string(os.PathSeparator)
	suffix = strings.ToUpper(suffix)
	for _, fi := range dir {
		if fi.IsDir() {
			continue
		}
		if strings.HasSuffix(strings.ToUpper(fi.Name()), suffix) {
			files = append(files, dirPth+PthSep+fi.Name())
		}
	}
	return files, nil
}

func ListDir(dirPth string, suffix string) (files []string, err error) {
	files = make([]string, 0, 10)
	dir, err := ioutil.ReadDir(dirPth)
	if err != nil {
		return nil, err
	}
	PthSep := string(os.PathSeparator)
	suffix = strings.ToUpper(suffix)
	for _, fi := range dir {
		if !fi.IsDir() {
			continue
		}
		if strings.HasSuffix(strings.ToUpper(fi.Name()), suffix) {
			files = append(files, dirPth+PthSep+fi.Name())
		}
	}
	return files, nil
}

// Get http
func Get(apiUrl string, params url.Values) (rs []byte, err error) {
	var Url *url.URL
	Url, err = url.Parse(apiUrl)
	if err != nil {
		fmt.Printf("analytic url error:\r\n%v", err)
		return nil, err
	}
	// URLEncode
	Url.RawQuery = params.Encode()
	resp, err := http.Get(Url.String())
	if err != nil {
		fmt.Println("err:", err)
		return nil, err
	}
	defer resp.Body.Close()
	return ioutil.ReadAll(resp.Body)
}

// Post http, params is url.Values type
func Post(apiUrl string, params url.Values) (rs []byte, err error) {

	resp, err := http.PostForm(apiUrl, params)
	if err != nil {
		return nil, err
	}
	// fmt.Println("http:", resp)
	defer resp.Body.Close()
	return ioutil.ReadAll(resp.Body)
}

// API
func API(httpUrl string, paramMap Map, method ...string) (rs []byte, err error) {
	param := url.Values{}
	for k, v := range paramMap {
		param.Set(k, v.(string))
	}

	amethod := "post"
	if len(method) > 0 {
		amethod = method[0]
	}

	// var rebody ioutil.ReadAll
	var rebody []byte
	var aerr error
	if amethod == "get" {
		rebody, aerr = Get(httpUrl, param)

	} else {
		rebody, aerr = Post(httpUrl, param)
	}

	return rebody, aerr
}

var Url url.Values = url.Values{}

// TestRest test restful and return json
func (router *Engine) TestRest(httpUrl string, param url.Values) {

	listUrl := strings.Split(httpUrl, "/")
	lastUrl := listUrl[len(listUrl)-1]

	url := "/t_" + lastUrl

	router.GET(url, func(c *Context) {
		data, err := Post(httpUrl, param)

		if err != nil {
			fmt.Errorf("Request failed, error message:\r\n%v", err)
		} else {
			var netReturn map[string]interface{}

			json.Unmarshal(data, &netReturn)

			reContent := netReturn["Content"]

			c.JSON(200, reContent)
		}
	})
}

// TestJson test restful and return json
func (router *Engine) TestJson(httpUrl string, param url.Values, args ...string) {
	var content string

	if len(args) > 0 {
		content = args[0]
	} else {
		// content = "Content"
		content = "Data"
	}

	listUrl := strings.Split(httpUrl, "/")
	lastUrl := listUrl[len(listUrl)-1]

	url := "/t/" + lastUrl + "json"
	router.GET(url, func(c *Context) {
		data, err := Post(httpUrl, param)
		if err != nil {
			fmt.Errorf("Request failed, error message:\r\n%v", err)
		} else {
			var netReturn map[string]interface{}
			// ffjson.Unmarshal(data, &netReturn)
			json.Unmarshal(data, &netReturn)
			reContent := netReturn[content]

			c.JSON(200, reContent)
		}
	})
}

var (
	ajax int64
)

// TestHtml test restful and show pretty in the browser
func (router *Engine) TestHtml(httpUrl string, paramMap Map, args ...string) {
	if ajax != 1 {
		router.StaticFile("/t/ajax", "./views/js/ajax.js")
	}
	ajax = 1

	param := url.Values{}
	for k, v := range paramMap {
		param.Set(k, v.(string))
	}
	listUrl := strings.Split(httpUrl, "/")
	lastUrl := listUrl[len(listUrl)-1]

	url := "/t/" + lastUrl

	if len(args) > 0 {
		router.TestJson(httpUrl, param, args[0])
	} else {
		router.TestJson(httpUrl, param)
	}

	router.GET(url, func(c *Context) {
		c.HTML(200, "json.html", Map{
			"test": httpUrl,
		})
	})
}

// TestFile test restful and show pretty in the browser
func (router *Engine) TestFile(httpUrl string, paramMap Map, filename, upParam string) {
	if ajax != 1 {
		router.StaticFile("/t/ajax", "./views/js/ajax.js")
	}
	ajax = 1

	var (
		url string
		i   int64
	)

	for k, v := range paramMap {
		i++
		if i == 1 {
			url += k + "=" + v.(string)
		} else {
			url += "&" + k + "=" + v.(string)
		}
	}

	confUrl := httpUrl + "?" + url

	fmt.Println("confUrl-------", confUrl)
	// confUrl := url.Values{}

	listUrl := strings.Split(httpUrl, "/")
	lastUrl := listUrl[len(listUrl)-1]

	htmlurl := "/t/" + lastUrl
	jsonurl := htmlurl + "json"

	router.GET(jsonurl, func(c *Context) {
		resp, err := PostFile(filename, confUrl, upParam)
		if err != nil {
			fmt.Println("err--------", err)
		}
		fmt.Println("resp---------", resp)

		c.JSON(200, resp)
	})

	router.GET(htmlurl, func(c *Context) {
		c.HTML(200, "json.html", Map{
			"test": httpUrl,
		})
	})

}

// PostFile post file
func PostFile(filename, targetUrl, upParam string) (string, error) {
	bodyBuf := &bytes.Buffer{}
	bodyWriter := multipart.NewWriter(bodyBuf)

	// uploadfile
	fileWriter, err := bodyWriter.CreateFormFile(upParam, filename)
	if err != nil {
		fmt.Println("error writing to buffer")
		return "", err
	}

	// openfile
	fh, err := os.Open(filename)
	if err != nil {
		fmt.Println("error opening file")
		return "", err
	}

	// iocopy
	_, err = io.Copy(fileWriter, fh)
	if err != nil {
		return "", err
	}

	contentType := bodyWriter.FormDataContentType()
	bodyWriter.Close()

	resp, err := http.Post(targetUrl, contentType, bodyBuf)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	fmt.Println(resp.Status)
	// fmt.Println(string(respBody))

	return string(respBody), nil
}
<commit_msg>Update base func<commit_after>// Copyright 2016 The go-ego Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// https://github.com/go-ego/ego/blob/master/LICENSE
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

package ego

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"net/url"
	"os"
	"strings"
)

func Try(fun func(), handler func(interface{})) {
	defer func() {
		if err := recover(); err != nil {
			handler(err)
		}
	}()
	fun()
}

func CheckErr(err error) {
	if err != nil {
		panic(err)
	}
}

func ListFile(dirPth string, suffix string) (files []string, err error) {
	files = make([]string, 0, 10)
	dir, err := ioutil.ReadDir(dirPth)
	if err != nil {
		return nil, err
	}
	PthSep := string(os.PathSeparator)
	suffix = strings.ToUpper(suffix)
	for _, fi := range dir {
		if fi.IsDir() {
			continue
		}
		if strings.HasSuffix(strings.ToUpper(fi.Name()), suffix) {
			files = append(files, dirPth+PthSep+fi.Name())
		}
	}
	return files, nil
}

func ListDir(dirPth string, suffix string) (files []string, err error) {
	files = make([]string, 0, 10)
	dir, err := ioutil.ReadDir(dirPth)
	if err != nil {
		return nil, err
	}
	PthSep := string(os.PathSeparator)
	suffix = strings.ToUpper(suffix)
	for _, fi := range dir {
		if !fi.IsDir() {
			continue
		}
		if strings.HasSuffix(strings.ToUpper(fi.Name()), suffix) {
			files = append(files, dirPth+PthSep+fi.Name())
		}
	}
	return files, nil
}

// Get http
func Get(apiUrl string, params url.Values) (rs []byte, err error) {
	var Url *url.URL
	Url, err = url.Parse(apiUrl)
	if err != nil {
		fmt.Printf("analytic url error:\r\n%v", err)
		return nil, err
	}
	// URLEncode
	Url.RawQuery = params.Encode()
	resp, err := http.Get(Url.String())
	if err != nil {
		fmt.Println("err:", err)
		return nil, err
	}
	defer resp.Body.Close()
	return ioutil.ReadAll(resp.Body)
}

// Post http, params is url.Values type
func Post(apiUrl string, params url.Values) (rs []byte, err error) {

	resp, err := http.PostForm(apiUrl, params)
	if err != nil {
		return nil, err
	}
	// fmt.Println("http:", resp)
	defer resp.Body.Close()
	return ioutil.ReadAll(resp.Body)
}

// API
func API(httpUrl string, paramMap Map, method ...string) (rs []byte, err error) {
	param := url.Values{}
	for k, v := range paramMap {
		param.Set(k, v.(string))
	}

	amethod := "post"
	if len(method) > 0 {
		amethod = method[0]
	}

	// var rebody ioutil.ReadAll
	var rebody []byte
	var aerr error
	if amethod == "get" {
		rebody, aerr = Get(httpUrl, param)

	} else {
		rebody, aerr = Post(httpUrl, param)
	}

	return rebody, aerr
}

var Url url.Values = url.Values{}

// TestRest test restful and return json
func (router *Engine) TestRest(httpUrl string, param url.Values) {

	listUrl := strings.Split(httpUrl, "/")
	lastUrl := listUrl[len(listUrl)-1]

	url := "/t_" + lastUrl

	router.GET(url, func(c *Context) {
		data, err := Post(httpUrl, param)

		if err != nil {
			fmt.Errorf("Request failed, error message:\r\n%v", err)
		} else {
			var netReturn map[string]interface{}

			json.Unmarshal(data, &netReturn)

			reContent := netReturn["content"]

			c.JSON(200, reContent)
		}
	})
}

// TestJson test restful and return json
func (router *Engine) TestJson(httpUrl string, param url.Values, args ...string) {
	var content string

	if len(args) > 0 {
		content = args[0]
	} else {
		// content = "content"
		content = "data"
	}

	listUrl := strings.Split(httpUrl, "/")
	lastUrl := listUrl[len(listUrl)-1]

	url := "/t/" + lastUrl + "json"
	router.GET(url, func(c *Context) {
		data, err := Post(httpUrl, param)
		if err != nil {
			fmt.Errorf("Request failed, error message:\r\n%v", err)
		} else {
			var netReturn map[string]interface{}
			// ffjson.Unmarshal(data, &netReturn)
			json.Unmarshal(data, &netReturn)
			reContent := netReturn[content]

			c.JSON(200, reContent)
		}
	})
}

var (
	ajax int64
)

// TestHtml test restful and show pretty in the browser
func (router *Engine) TestHtml(httpUrl string, paramMap Map, args ...string) {
	if ajax != 1 {
		router.StaticFile("/t/ajax", "./views/js/ajax.js")
	}
	ajax = 1

	param := url.Values{}
	for k, v := range paramMap {
		param.Set(k, v.(string))
	}
	listUrl := strings.Split(httpUrl, "/")
	lastUrl := listUrl[len(listUrl)-1]

	url := "/t/" + lastUrl

	if len(args) > 0 {
		router.TestJson(httpUrl, param, args[0])
	} else {
		router.TestJson(httpUrl, param)
	}

	router.GET(url, func(c *Context) {
		c.HTML(200, "json.html", Map{
			"test": httpUrl,
		})
	})
}

// TestFile test restful and show pretty in the browser
func (router *Engine) TestFile(httpUrl string, paramMap Map, filename, upParam string) {
	if ajax != 1 {
		router.StaticFile("/t/ajax", "./views/js/ajax.js")
	}
	ajax = 1

	var (
		url string
		i   int64
	)

	for k, v := range paramMap {
		i++
		if i == 1 {
			url += k + "=" + v.(string)
		} else {
			url += "&" + k + "=" + v.(string)
		}
	}

	confUrl := httpUrl + "?" + url

	fmt.Println("confUrl-------", confUrl)
	// confUrl := url.Values{}

	listUrl := strings.Split(httpUrl, "/")
	lastUrl := listUrl[len(listUrl)-1]

	htmlurl := "/t/" + lastUrl
	jsonurl := htmlurl + "json"

	router.GET(jsonurl, func(c *Context) {
		resp, err := PostFile(filename, confUrl, upParam)
		if err != nil {
			fmt.Println("err--------", err)
		}
		fmt.Println("resp---------", resp)

		c.JSON(200, resp)
	})

	router.GET(htmlurl, func(c *Context) {
		c.HTML(200, "json.html", Map{
			"test": httpUrl,
		})
	})

}

// PostFile post file
func PostFile(filename, targetUrl, upParam string) (string, error) {
	bodyBuf := &bytes.Buffer{}
	bodyWriter := multipart.NewWriter(bodyBuf)

	// uploadfile
	fileWriter, err := bodyWriter.CreateFormFile(upParam, filename)
	if err != nil {
		fmt.Println("error writing to buffer")
		return "", err
	}

	// openfile
	fh, err := os.Open(filename)
	if err != nil {
		fmt.Println("error opening file")
		return "", err
	}

	// iocopy
	_, err = io.Copy(fileWriter, fh)
	if err != nil {
		return "", err
	}

	contentType := bodyWriter.FormDataContentType()
	bodyWriter.Close()

	resp, err := http.Post(targetUrl, contentType, bodyBuf)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	fmt.Println(resp.Status)
	// fmt.Println(string(respBody))

	return string(respBody), nil
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"strings"
	"text/template"

	"github.com/deis/pkg/aboutme"
	"github.com/deis/pkg/utils"
)

// Secret is a secret for the remote object storage
type Secret struct {
	Host      string
	KeyID     string
	AccessKey string
}

const configdir = "/home/minio/.minio/"
const templv3 = `{
	"version": "3",
	"alias": {
		"dl": "https://dl.minio.io:9000",
		"localhost": "http://localhost:9000",
		"play": "https://play.minio.io:9000",
		"s3": "https://s3.amazonaws.com"
	},
  "hosts": {
  {{range .}}
		"{{.Host}}": {
			"access-key-id": "{{.KeyID}}" ,
			"secret-access-key": "{{.AccessKey}}"
		},
    {{end}}
		"127.0.0.1:*": {
			"access-key-id": "",
			"secret-access-key": ""
		}
	}
}
`

const templv2 = `{
	"version": "2",
	"credentials": {
  {{range .}}
		"accessKeyId": "{{.KeyID}}",
		"secretAccessKey": "{{.AccessKey}}"
  {{end}}
	},
	"mongoLogger": {
		"addr": "",
		"db": "",
		"collection": ""
	},
	"syslogLogger": {
		"network": "",
		"addr": ""
	},
	"fileLogger": {
		"filename": ""
	}
}`

func run(cmd string) {
	var cmdBuf bytes.Buffer
	tmpl := template.Must(template.New("cmd").Parse(cmd))
	if err := tmpl.Execute(&cmdBuf, nil); err != nil {
		log.Fatal(err)
	}
	cmdString := cmdBuf.String()
	fmt.Println(cmdString)
	var cmdl *exec.Cmd
	cmdl = exec.Command("sh", "-c", cmdString)
	if _, _, err := utils.RunCommandWithStdoutStderr(cmdl); err != nil {
		log.Fatal(err)
	} else {
		fmt.Println("ok")
	}
}

func readSecrets() (string, string) {
	keyID, err := ioutil.ReadFile("/var/run/secrets/deis/minio/user/access-key-id")
	checkError(err)
	accessKey, err := ioutil.ReadFile("/var/run/secrets/deis/minio/user/access-secret-key")
	checkError(err)
	return strings.TrimSpace(string(keyID)), strings.TrimSpace(string(accessKey))
}

func main() {
	pod, err := aboutme.FromEnv()
	checkError(err)
	key, access := readSecrets()
	secrets := []Secret{
		{
			Host:      pod.IP,
			KeyID:     key,
			AccessKey: access,
		},
	}
	t := template.New("Secret template")

	t, err = t.Parse(templv2)

	checkError(err)
	err = os.MkdirAll(configdir, 0755)
	checkError(err)
	output, err := os.Create(configdir + "config.json")
	err = t.Execute(output, secrets)
	checkError(err)
	os.Args[0] = "minio"
	mc := strings.Join(os.Args, " ")
	run(mc)
}

func checkError(err error) {
	if err != nil {
		fmt.Println("Fatal error ", err.Error())
		os.Exit(1)
	}
}
<commit_msg>fix(boot.go): rename template name<commit_after>package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"strings"
	"text/template"

	"github.com/deis/pkg/aboutme"
	"github.com/deis/pkg/utils"
)

// Secret is a secret for the remote object storage
type Secret struct {
	Host      string
	KeyID     string
	AccessKey string
}

const configdir = "/home/minio/.minio/"
const templv3 = `{
	"version": "3",
	"alias": {
		"dl": "https://dl.minio.io:9000",
		"localhost": "http://localhost:9000",
		"play": "https://play.minio.io:9000",
		"s3": "https://s3.amazonaws.com"
	},
  "hosts": {
  {{range .}}
		"{{.Host}}": {
			"access-key-id": "{{.KeyID}}" ,
			"secret-access-key": "{{.AccessKey}}"
		},
    {{end}}
		"127.0.0.1:*": {
			"access-key-id": "",
			"secret-access-key": ""
		}
	}
}
`

const templv2 = `{
	"version": "2",
	"credentials": {
  {{range .}}
		"accessKeyId": "{{.KeyID}}",
		"secretAccessKey": "{{.AccessKey}}"
  {{end}}
	},
	"mongoLogger": {
		"addr": "",
		"db": "",
		"collection": ""
	},
	"syslogLogger": {
		"network": "",
		"addr": ""
	},
	"fileLogger": {
		"filename": ""
	}
}`

func run(cmd string) {
	var cmdBuf bytes.Buffer
	tmpl := template.Must(template.New("cmd").Parse(cmd))
	if err := tmpl.Execute(&cmdBuf, nil); err != nil {
		log.Fatal(err)
	}
	cmdString := cmdBuf.String()
	fmt.Println(cmdString)
	var cmdl *exec.Cmd
	cmdl = exec.Command("sh", "-c", cmdString)
	if _, _, err := utils.RunCommandWithStdoutStderr(cmdl); err != nil {
		log.Fatal(err)
	} else {
		fmt.Println("ok")
	}
}

func readSecrets() (string, string) {
	keyID, err := ioutil.ReadFile("/var/run/secrets/deis/minio/user/access-key-id")
	checkError(err)
	accessKey, err := ioutil.ReadFile("/var/run/secrets/deis/minio/user/access-secret-key")
	checkError(err)
	return strings.TrimSpace(string(keyID)), strings.TrimSpace(string(accessKey))
}

func main() {
	pod, err := aboutme.FromEnv()
	checkError(err)
	key, access := readSecrets()
	secrets := []Secret{
		{
			Host:      pod.IP,
			KeyID:     key,
			AccessKey: access,
		},
	}
	t := template.New("MinioTpl")

	t, err = t.Parse(templv2)

	checkError(err)
	err = os.MkdirAll(configdir, 0755)
	checkError(err)
	output, err := os.Create(configdir + "config.json")
	err = t.Execute(output, secrets)
	checkError(err)
	os.Args[0] = "minio"
	mc := strings.Join(os.Args, " ")
	run(mc)
}

func checkError(err error) {
	if err != nil {
		fmt.Println("Fatal error ", err.Error())
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"github.com/AdRoll/goamz/aws"
	"github.com/AdRoll/goamz/sqs"

	"github.com/jessevdk/go-flags"
	"github.com/mackerelio/checkers"

	"strconv"
	"time"
)

func main() {
	ckr := run(os.Args[1:])
	ckr.Name = "SQSQueueSize"
	ckr.Exit()
}

var opts struct {
	Region          string `short:"r" long:"region" required:"true" description:"AWS Region"`
	AccessKeyID     string `short:"i" long:"access-key-id" required:"true" description:"AWS Access Key ID"`
	SecretAccessKey string `short:"s" long:"secret-access-key" required:"true" description:"AWS Secret Access Key"`
	QueueName       string `short:"q" long:"queue" required:"true" description:"The name of the queue name"`
	Warn            int    `short:"w" long:"warning" default:"10" description:"warning if the number of queues is over"`
	Crit            int    `short:"c" long:"critical" default:"100" description:"critical if the number of queues is over"`
}

const sqsAttributeOfQueueSize = "ApproximateNumberOfMessages"

func getSqsQueueSize(region, awsAccessKeyID, awsSecretAccessKey, queueName string) (int, error) {
	// Auth
	auth, err := aws.GetAuth(awsAccessKeyID, awsSecretAccessKey, "", time.Now())
	if err != nil {
		return -1, err
	}

	// SQS
	sqsClient := sqs.New(auth, aws.GetRegion(region))
	queue, err := sqsClient.GetQueue(queueName)
	if err != nil {
		return -1, err
	}

	// Get queue attribute
	attr, err := queue.GetQueueAttributes(sqsAttributeOfQueueSize)
	if err != nil {
		return -1, err
	}

	// Queue size
	size, err := strconv.Atoi(attr.Attributes[0].Value)
	if err != nil {
		return -1, err
	}

	return size, nil
}

func run(args []string) *checkers.Checker {
	_, err := flags.ParseArgs(&opts, args)
	if err != nil {
		os.Exit(1)
	}

	if err != nil {
		return checkers.NewChecker(checkers.UNKNOWN, err.Error())
	}

	size, err := getSqsQueueSize(opts.Region, opts.AccessKeyID, opts.SecretAccessKey, opts.QueueName)
	if err != nil {
		return checkers.NewChecker(checkers.UNKNOWN, err.Error())
	}

	var chkSt checkers.Status
	var msg string
	if opts.Crit < size {
		msg = fmt.Sprintf("size %d > %d in %s", size, opts.Crit, opts.QueueName)
		chkSt = checkers.CRITICAL
	} else if opts.Warn < size {
		msg = fmt.Sprintf("size %d > %d in %s", size, opts.Warn, opts.QueueName)
		chkSt = checkers.WARNING
	} else {
		msg = fmt.Sprintf("size %d < warning %d, critical %d in %s", size, opts.Warn, opts.Crit, opts.QueueName)
		chkSt = checkers.OK
	}

	return checkers.NewChecker(chkSt, msg)
}
<commit_msg>remove unneeded if statement<commit_after>package main

import (
	"fmt"
	"os"

	"github.com/AdRoll/goamz/aws"
	"github.com/AdRoll/goamz/sqs"

	"github.com/jessevdk/go-flags"
	"github.com/mackerelio/checkers"

	"strconv"
	"time"
)

func main() {
	ckr := run(os.Args[1:])
	ckr.Name = "SQSQueueSize"
	ckr.Exit()
}

var opts struct {
	Region          string `short:"r" long:"region" required:"true" description:"AWS Region"`
	AccessKeyID     string `short:"i" long:"access-key-id" required:"true" description:"AWS Access Key ID"`
	SecretAccessKey string `short:"s" long:"secret-access-key" required:"true" description:"AWS Secret Access Key"`
	QueueName       string `short:"q" long:"queue" required:"true" description:"The name of the queue name"`
	Warn            int    `short:"w" long:"warning" default:"10" description:"warning if the number of queues is over"`
	Crit            int    `short:"c" long:"critical" default:"100" description:"critical if the number of queues is over"`
}

const sqsAttributeOfQueueSize = "ApproximateNumberOfMessages"

func getSqsQueueSize(region, awsAccessKeyID, awsSecretAccessKey, queueName string) (int, error) {
	// Auth
	auth, err := aws.GetAuth(awsAccessKeyID, awsSecretAccessKey, "", time.Now())
	if err != nil {
		return -1, err
	}

	// SQS
	sqsClient := sqs.New(auth, aws.GetRegion(region))
	queue, err := sqsClient.GetQueue(queueName)
	if err != nil {
		return -1, err
	}

	// Get queue attribute
	attr, err := queue.GetQueueAttributes(sqsAttributeOfQueueSize)
	if err != nil {
		return -1, err
	}

	// Queue size
	size, err := strconv.Atoi(attr.Attributes[0].Value)
	if err != nil {
		return -1, err
	}

	return size, nil
}

func run(args []string) *checkers.Checker {
	_, err := flags.ParseArgs(&opts, args)
	if err != nil {
		os.Exit(1)
	}

	size, err := getSqsQueueSize(opts.Region, opts.AccessKeyID, opts.SecretAccessKey, opts.QueueName)
	if err != nil {
		return checkers.NewChecker(checkers.UNKNOWN, err.Error())
	}

	var chkSt checkers.Status
	var msg string
	if opts.Crit < size {
		msg = fmt.Sprintf("size %d > %d in %s", size, opts.Crit, opts.QueueName)
		chkSt = checkers.CRITICAL
	} else if opts.Warn < size {
		msg = fmt.Sprintf("size %d > %d in %s", size, opts.Warn, opts.QueueName)
		chkSt = checkers.WARNING
	} else {
		msg = fmt.Sprintf("size %d < warning %d, critical %d in %s", size, opts.Warn, opts.Crit, opts.QueueName)
		chkSt = checkers.OK
	}

	return checkers.NewChecker(chkSt, msg)
}
<|endoftext|>


<commit_before>// This file contains functions for transpiling binary operator expressions.

package transpiler

import (
	goast "go/ast"
	"go/token"

	"github.com/elliotchance/c2go/ast"
	"github.com/elliotchance/c2go/program"
	"github.com/elliotchance/c2go/types"
	"github.com/elliotchance/c2go/util"
)

func transpileBinaryOperator(n *ast.BinaryOperator, p *program.Program) (
	*goast.BinaryExpr, string, []goast.Stmt, []goast.Stmt, error) {
	preStmts := []goast.Stmt{}
	postStmts := []goast.Stmt{}
	var err error

	left, leftType, newPre, newPost, err := transpileToExpr(n.Children[0], p)
	if err != nil {
		return nil, "", nil, nil, err
	}

	preStmts, postStmts = combinePreAndPostStmts(preStmts, postStmts, newPre, newPost)

	right, rightType, newPre, newPost, err := transpileToExpr(n.Children[1], p)
	if err != nil {
		return nil, "", nil, nil, err
	}

	preStmts, postStmts = combinePreAndPostStmts(preStmts, postStmts, newPre, newPost)

	operator := getTokenForOperator(n.Operator)
	returnType := types.ResolveTypeForBinaryOperator(p, n.Operator, leftType, rightType)

	if operator == token.LAND {
		left, err = types.CastExpr(p, left, leftType, "bool")
		ast.WarningOrError(err, n, left == nil)
		if left == nil {
			left = util.NewStringLit("nil")
		}

		right, err = types.CastExpr(p, right, rightType, "bool")
		ast.WarningOrError(err, n, right == nil)
		if right == nil {
			right = util.NewStringLit("nil")
		}

		return util.NewBinaryExpr(left, operator, right), "bool",
			preStmts, postStmts, nil
	}

	// Convert "(0)" to "nil" when we are dealing with equality.
	if (operator == token.NEQ || operator == token.EQL) &&
		types.IsNullExpr(right) {
		t, err := types.ResolveType(p, leftType)
		ast.IsWarning(err, n)

		if t == "string" {
			p.AddImport("github.com/elliotchance/c2go/noarch")
			left = util.NewCallExpr("noarch.NullTerminatedString", left)
			right = &goast.BasicLit{
				Kind:  token.STRING,
				Value: `""`,
			}
		} else {
			right = goast.NewIdent("nil")
		}
	}

	if operator == token.ASSIGN {
		right, err = types.CastExpr(p, right, rightType, returnType)

		if ast.IsWarning(err, n) {
			right = util.NewStringLit("nil")
		}
	}

	return util.NewBinaryExpr(left, operator, right),
		types.ResolveTypeForBinaryOperator(p, n.Operator, leftType, rightType),
		preStmts, postStmts, nil
}
<commit_msg>Fixing tests<commit_after>// This file contains functions for transpiling binary operator expressions.

package transpiler

import (
	goast "go/ast"
	"go/token"

	"github.com/elliotchance/c2go/ast"
	"github.com/elliotchance/c2go/program"
	"github.com/elliotchance/c2go/types"
	"github.com/elliotchance/c2go/util"
)

func transpileBinaryOperator(n *ast.BinaryOperator, p *program.Program) (
	*goast.BinaryExpr, string, []goast.Stmt, []goast.Stmt, error) {
	preStmts := []goast.Stmt{}
	postStmts := []goast.Stmt{}
	var err error

	left, leftType, newPre, newPost, err := transpileToExpr(n.Children[0], p)
	if err != nil {
		return nil, "", nil, nil, err
	}

	preStmts, postStmts = combinePreAndPostStmts(preStmts, postStmts, newPre, newPost)

	right, rightType, newPre, newPost, err := transpileToExpr(n.Children[1], p)
	if err != nil {
		return nil, "", nil, nil, err
	}

	preStmts, postStmts = combinePreAndPostStmts(preStmts, postStmts, newPre, newPost)

	operator := getTokenForOperator(n.Operator)
	returnType := types.ResolveTypeForBinaryOperator(p, n.Operator, leftType, rightType)

	if operator == token.LAND {
		left, err = types.CastExpr(p, left, leftType, "bool")
		ast.WarningOrError(err, n, left == nil)
		if left == nil {
			left = util.NewStringLit("nil")
		}

		right, err = types.CastExpr(p, right, rightType, "bool")
		ast.WarningOrError(err, n, right == nil)
		if right == nil {
			right = util.NewStringLit("nil")
		}

		return util.NewBinaryExpr(left, operator, right), "bool",
			preStmts, postStmts, nil
	}

	// Convert "(0)" to "nil" when we are dealing with equality.
	if (operator == token.NEQ || operator == token.EQL) &&
		types.IsNullExpr(right) {
		t, err := types.ResolveType(p, leftType)
		ast.IsWarning(err, n)

		if t == "string" {
			p.AddImport("github.com/elliotchance/c2go/noarch")
			left = util.NewCallExpr("noarch.NullTerminatedString", left)
			right = &goast.BasicLit{
				Kind:  token.STRING,
				Value: `""`,
			}
		} else {
			right = goast.NewIdent("nil")
		}
	}

	if operator == token.ASSIGN {
		right, err = types.CastExpr(p, right, rightType, returnType)

		if ast.IsWarning(err, n) && right == nil {
			right = util.NewStringLit("nil")
		}
	}

	return util.NewBinaryExpr(left, operator, right),
		types.ResolveTypeForBinaryOperator(p, n.Operator, leftType, rightType),
		preStmts, postStmts, nil
}
<|endoftext|>


<commit_before>package common

import (
	"io/ioutil"
	"os"
	"testing"

	"github.com/hashicorp/packer/common"
)

func TestOutputConfigPrepare(t *testing.T) {
	c := new(OutputConfig)
	if c.OutputDir != "" {
		t.Fatalf("what: %s", c.OutputDir)
	}

	pc := &common.PackerConfig{PackerBuildName: "foo"}
	errs := c.Prepare(testConfigTemplate(t), pc)
	if len(errs) > 0 {
		t.Fatalf("err: %#v", errs)
	}

	if c.OutputDir == "" {
		t.Fatal("should have output dir")
	}
}

func TestOutputConfigPrepare_exists(t *testing.T) {
	td, err := ioutil.TempDir("", "packer")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer os.RemoveAll(td)

	c := new(OutputConfig)
	c.OutputDir = td

	pc := &common.PackerConfig{
		PackerBuildName: "foo",
		PackerForce:     false,
	}
	errs := c.Prepare(testConfigTemplate(t), pc)
	if len(errs) == 0 {
		t.Fatal("should have errors")
	}
}

func TestOutputConfigPrepare_forceExists(t *testing.T) {
	td, err := ioutil.TempDir("", "packer")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer os.RemoveAll(td)

	c := new(OutputConfig)
	c.OutputDir = td

	pc := &common.PackerConfig{
		PackerBuildName: "foo",
		PackerForce:     true,
	}
	errs := c.Prepare(testConfigTemplate(t), pc)
	if len(errs) > 0 {
		t.Fatal("should not have errors")
	}
}
<commit_msg>make builder/parallels/common/output_config_test.go invisible to windows<commit_after>// +build !windows

package common

import (
	"io/ioutil"
	"os"
	"testing"

	"github.com/hashicorp/packer/common"
)

func TestOutputConfigPrepare(t *testing.T) {
	c := new(OutputConfig)
	if c.OutputDir != "" {
		t.Fatalf("what: %s", c.OutputDir)
	}

	pc := &common.PackerConfig{PackerBuildName: "foo"}
	errs := c.Prepare(testConfigTemplate(t), pc)
	if len(errs) > 0 {
		t.Fatalf("err: %#v", errs)
	}

	if c.OutputDir == "" {
		t.Fatal("should have output dir")
	}
}

func TestOutputConfigPrepare_exists(t *testing.T) {
	td, err := ioutil.TempDir("", "packer")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer os.RemoveAll(td)

	c := new(OutputConfig)
	c.OutputDir = td

	pc := &common.PackerConfig{
		PackerBuildName: "foo",
		PackerForce:     false,
	}
	errs := c.Prepare(testConfigTemplate(t), pc)
	if len(errs) == 0 {
		t.Fatal("should have errors")
	}
}

func TestOutputConfigPrepare_forceExists(t *testing.T) {
	td, err := ioutil.TempDir("", "packer")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	defer os.RemoveAll(td)

	c := new(OutputConfig)
	c.OutputDir = td

	pc := &common.PackerConfig{
		PackerBuildName: "foo",
		PackerForce:     true,
	}
	errs := c.Prepare(testConfigTemplate(t), pc)
	if len(errs) > 0 {
		t.Fatal("should not have errors")
	}
}
<|endoftext|>