<commit_before>package horizon

import (
	"net/http"

	"github.com/stellar/horizon/actions"
	"github.com/stellar/horizon/db"
	"github.com/stellar/horizon/log"
	"github.com/zenazn/goji/web"
)

// Action is the "base type" for all actions in horizon.  It provides
// structs that embed it with access to the App struct.
//
// Additionally, this type is a trigger for go-codegen and causes
// the file at Action.tmpl to be instantiated for each struct that
// embeds Action.
type Action struct {
	actions.Base
	App *App
	Log *log.Entry
}

// Prepare sets the action's App field based upon the goji context
func (action *Action) Prepare(c web.C, w http.ResponseWriter, r *http.Request) {
	base := &action.Base
	base.Prepare(c, w, r)
	action.App = action.GojiCtx.Env["app"].(*App)
	action.Log = log.Ctx(action.Ctx)

}

// GetPagingParams modifies the base GetPagingParams method to replace
// cursors that are "now" with the last seen ledger's cursor.
func (action *Action) GetPagingParams() (cursor string, order string, limit int32) {
	if action.Err != nil {
		return
	}

	cursor, order, limit = action.Base.GetPagingParams()

	if cursor == "now" {
		tid := db.TotalOrderId{
			LedgerSequence: action.App.latestLedgerState.HorizonSequence,
		}
		cursor = tid.String()
	}

	return
}

// GetPageQuery is a helper that returns a new db.PageQuery struct initialized
// using the results from a call to GetPagingParams()
func (action *Action) GetPageQuery() db.PageQuery {
	if action.Err != nil {
		return db.PageQuery{}
	}

	r, err := db.NewPageQuery(action.GetPagingParams())

	if err != nil {
		action.Err = err
	}

	return r
}

func (action *Action) ValidateCursorAsDefault() {
	if action.Err != nil {
		return
	}

	if action.GetString(actions.ParamCursor) == "now" {
		return
	}

	action.GetInt64(actions.ParamCursor)
}
<commit_msg>Allow action.Ctx to be nil again by using default logger<commit_after>package horizon

import (
	"net/http"

	"github.com/stellar/horizon/actions"
	"github.com/stellar/horizon/db"
	"github.com/stellar/horizon/log"
	"github.com/zenazn/goji/web"
)

// Action is the "base type" for all actions in horizon.  It provides
// structs that embed it with access to the App struct.
//
// Additionally, this type is a trigger for go-codegen and causes
// the file at Action.tmpl to be instantiated for each struct that
// embeds Action.
type Action struct {
	actions.Base
	App *App
	Log *log.Entry
}

// Prepare sets the action's App field based upon the goji context
func (action *Action) Prepare(c web.C, w http.ResponseWriter, r *http.Request) {
	base := &action.Base
	base.Prepare(c, w, r)
	action.App = action.GojiCtx.Env["app"].(*App)

	if action.Ctx != nil {
		action.Log = log.Ctx(action.Ctx)
	} else {
		action.Log = log.DefaultLogger
	}
}

// GetPagingParams modifies the base GetPagingParams method to replace
// cursors that are "now" with the last seen ledger's cursor.
func (action *Action) GetPagingParams() (cursor string, order string, limit int32) {
	if action.Err != nil {
		return
	}

	cursor, order, limit = action.Base.GetPagingParams()

	if cursor == "now" {
		tid := db.TotalOrderId{
			LedgerSequence: action.App.latestLedgerState.HorizonSequence,
		}
		cursor = tid.String()
	}

	return
}

// GetPageQuery is a helper that returns a new db.PageQuery struct initialized
// using the results from a call to GetPagingParams()
func (action *Action) GetPageQuery() db.PageQuery {
	if action.Err != nil {
		return db.PageQuery{}
	}

	r, err := db.NewPageQuery(action.GetPagingParams())

	if err != nil {
		action.Err = err
	}

	return r
}

func (action *Action) ValidateCursorAsDefault() {
	if action.Err != nil {
		return
	}

	if action.GetString(actions.ParamCursor) == "now" {
		return
	}

	action.GetInt64(actions.ParamCursor)
}
<|endoftext|>


<commit_before>// Copyright 2017, TCN Inc.
// All rights reserved.

// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:

//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of TCN Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.

// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package generator

import (
	"fmt"
	"github.com/Sirupsen/logrus"
	"github.com/xwb1989/sqlparser"
	"strings"
)

type QueryArg struct {
	Name         string      // name in the map,
	Value        interface{} // generic value of the argument. If is a field, this will be empty
	IsFieldValue bool        // Whether this refers to a field passed in
	Field        TypeDesc    // if IsFieldValue is true, this will describe the Field
}

type KeyRangeDesc struct {
	Start []QueryArg
	End   []QueryArg
	Kind  string // a string of of a spanner.KeyRangeKind (ClosedOpen, ClosedClosed ex.)
}

type SpannerHelper struct {
	RawQuery        string
	Query           string
	ParsedQuery     sqlparser.Statement
	TableName       string
	OptionArguments []string
	IsSelect        bool
	IsUpdate        bool
	IsInsert        bool
	IsDelete        bool
	QueryArgs       []QueryArg
	KeyRangeDesc    *KeyRangeDesc // used for delete queries, will be set if IsDelete is true
	InsertCols      []string      // the column names for insert queries
	Parent          *Method
	ProtoFieldDescs map[string]TypeDesc
}

func (sh *SpannerHelper) String() string {
	if sh != nil {
		return fmt.Sprintf("SpannerHelper\n\tQuery: %s\n\tIsSelect: %t\n\tIsUpdate: %t\n\tIsInsert: %t\n\tIsDelete: %t\n\n",
			sh.Query, sh.IsSelect, sh.IsUpdate, sh.IsInsert, sh.IsDelete)
	}
	return "<nil>"
}

func NewSpannerHelper(p *Method) (*SpannerHelper, error) {
	// get the query, and parse it
	opts := p.GetMethodOption()
	if opts == nil {
		return nil, fmt.Errorf("no options found on proto method")
	}
	args := opts.GetArguments()
	query := opts.GetQuery()
	logrus.Debugf("query: %#v", query)
	pquery, err := sqlparser.Parse(query)
	if err != nil {
		return nil, fmt.Errorf("parsing error in spanner_helper: %s", err)
	}
	// get the fields descriptions to construct query args
	input := p.GetInputTypeStruct()
	fieldsMap := p.GetTypeDescForFieldsInStructSnakeCase(input)

	sh := &SpannerHelper{
		RawQuery:        query,
		ParsedQuery:     pquery,
		OptionArguments: args,
		Parent:          p,
		ProtoFieldDescs: fieldsMap,
	}
	err = sh.Parse()
	if err != nil {
		return nil, err
	}
	return sh, nil
}

func (sh *SpannerHelper) Parse() error {
	// parse our query
	switch pq := sh.ParsedQuery.(type) {
	case *sqlparser.Select:
		return sh.ParseSelect(pq)
	case *sqlparser.Insert:
		return sh.ParseInsert(pq)
	case *sqlparser.Delete:
		return sh.ParseDelete(pq)
	case *sqlparser.Update:
		return sh.ParseUpdate(pq)
	default:
		return fmt.Errorf("not a query we can parse")
	}
}

func (sh *SpannerHelper) InsertColsAsString() string {
	return fmt.Sprintf("%#v", sh.InsertCols)
}

func (sh *SpannerHelper) PopulateArgSlice(slice []interface{}) ([]QueryArg) {
	qas := make([]QueryArg, len(slice))
	for i, arg := range slice {
		var qa QueryArg
		if ap, ok := arg.(PassedInArgPos); ok {
			index := int(ap)
			argName := sh.OptionArguments[index]
			qa = QueryArg{
				IsFieldValue: true,
				Field:        sh.ProtoFieldDescs[argName],
			}
		} else {
			qa = QueryArg{
				Value:        fmt.Sprintf("%#v", arg),
				IsFieldValue: false,
			}
		}
		qas[i] = qa
	}
	return qas
}

func (sh *SpannerHelper) ParseInsert(pq *sqlparser.Insert) error {
	sh.IsInsert = true
	cols, err := extractInsertColumns(pq)
	if err != nil {
		return err
	}
	table, err := extractIUDTableName(pq)
	if err != nil {
		return err
	}
	pas, err := prepareInsertValues(pq)
	if err != nil {
		return err
	}
	qas := sh.PopulateArgSlice(pas.args)
	if err != nil {
		return err
	}
	sh.QueryArgs = qas
	sh.InsertCols = cols
	sh.TableName = table
	return nil
}
func (sh *SpannerHelper) ParseSelect(pq *sqlparser.Select) error {
	sh.IsSelect = true
	spl := strings.Split(sh.RawQuery, "?")
	var updatedQuery string

	if len(sh.OptionArguments) != len(spl)-1 {
		errStr := "err parsing spanner query: not correct number of option arguments"
		errStr += " for method: %s of service: %s  want: %d have: %d"
		return fmt.Errorf(errStr, sh.Parent.GetName(), sh.Parent.Service.GetName(), len(spl)-1, len(sh.OptionArguments))
	}
	for i := 0; i < len(spl)-1; i++ {
		name := fmt.Sprintf("@%d", i)
		field := sh.ProtoFieldDescs[sh.OptionArguments[i]]
		qa := QueryArg{
			Name:         name,
			IsFieldValue: true,
			Field:        field,
		}
		sh.QueryArgs = append(sh.QueryArgs, qa)
		updatedQuery += (spl[i] + name)
	}
	updatedQuery += spl[len(spl)-1]
	sh.Query = updatedQuery
	return nil
}
func (sh *SpannerHelper) ParseDelete(pq *sqlparser.Delete) error {
	sh.IsDelete = true
	table, err := extractIUDTableName(pq)
	if err != nil {
		return err
	}
	mkr, err := extractSpannerKeyFromDelete(pq)
	if err != nil {
		return err
	}
	start := sh.PopulateArgSlice(mkr.Start.args)
	end := sh.PopulateArgSlice(mkr.End.args)
	low := mkr.LowerOpen
	up := mkr.UpperOpen

	var kind string

	if low && up {
		kind = "spanner.OpenOpen"
	} else if low && !up {
		kind = "spanner.OpenClosed"
	} else if !low && up {
		kind = "spanner.ClosedOpen"
	} else {
		kind = "spanner.ClosedClosed"
	}
	sh.KeyRangeDesc = &KeyRangeDesc{
		Start: start,
		End:   end,
		Kind:  kind,
	}
	sh.TableName = table
	return nil
}

func (sh *SpannerHelper) ParseUpdate(pq *sqlparser.Update) error {
	sh.IsUpdate = true
	table, err := extractIUDTableName(pq)
	if err != nil {
		return err
	}
	pam, err := extractUpdateClause(pq)
	if err != nil {
		return err
	}
	for key, arg := range pam.args {
		var qa QueryArg
		if ap, ok := arg.(PassedInArgPos); ok {
			index := int(ap)
			argName := sh.OptionArguments[index]
			qa = QueryArg{
				Name:         key,
				IsFieldValue: true,
				Field:        sh.ProtoFieldDescs[argName],
			}
		} else {
			qa = QueryArg{
				Name:         key,
				Value:        fmt.Sprintf("%#v", arg),
				IsFieldValue: false,
			}
		}
		sh.QueryArgs = append(sh.QueryArgs, qa)
	}
	sh.TableName = table
	return nil
}
<commit_msg>use @string for string key params<commit_after>// Copyright 2017, TCN Inc.
// All rights reserved.

// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:

//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of TCN Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.

// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package generator

import (
	"fmt"
	"github.com/Sirupsen/logrus"
	"github.com/xwb1989/sqlparser"
	"strings"
)

type QueryArg struct {
	Name         string      // name in the map,
	Value        interface{} // generic value of the argument. If is a field, this will be empty
	IsFieldValue bool        // Whether this refers to a field passed in
	Field        TypeDesc    // if IsFieldValue is true, this will describe the Field
}

type KeyRangeDesc struct {
	Start []QueryArg
	End   []QueryArg
	Kind  string // a string of of a spanner.KeyRangeKind (ClosedOpen, ClosedClosed ex.)
}

type SpannerHelper struct {
	RawQuery        string
	Query           string
	ParsedQuery     sqlparser.Statement
	TableName       string
	OptionArguments []string
	IsSelect        bool
	IsUpdate        bool
	IsInsert        bool
	IsDelete        bool
	QueryArgs       []QueryArg
	KeyRangeDesc    *KeyRangeDesc // used for delete queries, will be set if IsDelete is true
	InsertCols      []string      // the column names for insert queries
	Parent          *Method
	ProtoFieldDescs map[string]TypeDesc
}

func (sh *SpannerHelper) String() string {
	if sh != nil {
		return fmt.Sprintf("SpannerHelper\n\tQuery: %s\n\tIsSelect: %t\n\tIsUpdate: %t\n\tIsInsert: %t\n\tIsDelete: %t\n\n",
			sh.Query, sh.IsSelect, sh.IsUpdate, sh.IsInsert, sh.IsDelete)
	}
	return "<nil>"
}

func NewSpannerHelper(p *Method) (*SpannerHelper, error) {
	// get the query, and parse it
	opts := p.GetMethodOption()
	if opts == nil {
		return nil, fmt.Errorf("no options found on proto method")
	}
	args := opts.GetArguments()
	query := opts.GetQuery()
	logrus.Debugf("query: %#v", query)
	pquery, err := sqlparser.Parse(query)
	if err != nil {
		return nil, fmt.Errorf("parsing error in spanner_helper: %s", err)
	}
	// get the fields descriptions to construct query args
	input := p.GetInputTypeStruct()
	fieldsMap := p.GetTypeDescForFieldsInStructSnakeCase(input)

	sh := &SpannerHelper{
		RawQuery:        query,
		ParsedQuery:     pquery,
		OptionArguments: args,
		Parent:          p,
		ProtoFieldDescs: fieldsMap,
	}
	err = sh.Parse()
	if err != nil {
		return nil, err
	}
	return sh, nil
}

func (sh *SpannerHelper) Parse() error {
	// parse our query
	switch pq := sh.ParsedQuery.(type) {
	case *sqlparser.Select:
		return sh.ParseSelect(pq)
	case *sqlparser.Insert:
		return sh.ParseInsert(pq)
	case *sqlparser.Delete:
		return sh.ParseDelete(pq)
	case *sqlparser.Update:
		return sh.ParseUpdate(pq)
	default:
		return fmt.Errorf("not a query we can parse")
	}
}

func (sh *SpannerHelper) InsertColsAsString() string {
	return fmt.Sprintf("%#v", sh.InsertCols)
}

func (sh *SpannerHelper) PopulateArgSlice(slice []interface{}) ([]QueryArg) {
	qas := make([]QueryArg, len(slice))
	for i, arg := range slice {
		var qa QueryArg
		if ap, ok := arg.(PassedInArgPos); ok {
			index := int(ap)
			argName := sh.OptionArguments[index]
			qa = QueryArg{
				IsFieldValue: true,
				Field:        sh.ProtoFieldDescs[argName],
			}
		} else {
			qa = QueryArg{
				Value:        fmt.Sprintf("%#v", arg),
				IsFieldValue: false,
			}
		}
		qas[i] = qa
	}
	return qas
}

func (sh *SpannerHelper) ParseInsert(pq *sqlparser.Insert) error {
	sh.IsInsert = true
	cols, err := extractInsertColumns(pq)
	if err != nil {
		return err
	}
	table, err := extractIUDTableName(pq)
	if err != nil {
		return err
	}
	pas, err := prepareInsertValues(pq)
	if err != nil {
		return err
	}
	qas := sh.PopulateArgSlice(pas.args)
	if err != nil {
		return err
	}
	sh.QueryArgs = qas
	sh.InsertCols = cols
	sh.TableName = table
	return nil
}
func (sh *SpannerHelper) ParseSelect(pq *sqlparser.Select) error {
	sh.IsSelect = true
	spl := strings.Split(sh.RawQuery, "?")
	var updatedQuery string

	if len(sh.OptionArguments) != len(spl)-1 {
		errStr := "err parsing spanner query: not correct number of option arguments"
		errStr += " for method: %s of service: %s  want: %d have: %d"
		return fmt.Errorf(errStr, sh.Parent.GetName(), sh.Parent.Service.GetName(), len(spl)-1, len(sh.OptionArguments))
	}
	for i := 0; i < len(spl)-1; i++ {
		name := fmt.Sprintf(` @string%d`, i)
		index := fmt.Sprintf("string%d", i)
		field := sh.ProtoFieldDescs[sh.OptionArguments[i]]
		qa := QueryArg{
			Name:         index,
			IsFieldValue: true,
			Field:        field,
		}
		sh.QueryArgs = append(sh.QueryArgs, qa)
		updatedQuery += (spl[i] + name)
	}
	updatedQuery += spl[len(spl)-1]
	sh.Query = updatedQuery
	return nil
}
func (sh *SpannerHelper) ParseDelete(pq *sqlparser.Delete) error {
	sh.IsDelete = true
	table, err := extractIUDTableName(pq)
	if err != nil {
		return err
	}
	mkr, err := extractSpannerKeyFromDelete(pq)
	if err != nil {
		return err
	}
	start := sh.PopulateArgSlice(mkr.Start.args)
	end := sh.PopulateArgSlice(mkr.End.args)
	low := mkr.LowerOpen
	up := mkr.UpperOpen

	var kind string

	if low && up {
		kind = "spanner.OpenOpen"
	} else if low && !up {
		kind = "spanner.OpenClosed"
	} else if !low && up {
		kind = "spanner.ClosedOpen"
	} else {
		kind = "spanner.ClosedClosed"
	}
	sh.KeyRangeDesc = &KeyRangeDesc{
		Start: start,
		End:   end,
		Kind:  kind,
	}
	sh.TableName = table
	return nil
}

func (sh *SpannerHelper) ParseUpdate(pq *sqlparser.Update) error {
	sh.IsUpdate = true
	table, err := extractIUDTableName(pq)
	if err != nil {
		return err
	}
	pam, err := extractUpdateClause(pq)
	if err != nil {
		return err
	}
	for key, arg := range pam.args {
		var qa QueryArg
		if ap, ok := arg.(PassedInArgPos); ok {
			index := int(ap)
			argName := sh.OptionArguments[index]
			qa = QueryArg{
				Name:         key,
				IsFieldValue: true,
				Field:        sh.ProtoFieldDescs[argName],
			}
		} else {
			qa = QueryArg{
				Name:         key,
				Value:        fmt.Sprintf("%#v", arg),
				IsFieldValue: false,
			}
		}
		sh.QueryArgs = append(sh.QueryArgs, qa)
	}
	sh.TableName = table
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"github.com/fredhsu/go-eapi"
	"io/ioutil"
	"os"
)

type EosNode struct {
	Hostname      string
	MgmtIp        string
	Username      string
	Password      string
	Ssl           bool
	Reachable     bool
	ConfigCorrect bool
	Uptime        float64
	Version       string
	Config        string
}

type ChanResponse struct {
	response eapi.JsonRpcResponse
	node     EosNode
}

func writeConfigFile(path string, n EosNode, config string) {
	filename := path + n.Hostname + ".eos"
	err := ioutil.WriteFile(filename, []byte(config), 0644)
	if err != nil {
		panic(err)
	}
	fmt.Println("wrote to ", filename)
}

func readSwitches(filename string) []EosNode {
	var switches []EosNode

	file, err := os.Open("switches.json")
	if err != nil {
		panic(err)
	}
	decoder := json.NewDecoder(file)
	err = decoder.Decode(&switches)
	if err != nil {
		panic(err)
	}
	return switches
}

func genSwitches(nodes []EosNode) <-chan EosNode {
	out := make(chan EosNode)
	go func() {
		for _, node := range nodes {
			out <- node
		}
		close(out)
	}()
	return out
}

func buildUrl(node EosNode) string {
	prefix := "http"
	if node.Ssl == true {
		prefix = prefix + "s"
	}
	url := prefix + "://" + node.Username + ":" + node.Password + "@" + node.Hostname + "/command-api"
	return url
}

func getConfigs(in <-chan EosNode) <-chan EosNode {
	out := make(chan EosNode)
	go func() {
		for n := range in {
			cmds := []string{"enable", "show running-config"}
			url := buildUrl(n)
			response := eapi.Call(url, cmds, "text")
			config := response.Result[1]["output"].(string)
			n.Config = config
			out <- n
		}
		close(out)
	}()
	return out
}

func getVersion(in <-chan EosNode) <-chan EosNode {
	out := make(chan EosNode)
	go func() {
		for n := range in {
			cmds := []string{"show version"}
			url := buildUrl(n)
			response := eapi.Call(url, cmds, "json")
			version := response.Result[0]["version"].(string)
			n.Version = version
			out <- n
		}
		close(out)
	}()
	return out
}

func main() {
	// swFilePtr := flag.String("swfile", "switches.json", "A JSON file with switches to fetch")
	// pathPtr := flag.String("path", "./baseconfigs", "a directory to store the configs")
	// flag.Parse() // command-line flag parsing
	// fmt.Println(*swFilePtr)
	// fmt.Println(*pathPtr)
	switches := readSwitches("switches.json")
	// path := "./baseconfigs/"

	fmt.Println("############# Using Pipelines ###################")
	c1 := genSwitches(switches)
	c2 := getConfigs(c1)
	out := getVersion(c2)
	for i := 0; i < len(switches); i++ {
		fmt.Println(<-out)
	}

}
<commit_msg>removing unused struct<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"github.com/fredhsu/go-eapi"
	"io/ioutil"
	"os"
)

type EosNode struct {
	Hostname      string
	MgmtIp        string
	Username      string
	Password      string
	Ssl           bool
	Reachable     bool
	ConfigCorrect bool
	Uptime        float64
	Version       string
	Config        string
}

func writeConfigFile(path string, n EosNode, config string) {
	filename := path + n.Hostname + ".eos"
	err := ioutil.WriteFile(filename, []byte(config), 0644)
	if err != nil {
		panic(err)
	}
	fmt.Println("wrote to ", filename)
}

func readSwitches(filename string) []EosNode {
	var switches []EosNode

	file, err := os.Open("switches.json")
	if err != nil {
		panic(err)
	}
	decoder := json.NewDecoder(file)
	err = decoder.Decode(&switches)
	if err != nil {
		panic(err)
	}
	return switches
}

func genSwitches(nodes []EosNode) <-chan EosNode {
	out := make(chan EosNode)
	go func() {
		for _, node := range nodes {
			out <- node
		}
		close(out)
	}()
	return out
}

func buildUrl(node EosNode) string {
	prefix := "http"
	if node.Ssl == true {
		prefix = prefix + "s"
	}
	url := prefix + "://" + node.Username + ":" + node.Password + "@" + node.Hostname + "/command-api"
	return url
}

func getConfigs(in <-chan EosNode) <-chan EosNode {
	out := make(chan EosNode)
	go func() {
		for n := range in {
			cmds := []string{"enable", "show running-config"}
			url := buildUrl(n)
			response := eapi.Call(url, cmds, "text")
			config := response.Result[1]["output"].(string)
			n.Config = config
			out <- n
		}
		close(out)
	}()
	return out
}

func getVersion(in <-chan EosNode) <-chan EosNode {
	out := make(chan EosNode)
	go func() {
		for n := range in {
			cmds := []string{"show version"}
			url := buildUrl(n)
			response := eapi.Call(url, cmds, "json")
			version := response.Result[0]["version"].(string)
			n.Version = version
			out <- n
		}
		close(out)
	}()
	return out
}

func main() {
	// swFilePtr := flag.String("swfile", "switches.json", "A JSON file with switches to fetch")
	// pathPtr := flag.String("path", "./baseconfigs", "a directory to store the configs")
	// flag.Parse() // command-line flag parsing
	// fmt.Println(*swFilePtr)
	// fmt.Println(*pathPtr)
	switches := readSwitches("switches.json")
	// path := "./baseconfigs/"

	fmt.Println("############# Using Pipelines ###################")
	c1 := genSwitches(switches)
	c2 := getConfigs(c1)
	out := getVersion(c2)
	for i := 0; i < len(switches); i++ {
		fmt.Println(<-out)
	}

}
<|endoftext|>


<commit_before>// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package github

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"reflect"
	"testing"
)

func TestUsersService_ListEmails(t *testing.T) {
	client, mux, _, teardown := setup()
	defer teardown()

	mux.HandleFunc("/user/emails", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		testFormValues(t, r, values{"page": "2"})
		fmt.Fprint(w, `[{
			"email": "user@example.com",
			"verified": false,
			"primary": true
		}]`)
	})

	opt := &ListOptions{Page: 2}
	ctx := context.Background()
	emails, _, err := client.Users.ListEmails(ctx, opt)
	if err != nil {
		t.Errorf("Users.ListEmails returned error: %v", err)
	}

	want := []*UserEmail{{Email: String("user@example.com"), Verified: Bool(false), Primary: Bool(true)}}
	if !reflect.DeepEqual(emails, want) {
		t.Errorf("Users.ListEmails returned %+v, want %+v", emails, want)
	}
}

func TestUsersService_AddEmails(t *testing.T) {
	client, mux, _, teardown := setup()
	defer teardown()

	input := []string{"new@example.com"}

	mux.HandleFunc("/user/emails", func(w http.ResponseWriter, r *http.Request) {
		var v []string
		json.NewDecoder(r.Body).Decode(&v)

		testMethod(t, r, "POST")
		if !reflect.DeepEqual(v, input) {
			t.Errorf("Request body = %+v, want %+v", v, input)
		}

		fmt.Fprint(w, `[{"email":"old@example.com"}, {"email":"new@example.com"}]`)
	})

	ctx := context.Background()
	emails, _, err := client.Users.AddEmails(ctx, input)
	if err != nil {
		t.Errorf("Users.AddEmails returned error: %v", err)
	}

	want := []*UserEmail{
		{Email: String("old@example.com")},
		{Email: String("new@example.com")},
	}
	if !reflect.DeepEqual(emails, want) {
		t.Errorf("Users.AddEmails returned %+v, want %+v", emails, want)
	}
}

func TestUsersService_DeleteEmails(t *testing.T) {
	client, mux, _, teardown := setup()
	defer teardown()

	input := []string{"user@example.com"}

	mux.HandleFunc("/user/emails", func(w http.ResponseWriter, r *http.Request) {
		var v []string
		json.NewDecoder(r.Body).Decode(&v)

		testMethod(t, r, "DELETE")
		if !reflect.DeepEqual(v, input) {
			t.Errorf("Request body = %+v, want %+v", v, input)
		}
	})

	ctx := context.Background()
	_, err := client.Users.DeleteEmails(ctx, input)
	if err != nil {
		t.Errorf("Users.DeleteEmails returned error: %v", err)
	}
}
<commit_msg>Increase users_emails.go code coverage (#1665)<commit_after>// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package github

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"reflect"
	"testing"
	"time"
)

func TestUsersService_ListEmails(t *testing.T) {
	client, mux, _, teardown := setup()
	defer teardown()

	mux.HandleFunc("/user/emails", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		testFormValues(t, r, values{"page": "2"})
		fmt.Fprint(w, `[{
			"email": "user@example.com",
			"verified": false,
			"primary": true
		}]`)
	})

	opt := &ListOptions{Page: 2}
	ctx := context.Background()
	emails, _, err := client.Users.ListEmails(ctx, opt)
	if err != nil {
		t.Errorf("Users.ListEmails returned error: %v", err)
	}

	want := []*UserEmail{{Email: String("user@example.com"), Verified: Bool(false), Primary: Bool(true)}}
	if !reflect.DeepEqual(emails, want) {
		t.Errorf("Users.ListEmails returned %+v, want %+v", emails, want)
	}

	// Test s.client.NewRequest failure
	client.BaseURL.Path = ""
	got, resp, err := client.Users.ListEmails(ctx, nil)
	if got != nil {
		t.Errorf("client.BaseURL.Path='' ListEmails = %#v, want nil", got)
	}
	if resp != nil {
		t.Errorf("client.BaseURL.Path='' ListEmails resp = %#v, want nil", resp)
	}
	if err == nil {
		t.Error("client.BaseURL.Path='' ListEmails err = nil, want error")
	}

	// Test s.client.Do failure
	client.BaseURL.Path = "/api-v3/"
	client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute)
	got, resp, err = client.Users.ListEmails(ctx, nil)
	if got != nil {
		t.Errorf("rate.Reset.Time > now ListEmails = %#v, want nil", got)
	}
	if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want {
		t.Errorf("rate.Reset.Time > now ListEmails resp = %#v, want StatusCode=%v", resp.Response, want)
	}
	if err == nil {
		t.Error("rate.Reset.Time > now ListEmails err = nil, want error")
	}
}

func TestUsersService_AddEmails(t *testing.T) {
	client, mux, _, teardown := setup()
	defer teardown()

	input := []string{"new@example.com"}

	mux.HandleFunc("/user/emails", func(w http.ResponseWriter, r *http.Request) {
		var v []string
		json.NewDecoder(r.Body).Decode(&v)

		testMethod(t, r, "POST")
		if !reflect.DeepEqual(v, input) {
			t.Errorf("Request body = %+v, want %+v", v, input)
		}

		fmt.Fprint(w, `[{"email":"old@example.com"}, {"email":"new@example.com"}]`)
	})

	ctx := context.Background()
	emails, _, err := client.Users.AddEmails(ctx, input)
	if err != nil {
		t.Errorf("Users.AddEmails returned error: %v", err)
	}

	want := []*UserEmail{
		{Email: String("old@example.com")},
		{Email: String("new@example.com")},
	}
	if !reflect.DeepEqual(emails, want) {
		t.Errorf("Users.AddEmails returned %+v, want %+v", emails, want)
	}

	// Test s.client.NewRequest failure
	client.BaseURL.Path = ""
	got, resp, err := client.Users.AddEmails(ctx, input)
	if got != nil {
		t.Errorf("client.BaseURL.Path='' AddEmails = %#v, want nil", got)
	}
	if resp != nil {
		t.Errorf("client.BaseURL.Path='' AddEmails resp = %#v, want nil", resp)
	}
	if err == nil {
		t.Error("client.BaseURL.Path='' AddEmails err = nil, want error")
	}

	// Test s.client.Do failure
	client.BaseURL.Path = "/api-v3/"
	client.rateLimits[0].Reset.Time = time.Now().Add(10 * time.Minute)
	got, resp, err = client.Users.AddEmails(ctx, input)
	if got != nil {
		t.Errorf("rate.Reset.Time > now AddEmails = %#v, want nil", got)
	}
	if want := http.StatusForbidden; resp == nil || resp.Response.StatusCode != want {
		t.Errorf("rate.Reset.Time > now AddEmails resp = %#v, want StatusCode=%v", resp.Response, want)
	}
	if err == nil {
		t.Error("rate.Reset.Time > now AddEmails err = nil, want error")
	}
}

func TestUsersService_DeleteEmails(t *testing.T) {
	client, mux, _, teardown := setup()
	defer teardown()

	input := []string{"user@example.com"}

	mux.HandleFunc("/user/emails", func(w http.ResponseWriter, r *http.Request) {
		var v []string
		json.NewDecoder(r.Body).Decode(&v)

		testMethod(t, r, "DELETE")
		if !reflect.DeepEqual(v, input) {
			t.Errorf("Request body = %+v, want %+v", v, input)
		}
	})

	ctx := context.Background()
	_, err := client.Users.DeleteEmails(ctx, input)
	if err != nil {
		t.Errorf("Users.DeleteEmails returned error: %v", err)
	}

	// Test s.client.NewRequest failure
	client.BaseURL.Path = ""
	resp, err := client.Users.DeleteEmails(ctx, input)
	if resp != nil {
		t.Errorf("client.BaseURL.Path='' DeleteEmails resp = %#v, want nil", resp)
	}
	if err == nil {
		t.Error("client.BaseURL.Path='' DeleteEmails err = nil, want error")
	}
}
<|endoftext|>


<commit_before>package dependency

import (
	"log"
	"math/rand"
	"path"
	"strings"
	"time"

	"github.com/hashicorp/vault/api"
)

var (
	// VaultDefaultLeaseDuration is the default lease duration in seconds.
	VaultDefaultLeaseDuration = 5 * time.Minute
)

// Secret is the structure returned for every secret within Vault.
type Secret struct {
	// The request ID that generated this response
	RequestID string

	LeaseID       string
	LeaseDuration int
	Renewable     bool

	// Data is the actual contents of the secret. The format of the data
	// is arbitrary and up to the secret backend.
	Data map[string]interface{}

	// Warnings contains any warnings related to the operation. These
	// are not issues that caused the command to fail, but that the
	// client should be aware of.
	Warnings []string

	// Auth, if non-nil, means that there was authentication information
	// attached to this response.
	Auth *SecretAuth

	// WrapInfo, if non-nil, means that the initial response was wrapped in the
	// cubbyhole of the given token (which has a TTL of the given number of
	// seconds)
	WrapInfo *SecretWrapInfo
}

// SecretAuth is the structure containing auth information if we have it.
type SecretAuth struct {
	ClientToken string
	Accessor    string
	Policies    []string
	Metadata    map[string]string

	LeaseDuration int
	Renewable     bool
}

// SecretWrapInfo contains wrapping information if we have it. If what is
// contained is an authentication token, the accessor for the token will be
// available in WrappedAccessor.
type SecretWrapInfo struct {
	Token           string
	TTL             int
	CreationTime    time.Time
	WrappedAccessor string
}

// vaultRenewDuration accepts a secret and returns the recommended amount of
// time to sleep.
func vaultRenewDuration(s *Secret) time.Duration {
	// Handle whether this is an auth or a regular secret.
	base := s.LeaseDuration
	if s.Auth != nil && s.Auth.LeaseDuration > 0 {
		base = s.Auth.LeaseDuration
	}

	// Ensure we have a lease duration, since sometimes this can be zero.
	if base <= 0 {
		base = int(VaultDefaultLeaseDuration.Seconds())
	}

	// Convert to float seconds.
	sleep := float64(time.Duration(base) * time.Second)

	if vaultSecretRenewable(s) {
		// Renew at 1/3 the remaining lease. This will give us an opportunity to retry
		// at least one more time should the first renewal fail.
		sleep = sleep / 3.0

		// Use a randomness so many clients do not hit Vault simultaneously.
		sleep = sleep * (rand.Float64() + 1) / 2.0
	} else {
		// For non-renewable leases set the renew duration to use much of the secret
		// lease as possible. Use a stagger over 85%-95% of the lease duration so that
		// many clients do not hit Vault simultaneously.
		sleep = sleep * (.85 + rand.Float64()*0.1)
	}

	return time.Duration(sleep)
}

// printVaultWarnings prints warnings for a given dependency.
func printVaultWarnings(d Dependency, warnings []string) {
	for _, w := range warnings {
		log.Printf("[WARN] %s: %s", d, w)
	}
}

// vaultSecretRenewable determines if the given secret is renewable.
func vaultSecretRenewable(s *Secret) bool {
	if s.Auth != nil {
		return s.Auth.Renewable
	}
	return s.Renewable
}

// transformSecret transforms an api secret into our secret. This does not deep
// copy underlying deep data structures, so it's not safe to modify the vault
// secret as that may modify the data in the transformed secret.
func transformSecret(theirs *api.Secret) *Secret {
	var ours Secret
	updateSecret(&ours, theirs)
	return &ours
}

// updateSecret updates our secret with the new data from the api, careful to
// not overwrite missing data. Renewals don't include the original secret, and
// we don't want to delete that data accidentally.
func updateSecret(ours *Secret, theirs *api.Secret) {
	if theirs.RequestID != "" {
		ours.RequestID = theirs.RequestID
	}

	if theirs.LeaseID != "" {
		ours.LeaseID = theirs.LeaseID
	}

	if theirs.LeaseDuration != 0 {
		ours.LeaseDuration = theirs.LeaseDuration
	}

	if theirs.Renewable {
		ours.Renewable = theirs.Renewable
	}

	if len(theirs.Data) != 0 {
		ours.Data = theirs.Data
	}

	if len(theirs.Warnings) != 0 {
		ours.Warnings = theirs.Warnings
	}

	if theirs.Auth != nil {
		if ours.Auth == nil {
			ours.Auth = &SecretAuth{}
		}

		if theirs.Auth.ClientToken != "" {
			ours.Auth.ClientToken = theirs.Auth.ClientToken
		}

		if theirs.Auth.Accessor != "" {
			ours.Auth.Accessor = theirs.Auth.Accessor
		}

		if len(theirs.Auth.Policies) != 0 {
			ours.Auth.Policies = theirs.Auth.Policies
		}

		if len(theirs.Auth.Metadata) != 0 {
			ours.Auth.Metadata = theirs.Auth.Metadata
		}

		if theirs.Auth.LeaseDuration != 0 {
			ours.Auth.LeaseDuration = theirs.Auth.LeaseDuration
		}

		if theirs.Auth.Renewable {
			ours.Auth.Renewable = theirs.Auth.Renewable
		}
	}

	if theirs.WrapInfo != nil {
		if ours.WrapInfo == nil {
			ours.WrapInfo = &SecretWrapInfo{}
		}

		if theirs.WrapInfo.Token != "" {
			ours.WrapInfo.Token = theirs.WrapInfo.Token
		}

		if theirs.WrapInfo.TTL != 0 {
			ours.WrapInfo.TTL = theirs.WrapInfo.TTL
		}

		if !theirs.WrapInfo.CreationTime.IsZero() {
			ours.WrapInfo.CreationTime = theirs.WrapInfo.CreationTime
		}

		if theirs.WrapInfo.WrappedAccessor != "" {
			ours.WrapInfo.WrappedAccessor = theirs.WrapInfo.WrappedAccessor
		}
	}
}

func isKVv2(client *api.Client, path string) (string, bool, error) {
	// We don't want to use a wrapping call here so save any custom value and
	// restore after
	currentWrappingLookupFunc := client.CurrentWrappingLookupFunc()
	client.SetWrappingLookupFunc(nil)
	defer client.SetWrappingLookupFunc(currentWrappingLookupFunc)
	currentOutputCurlString := client.OutputCurlString()
	client.SetOutputCurlString(false)
	defer client.SetOutputCurlString(currentOutputCurlString)

	r := client.NewRequest("GET", "/v1/sys/internal/ui/mounts/"+path)
	resp, err := client.RawRequest(r)
	if resp != nil {
		defer resp.Body.Close()
	}
	if err != nil {
		// If we get a 404 we are using an older version of vault, default to
		// version 1
		if resp != nil && resp.StatusCode == 404 {
			return "", false, nil
		}

		return "", false, err
	}

	secret, err := api.ParseSecret(resp.Body)
	if err != nil {
		return "", false, err
	}
	var mountPath string
	if mountPathRaw, ok := secret.Data["path"]; ok {
		mountPath = mountPathRaw.(string)
	}
	var mountType string
	if mountTypeRaw, ok := secret.Data["type"]; ok {
		mountType = mountTypeRaw.(string)
	}
	options := secret.Data["options"]
	if options == nil {
		return mountPath, false, nil
	}
	versionRaw := options.(map[string]interface{})["version"]
	if versionRaw == nil {
		return mountPath, false, nil
	}
	version := versionRaw.(string)
	switch version {
	case "", "1":
		return mountPath, false, nil
	case "2":
		return mountPath, mountType == "kv", nil
	}

	return mountPath, false, nil
}

func addPrefixToVKVPath(p, mountPath, apiPrefix string) string {
	switch {
	case p == mountPath, p == strings.TrimSuffix(mountPath, "/"):
		return path.Join(mountPath, apiPrefix)
	default:
		p = strings.TrimPrefix(p, mountPath)
		return path.Join(mountPath, apiPrefix, p)
	}
}
<commit_msg>Fix the wording in a comment<commit_after>package dependency

import (
	"log"
	"math/rand"
	"path"
	"strings"
	"time"

	"github.com/hashicorp/vault/api"
)

var (
	// VaultDefaultLeaseDuration is the default lease duration in seconds.
	VaultDefaultLeaseDuration = 5 * time.Minute
)

// Secret is the structure returned for every secret within Vault.
type Secret struct {
	// The request ID that generated this response
	RequestID string

	LeaseID       string
	LeaseDuration int
	Renewable     bool

	// Data is the actual contents of the secret. The format of the data
	// is arbitrary and up to the secret backend.
	Data map[string]interface{}

	// Warnings contains any warnings related to the operation. These
	// are not issues that caused the command to fail, but that the
	// client should be aware of.
	Warnings []string

	// Auth, if non-nil, means that there was authentication information
	// attached to this response.
	Auth *SecretAuth

	// WrapInfo, if non-nil, means that the initial response was wrapped in the
	// cubbyhole of the given token (which has a TTL of the given number of
	// seconds)
	WrapInfo *SecretWrapInfo
}

// SecretAuth is the structure containing auth information if we have it.
type SecretAuth struct {
	ClientToken string
	Accessor    string
	Policies    []string
	Metadata    map[string]string

	LeaseDuration int
	Renewable     bool
}

// SecretWrapInfo contains wrapping information if we have it. If what is
// contained is an authentication token, the accessor for the token will be
// available in WrappedAccessor.
type SecretWrapInfo struct {
	Token           string
	TTL             int
	CreationTime    time.Time
	WrappedAccessor string
}

// vaultRenewDuration accepts a secret and returns the recommended amount of
// time to sleep.
func vaultRenewDuration(s *Secret) time.Duration {
	// Handle whether this is an auth or a regular secret.
	base := s.LeaseDuration
	if s.Auth != nil && s.Auth.LeaseDuration > 0 {
		base = s.Auth.LeaseDuration
	}

	// Ensure we have a lease duration, since sometimes this can be zero.
	if base <= 0 {
		base = int(VaultDefaultLeaseDuration.Seconds())
	}

	// Convert to float seconds.
	sleep := float64(time.Duration(base) * time.Second)

	if vaultSecretRenewable(s) {
		// Renew at 1/3 the remaining lease. This will give us an opportunity to retry
		// at least one more time should the first renewal fail.
		sleep = sleep / 3.0

		// Use some randomness so many clients do not hit Vault simultaneously.
		sleep = sleep * (rand.Float64() + 1) / 2.0
	} else {
		// For non-renewable leases set the renew duration to use much of the secret
		// lease as possible. Use a stagger over 85%-95% of the lease duration so that
		// many clients do not hit Vault simultaneously.
		sleep = sleep * (.85 + rand.Float64()*0.1)
	}

	return time.Duration(sleep)
}

// printVaultWarnings prints warnings for a given dependency.
func printVaultWarnings(d Dependency, warnings []string) {
	for _, w := range warnings {
		log.Printf("[WARN] %s: %s", d, w)
	}
}

// vaultSecretRenewable determines if the given secret is renewable.
func vaultSecretRenewable(s *Secret) bool {
	if s.Auth != nil {
		return s.Auth.Renewable
	}
	return s.Renewable
}

// transformSecret transforms an api secret into our secret. This does not deep
// copy underlying deep data structures, so it's not safe to modify the vault
// secret as that may modify the data in the transformed secret.
func transformSecret(theirs *api.Secret) *Secret {
	var ours Secret
	updateSecret(&ours, theirs)
	return &ours
}

// updateSecret updates our secret with the new data from the api, careful to
// not overwrite missing data. Renewals don't include the original secret, and
// we don't want to delete that data accidentally.
func updateSecret(ours *Secret, theirs *api.Secret) {
	if theirs.RequestID != "" {
		ours.RequestID = theirs.RequestID
	}

	if theirs.LeaseID != "" {
		ours.LeaseID = theirs.LeaseID
	}

	if theirs.LeaseDuration != 0 {
		ours.LeaseDuration = theirs.LeaseDuration
	}

	if theirs.Renewable {
		ours.Renewable = theirs.Renewable
	}

	if len(theirs.Data) != 0 {
		ours.Data = theirs.Data
	}

	if len(theirs.Warnings) != 0 {
		ours.Warnings = theirs.Warnings
	}

	if theirs.Auth != nil {
		if ours.Auth == nil {
			ours.Auth = &SecretAuth{}
		}

		if theirs.Auth.ClientToken != "" {
			ours.Auth.ClientToken = theirs.Auth.ClientToken
		}

		if theirs.Auth.Accessor != "" {
			ours.Auth.Accessor = theirs.Auth.Accessor
		}

		if len(theirs.Auth.Policies) != 0 {
			ours.Auth.Policies = theirs.Auth.Policies
		}

		if len(theirs.Auth.Metadata) != 0 {
			ours.Auth.Metadata = theirs.Auth.Metadata
		}

		if theirs.Auth.LeaseDuration != 0 {
			ours.Auth.LeaseDuration = theirs.Auth.LeaseDuration
		}

		if theirs.Auth.Renewable {
			ours.Auth.Renewable = theirs.Auth.Renewable
		}
	}

	if theirs.WrapInfo != nil {
		if ours.WrapInfo == nil {
			ours.WrapInfo = &SecretWrapInfo{}
		}

		if theirs.WrapInfo.Token != "" {
			ours.WrapInfo.Token = theirs.WrapInfo.Token
		}

		if theirs.WrapInfo.TTL != 0 {
			ours.WrapInfo.TTL = theirs.WrapInfo.TTL
		}

		if !theirs.WrapInfo.CreationTime.IsZero() {
			ours.WrapInfo.CreationTime = theirs.WrapInfo.CreationTime
		}

		if theirs.WrapInfo.WrappedAccessor != "" {
			ours.WrapInfo.WrappedAccessor = theirs.WrapInfo.WrappedAccessor
		}
	}
}

func isKVv2(client *api.Client, path string) (string, bool, error) {
	// We don't want to use a wrapping call here so save any custom value and
	// restore after
	currentWrappingLookupFunc := client.CurrentWrappingLookupFunc()
	client.SetWrappingLookupFunc(nil)
	defer client.SetWrappingLookupFunc(currentWrappingLookupFunc)
	currentOutputCurlString := client.OutputCurlString()
	client.SetOutputCurlString(false)
	defer client.SetOutputCurlString(currentOutputCurlString)

	r := client.NewRequest("GET", "/v1/sys/internal/ui/mounts/"+path)
	resp, err := client.RawRequest(r)
	if resp != nil {
		defer resp.Body.Close()
	}
	if err != nil {
		// If we get a 404 we are using an older version of vault, default to
		// version 1
		if resp != nil && resp.StatusCode == 404 {
			return "", false, nil
		}

		return "", false, err
	}

	secret, err := api.ParseSecret(resp.Body)
	if err != nil {
		return "", false, err
	}
	var mountPath string
	if mountPathRaw, ok := secret.Data["path"]; ok {
		mountPath = mountPathRaw.(string)
	}
	var mountType string
	if mountTypeRaw, ok := secret.Data["type"]; ok {
		mountType = mountTypeRaw.(string)
	}
	options := secret.Data["options"]
	if options == nil {
		return mountPath, false, nil
	}
	versionRaw := options.(map[string]interface{})["version"]
	if versionRaw == nil {
		return mountPath, false, nil
	}
	version := versionRaw.(string)
	switch version {
	case "", "1":
		return mountPath, false, nil
	case "2":
		return mountPath, mountType == "kv", nil
	}

	return mountPath, false, nil
}

func addPrefixToVKVPath(p, mountPath, apiPrefix string) string {
	switch {
	case p == mountPath, p == strings.TrimSuffix(mountPath, "/"):
		return path.Join(mountPath, apiPrefix)
	default:
		p = strings.TrimPrefix(p, mountPath)
		return path.Join(mountPath, apiPrefix, p)
	}
}
<|endoftext|>


<commit_before>package deploy_docus

import (
	"fmt"
	"strings"
)

type Repository struct {
	Id          int64
	Origin      string
	Destination string

	Rsa *Rsa
}

func (r *Repository) Name() string {
	suffix := "git@github.com:"
	affix := ".git"
	name := r.Origin[len(suffix) : len(r.Origin)-len(affix)]

	return strings.Replace(name, "/", "_", 1)
}

func (r *Repository) LocalPath() string {
	return fmt.Sprintf("/tmp/%s", r.Name())
}

func BuildRepository(id int64, origin string, destination string, rsa_key []byte) *Repository {
	repository := &Repository{
		Id:          id,
		Origin:      origin,
		Destination: destination,
	}
	repository.Rsa = NewRsa(repository, rsa_key)
	return repository
}

func CreateRepository(origin string, destination string, rsa_key []byte) (*Repository, error) {
	db, err := GetDbConnection()
	if err != nil {
		return nil, err
	}

	var id int64
	err = db.QueryRow(`INSERT INTO repositories (origin, destination, rsa_key) VALUES ($1, $2, $3) RETURNING id;`, origin, destination, rsa_key).Scan(&id)
	if err != nil {
		return nil, err
	}

	return BuildRepository(id, origin, destination, rsa_key), nil
}

func FindRepository(id int64) (*Repository, error) {
	db, err := GetDbConnection()
	if err != nil {
		return nil, err
	}

	var origin string
	var destination string
	var rsa_key []byte
	err = db.QueryRow("SELECT origin, destination, rsa_key FROM repositories WHERE id = $1", id).Scan(&origin, &destination, &rsa_key)
	if err != nil {
		return nil, err
	}

	return BuildRepository(id, origin, destination, rsa_key), nil
}
<commit_msg>don't forget to close the connection<commit_after>package deploy_docus

import (
	"fmt"
	"strings"
)

type Repository struct {
	Id          int64
	Origin      string
	Destination string

	Rsa *Rsa
}

func (r *Repository) Name() string {
	suffix := "git@github.com:"
	affix := ".git"
	name := r.Origin[len(suffix) : len(r.Origin)-len(affix)]

	return strings.Replace(name, "/", "_", 1)
}

func (r *Repository) LocalPath() string {
	return fmt.Sprintf("/tmp/%s", r.Name())
}

func BuildRepository(id int64, origin string, destination string, rsa_key []byte) *Repository {
	repository := &Repository{
		Id:          id,
		Origin:      origin,
		Destination: destination,
	}
	repository.Rsa = NewRsa(repository, rsa_key)
	return repository
}

func CreateRepository(origin string, destination string, rsa_key []byte) (*Repository, error) {
	db, err := GetDbConnection()
	defer db.Close()
	if err != nil {
		return nil, err
	}

	var id int64
	err = db.QueryRow(`INSERT INTO repositories (origin, destination, rsa_key) VALUES ($1, $2, $3) RETURNING id;`, origin, destination, rsa_key).Scan(&id)
	if err != nil {
		return nil, err
	}

	return BuildRepository(id, origin, destination, rsa_key), nil
}

func FindRepository(id int64) (*Repository, error) {
	db, err := GetDbConnection()
	defer db.Close()
	if err != nil {
		return nil, err
	}

	var origin string
	var destination string
	var rsa_key []byte
	err = db.QueryRow("SELECT origin, destination, rsa_key FROM repositories WHERE id = $1", id).Scan(&origin, &destination, &rsa_key)
	if err != nil {
		return nil, err
	}

	return BuildRepository(id, origin, destination, rsa_key), nil
}
<|endoftext|>


<commit_before>// Copyright 2019 Google LLC
//
// 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
//
//     https://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 productsearch

import (
	"bytes"
	"strings"
	"testing"

	"github.com/GoogleCloudPlatform/golang-samples/internal/testutil"
)

func TestDeleteProductSet(t *testing.T) {
	tc := testutil.SystemTest(t)

	const location = "us-west1"
	const productSetDisplayName = "fake_product_set_display_name_for_testing"
	const productSetID = "fake_product_set_id_for_testing"

	var buf bytes.Buffer

	// Ensure re-used resource names don't exist prior to test start.
	if err := getProductSet(&buf, tc.ProjectID, location, productSetID); err == nil {
		deleteProductSet(&buf, tc.ProjectID, location, productSetID)
	}
	buf.Reset()

	// Create a fake product set.
	if err := createProductSet(&buf, tc.ProjectID, location, productSetID, productSetDisplayName); err != nil {
		t.Fatalf("createProductSet: %v", err)
	}

	// Confirm the product set exists.
	if err := listProductSets(&buf, tc.ProjectID, location); err != nil {
		t.Fatalf("listProductSets: %v", err)
	}
	if got := buf.String(); !strings.Contains(got, productSetID) {
		t.Errorf("Product set ID %s does not exist", productSetID)
	}

	// Delete the product set.
	deleteProductSet(&buf, tc.ProjectID, location, productSetID)

	// Confirm the product set has been deleted.
	buf.Reset()
	if err := listProductSets(&buf, tc.ProjectID, location); err != nil {
		t.Fatalf("listProductSets: %v", err)
	}
	if got := buf.String(); strings.Contains(got, productSetID) {
		t.Errorf("Product set ID %s still exists", productSetID)
	}
}
<commit_msg>vision/product_search: retry TestDeleteProductSet (#861)<commit_after>// Copyright 2019 Google LLC
//
// 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
//
//     https://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 productsearch

import (
	"bytes"
	"strings"
	"testing"
	"time"

	"github.com/GoogleCloudPlatform/golang-samples/internal/testutil"
)

func TestDeleteProductSet(t *testing.T) {
	tc := testutil.SystemTest(t)

	const location = "us-west1"
	const productSetDisplayName = "fake_product_set_display_name_for_testing"
	const productSetID = "fake_product_set_id_for_testing"

	var buf bytes.Buffer

	// Ensure re-used resource names don't exist prior to test start.
	if err := getProductSet(&buf, tc.ProjectID, location, productSetID); err == nil {
		deleteProductSet(&buf, tc.ProjectID, location, productSetID)
	}
	buf.Reset()

	// Create a fake product set.
	if err := createProductSet(&buf, tc.ProjectID, location, productSetID, productSetDisplayName); err != nil {
		t.Fatalf("createProductSet: %v", err)
	}

	// Confirm the product set exists.
	if err := listProductSets(&buf, tc.ProjectID, location); err != nil {
		t.Fatalf("listProductSets: %v", err)
	}
	if got := buf.String(); !strings.Contains(got, productSetID) {
		t.Errorf("Product set ID %s does not exist", productSetID)
	}

	// Delete the product set.
	testutil.Retry(t, 10, 1*time.Second, func(r *testutil.R) {
		if err := deleteProductSet(&buf, tc.ProjectID, location, productSetID); err != nil {
			r.Errorf("deleteProductSet: %v", err)
		}

		// Confirm the product set has been deleted.
		buf.Reset()
		if err := listProductSets(&buf, tc.ProjectID, location); err != nil {
			r.Errorf("listProductSets: %v", err)
			return
		}
		if got := buf.String(); strings.Contains(got, productSetID) {
			r.Errorf("Product set ID %s still exists", productSetID)
		}
	})
}
<|endoftext|>


<commit_before>package chat

import (
	"io"

	"github.com/agl/ed25519"
	"github.com/keybase/client/go/chat/signencrypt"
	"github.com/keybase/client/go/libkb"
)

type Encrypter interface {
	// EncryptedLen returns the number of bytes that the ciphertext of
	// size plaintext bytes will be.
	EncryptedLen(size int) int

	// Encrypt takes a plaintext reader and returns a ciphertext reader.
	Encrypt(plaintext io.Reader) (ciphertext io.Reader)

	// EncryptKey returns the ephemeral key that was used during Encrypt.
	EncryptKey() []byte

	// VerifyKey returns the public portion of the signing key that
	// can be used for signature verification.
	VerifyKey() []byte
}

type Decrypter interface {
	// Decrypt takes a ciphertext reader, encryption and verify keys.
	// It returns a plaintext reader.
	Decrypt(ciphertext io.Reader, encKey, verifyKey []byte) (plaintext io.Reader)
}

var nonce = &[signencrypt.NonceSize]byte{
	0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20,
	0x30, 0x30, 0x30, 0x30, 0x40, 0x40, 0x40, 0x40,
}

type SignEncrypter struct {
	encKey    signencrypt.SecretboxKey
	signKey   signencrypt.SignKey
	verifyKey signencrypt.VerifyKey
}

func NewSignEncrypter() (*SignEncrypter, error) {
	enc, err := libkb.GenerateNaclDHKeyPair()
	if err != nil {
		return nil, err
	}
	sign, err := libkb.GenerateNaclSigningKeyPair()
	if err != nil {
		return nil, err
	}

	var encKey [signencrypt.SecretboxKeySize]byte
	copy(encKey[:], (*enc.Private)[:])
	var signKey [ed25519.PrivateKeySize]byte
	copy(signKey[:], (*sign.Private)[:])
	var verifyKey [ed25519.PublicKeySize]byte
	copy(verifyKey[:], sign.Public[:])

	res := SignEncrypter{
		encKey:    &encKey,
		signKey:   &signKey,
		verifyKey: &verifyKey,
	}

	return &res, nil
}

func (s *SignEncrypter) EncryptedLen(size int) int {
	return signencrypt.GetSealedSize(size)
}

func (s *SignEncrypter) Encrypt(r io.Reader) io.Reader {
	return signencrypt.NewEncodingReader(s.encKey, s.signKey, nonce, r)
}

func (s *SignEncrypter) EncryptKey() []byte {
	return []byte((*s.encKey)[:])
}

func (s *SignEncrypter) VerifyKey() []byte {
	return []byte((*s.verifyKey)[:])
}

type SignDecrypter struct{}

func NewSignDecrypter() *SignDecrypter {
	return &SignDecrypter{}
}

func (s *SignDecrypter) Decrypt(r io.Reader, encKey, verifyKey []byte) io.Reader {
	var xencKey [signencrypt.SecretboxKeySize]byte
	copy(xencKey[:], encKey)
	var xverifyKey [ed25519.PublicKeySize]byte
	copy(xverifyKey[:], verifyKey)
	return signencrypt.NewDecodingReader(&xencKey, &xverifyKey, nonce, r)
}
<commit_msg>Fix encKey<commit_after>package chat

import (
	"crypto/rand"
	"errors"
	"io"

	"github.com/agl/ed25519"
	"github.com/keybase/client/go/chat/signencrypt"
	"github.com/keybase/client/go/libkb"
)

type Encrypter interface {
	// EncryptedLen returns the number of bytes that the ciphertext of
	// size plaintext bytes will be.
	EncryptedLen(size int) int

	// Encrypt takes a plaintext reader and returns a ciphertext reader.
	Encrypt(plaintext io.Reader) (ciphertext io.Reader)

	// EncryptKey returns the ephemeral key that was used during Encrypt.
	EncryptKey() []byte

	// VerifyKey returns the public portion of the signing key that
	// can be used for signature verification.
	VerifyKey() []byte
}

type Decrypter interface {
	// Decrypt takes a ciphertext reader, encryption and verify keys.
	// It returns a plaintext reader.
	Decrypt(ciphertext io.Reader, encKey, verifyKey []byte) (plaintext io.Reader)
}

var nonce = &[signencrypt.NonceSize]byte{
	0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20,
	0x30, 0x30, 0x30, 0x30, 0x40, 0x40, 0x40, 0x40,
}

type SignEncrypter struct {
	encKey    signencrypt.SecretboxKey
	signKey   signencrypt.SignKey
	verifyKey signencrypt.VerifyKey
}

func NewSignEncrypter() (*SignEncrypter, error) {
	var encKey [signencrypt.SecretboxKeySize]byte
	n, err := rand.Read(encKey[:])
	if err != nil {
		return nil, err
	}
	if n != signencrypt.SecretboxKeySize {
		return nil, errors.New("failed to rand.Read the correct number of bytes")
	}

	sign, err := libkb.GenerateNaclSigningKeyPair()
	if err != nil {
		return nil, err
	}

	var signKey [ed25519.PrivateKeySize]byte
	copy(signKey[:], (*sign.Private)[:])
	var verifyKey [ed25519.PublicKeySize]byte
	copy(verifyKey[:], sign.Public[:])

	res := SignEncrypter{
		encKey:    &encKey,
		signKey:   &signKey,
		verifyKey: &verifyKey,
	}

	return &res, nil
}

func (s *SignEncrypter) EncryptedLen(size int) int {
	return signencrypt.GetSealedSize(size)
}

func (s *SignEncrypter) Encrypt(r io.Reader) io.Reader {
	return signencrypt.NewEncodingReader(s.encKey, s.signKey, nonce, r)
}

func (s *SignEncrypter) EncryptKey() []byte {
	return []byte((*s.encKey)[:])
}

func (s *SignEncrypter) VerifyKey() []byte {
	return []byte((*s.verifyKey)[:])
}

type SignDecrypter struct{}

func NewSignDecrypter() *SignDecrypter {
	return &SignDecrypter{}
}

func (s *SignDecrypter) Decrypt(r io.Reader, encKey, verifyKey []byte) io.Reader {
	var xencKey [signencrypt.SecretboxKeySize]byte
	copy(xencKey[:], encKey)
	var xverifyKey [ed25519.PublicKeySize]byte
	copy(xverifyKey[:], verifyKey)
	return signencrypt.NewDecodingReader(&xencKey, &xverifyKey, nonce, r)
}
<|endoftext|>


<commit_before>package chessboard

// Declare a type named Rank which stores if a square is occupied by a piece - this will be a slice of bools

// Declare a type named Chessboard contains a map of eight Ranks, accessed with values from 1 to 8

// CountInRank returns how many squares are occupied in the chessboard,
// within the given rank
func CountInRank(cb Chessboard, rank int) (ret int) {
	panic("Please implement CountInRank()")
}

// CountInFile returns how many squares are occupied in the chessboard,
// within the given file
func CountInFile(cb Chessboard, file int) (ret int) {
	panic("Please implement CountInFile()")
}

// CountAll should count how many squares are present in the chessboard
func CountAll(cb Chessboard) (ret int) {
	panic("Please implement CountAll()")
}

// CountOccupied returns how many squares are occupied in the chessboard
func CountOccupied(cb Chessboard) (ret int) {
	panic("Please implement CountOccupied()")
}
<commit_msg>Solve chessboard<commit_after>package chessboard

// Declare a type named Rank which stores if a square is occupied by a piece - this will be a slice of bools
type Rank = []bool

// Declare a type named Chessboard contains a map of eight Ranks, accessed with values from 1 to 8
type Chessboard map[int]Rank

// CountInRank returns how many squares are occupied in the chessboard,
// within the given rank
func CountInRank(cb Chessboard, rank int) (ret int) {
	for _, square := range cb[rank] {
		if square {
			ret += 1
		}
	}
	return ret
}

// CountInFile returns how many squares are occupied in the chessboard,
// within the given file
func CountInFile(cb Chessboard, file int) (ret int) {
	if file > 8 || file < 1 {
		return 0
	}
	for _, rank := range cb {
		if rank[file-1] {
			ret += 1
		}
	}
	return ret
}

// CountAll should count how many squares are present in the chessboard
func CountAll(cb Chessboard) (ret int) {
	for _, rank := range cb {
		for range rank {
			ret += 1
		}
	}
	return ret
}

// CountOccupied returns how many squares are occupied in the chessboard
func CountOccupied(cb Chessboard) (ret int) {
	for _, rank := range cb {
		for _, square := range rank {
			if square {
				ret += 1
			}
		}
	}
	return ret
}
<|endoftext|>


<commit_before>package client

import (
	"errors"
	"fmt"

	"golang.org/x/net/context"

	"github.com/keybase/cli"
	"github.com/keybase/client/go/libcmdline"
	"github.com/keybase/client/go/libkb"
	keybase1 "github.com/keybase/client/go/protocol/keybase1"
)

type CmdGitCreate struct {
	libkb.Contextified
	repoName   keybase1.GitRepoName
	teamName   keybase1.TeamName
	skipNotify bool
}

func newCmdGitCreate(cl *libcmdline.CommandLine, g *libkb.GlobalContext) cli.Command {
	return cli.Command{
		Name:         "create",
		ArgumentHelp: "[--team=<team name>] <repo name>",
		Usage:        "Create a personal or team git repository.",
		Description:  "`keybase git create reponame` will create a personal git repo.\n   `keybase git create --team=treehouse reponame` will create a\n   team git repo for the `treehouse` team.",
		Action: func(c *cli.Context) {
			cmd := NewCmdGitCreateRunner(g)
			cl.ChooseCommand(cmd, "create", c)
		},
		Flags: []cli.Flag{
			cli.StringFlag{
				Name:  "team",
				Usage: "keybase team name (optional)",
			},
			cli.BoolFlag{
				Name:  "skip-notify",
				Usage: "skip posting new repo notifications for team members",
			},
		},
	}
}

func NewCmdGitCreateRunner(g *libkb.GlobalContext) *CmdGitCreate {
	return &CmdGitCreate{Contextified: libkb.NewContextified(g)}
}

func (c *CmdGitCreate) ParseArgv(ctx *cli.Context) error {
	if len(ctx.Args()) == 0 {
		return errors.New("repo name argument required")
	}
	c.repoName = keybase1.GitRepoName(ctx.Args()[0])
	c.skipNotify = ctx.Bool("skip-notify")
	if len(ctx.String("team")) > 0 {
		teamName, err := keybase1.TeamNameFromString(ctx.String("team"))
		if err != nil {
			return err
		}
		c.teamName = teamName
	}

	return nil
}

func (c *CmdGitCreate) Run() error {
	cli, err := GetGitClient(c.G())
	if err != nil {
		return err
	}

	var urlString string
	if len(c.teamName.String()) > 0 {
		urlString, err = c.runTeam(cli)
	} else {
		urlString, err = c.runPersonal(cli)
	}

	if err != nil {
		return err
	}

	dui := c.G().UI.GetDumbOutputUI()
	dui.Printf("Repo created! You can clone it with:\n  git clone %s\n", urlString)
	return nil
}

func (c *CmdGitCreate) runPersonal(cli keybase1.GitClient) (string, error) {
	if _, err := cli.CreatePersonalRepo(context.Background(), c.repoName); err != nil {
		return "", err
	}
	return fmt.Sprintf("keybase://private/%s/%s", c.G().Env.GetUsername(), c.repoName), nil
}

func (c *CmdGitCreate) runTeam(cli keybase1.GitClient) (string, error) {
	arg := keybase1.CreateTeamRepoArg{
		TeamName:   c.teamName,
		RepoName:   c.repoName,
		NotifyTeam: !c.skipNotify,
	}
	if _, err := cli.CreateTeamRepo(context.Background(), arg); err != nil {
		return "", err
	}
	return fmt.Sprintf("keybase://team/%s/%s", c.teamName, c.repoName), nil
}

func (c *CmdGitCreate) GetUsage() libkb.Usage {
	return libkb.Usage{
		Config:    true,
		API:       true,
		KbKeyring: true,
	}
}
<commit_msg>git hint (#12675)<commit_after>package client

import (
	"errors"
	"fmt"

	"golang.org/x/net/context"

	"github.com/keybase/cli"
	"github.com/keybase/client/go/libcmdline"
	"github.com/keybase/client/go/libkb"
	keybase1 "github.com/keybase/client/go/protocol/keybase1"
)

type CmdGitCreate struct {
	libkb.Contextified
	repoName   keybase1.GitRepoName
	teamName   keybase1.TeamName
	skipNotify bool
}

func newCmdGitCreate(cl *libcmdline.CommandLine, g *libkb.GlobalContext) cli.Command {
	return cli.Command{
		Name:         "create",
		ArgumentHelp: "[--team=<team name>] <repo name>",
		Usage:        "Create a personal or team git repository.",
		Description:  "`keybase git create reponame` will create a personal git repo.\n   `keybase git create --team=treehouse reponame` will create a\n   team git repo for the `treehouse` team.",
		Action: func(c *cli.Context) {
			cmd := NewCmdGitCreateRunner(g)
			cl.ChooseCommand(cmd, "create", c)
		},
		Flags: []cli.Flag{
			cli.StringFlag{
				Name:  "team",
				Usage: "keybase team name (optional)",
			},
			cli.BoolFlag{
				Name:  "skip-notify",
				Usage: "skip posting new repo notifications for team members",
			},
		},
	}
}

func NewCmdGitCreateRunner(g *libkb.GlobalContext) *CmdGitCreate {
	return &CmdGitCreate{Contextified: libkb.NewContextified(g)}
}

func (c *CmdGitCreate) ParseArgv(ctx *cli.Context) error {
	if len(ctx.Args()) == 0 {
		return errors.New("repo name argument required")
	}
	c.repoName = keybase1.GitRepoName(ctx.Args()[0])
	c.skipNotify = ctx.Bool("skip-notify")
	if len(ctx.String("team")) > 0 {
		teamName, err := keybase1.TeamNameFromString(ctx.String("team"))
		if err != nil {
			return err
		}
		c.teamName = teamName
	}

	return nil
}

func (c *CmdGitCreate) Run() error {
	cli, err := GetGitClient(c.G())
	if err != nil {
		return err
	}

	var urlString string
	if len(c.teamName.String()) > 0 {
		urlString, err = c.runTeam(cli)
	} else {
		urlString, err = c.runPersonal(cli)
	}

	if err != nil {
		return err
	}

	dui := c.G().UI.GetDumbOutputUI()
	dui.Printf(`Repo created! You can clone it with:
  git clone %s
Or add it as a remote to an existing repo with:
  git remote add origin %s
`, urlString, urlString)
	return nil
}

func (c *CmdGitCreate) runPersonal(cli keybase1.GitClient) (string, error) {
	if _, err := cli.CreatePersonalRepo(context.Background(), c.repoName); err != nil {
		return "", err
	}
	return fmt.Sprintf("keybase://private/%s/%s", c.G().Env.GetUsername(), c.repoName), nil
}

func (c *CmdGitCreate) runTeam(cli keybase1.GitClient) (string, error) {
	arg := keybase1.CreateTeamRepoArg{
		TeamName:   c.teamName,
		RepoName:   c.repoName,
		NotifyTeam: !c.skipNotify,
	}
	if _, err := cli.CreateTeamRepo(context.Background(), arg); err != nil {
		return "", err
	}
	return fmt.Sprintf("keybase://team/%s/%s", c.teamName, c.repoName), nil
}

func (c *CmdGitCreate) GetUsage() libkb.Usage {
	return libkb.Usage{
		Config:    true,
		API:       true,
		KbKeyring: true,
	}
}
<|endoftext|>


<commit_before>// Copyright 2012, Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"flag"
	"fmt"
	"log"
	"net/url"
	"os"
	"strings"

	"code.google.com/p/vitess/go/relog"
	"code.google.com/p/vitess/go/vt/dbconfigs"
	"code.google.com/p/vitess/go/vt/key"
	"code.google.com/p/vitess/go/vt/mysqlctl"
)

var port = flag.Int("port", 6612, "vtocc port")
var mysqlPort = flag.Int("mysql-port", 3306, "mysql port")
var tabletUid = flag.Uint("tablet-uid", 41983, "tablet uid")
var logLevel = flag.String("log.level", "WARNING", "set log level")
var tabletAddr string

func initCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	waitTime := subFlags.Duration("wait-time", mysqlctl.MysqlWaitTime, "how long to wait for startup")
	subFlags.Parse(args)

	if err := mysqlctl.Init(mysqld, *waitTime); err != nil {
		relog.Fatal("failed init mysql: %v", err)
	}
}

func partialRestoreCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	fetchConcurrency := subFlags.Int("fetch-concurrency", 3, "how many files to fetch simultaneously")
	fetchRetryCount := subFlags.Int("fetch-retry-count", 3, "how many times to retry a failed transfer")
	subFlags.Parse(args)
	if subFlags.NArg() != 1 {
		relog.Fatal("Command partialrestore requires <split snapshot manifest file>")
	}

	rs, err := mysqlctl.ReadSplitSnapshotManifest(subFlags.Arg(0))
	if err == nil {
		err = mysqld.RestoreFromPartialSnapshot(rs, *fetchConcurrency, *fetchRetryCount)
	}
	if err != nil {
		relog.Fatal("partialrestore failed: %v", err)
	}
}

func partialSnapshotCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	start := subFlags.String("start", "", "start of the key range")
	end := subFlags.String("end", "", "end of the key range")
	concurrency := subFlags.Int("concurrency", 4, "how many compression jobs to run simultaneously")
	subFlags.Parse(args)
	if subFlags.NArg() != 2 {
		relog.Fatal("action partialsnapshot requires <db name> <key name>")
	}

	filename, err := mysqld.CreateSplitSnapshot(subFlags.Arg(0), subFlags.Arg(1), key.HexKeyspaceId(*start), key.HexKeyspaceId(*end), tabletAddr, false, *concurrency)
	if err != nil {
		relog.Fatal("partialsnapshot failed: %v", err)
	} else {
		relog.Info("manifest location: %v", filename)
	}
}

func multisnapshotCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	concurrency := subFlags.Int("concurrency", 3, "how many compression jobs to run simultaneously")
	spec := subFlags.String("spec", "-", "shard specification")
	tablesString := subFlags.String("tables", "", "dump only this comma separated list of tables")
	subFlags.Parse(args)
	if subFlags.NArg() != 2 {
		relog.Fatal("action partialsnapshot requires <db name> <key name>")
	}
	shards, err := key.ParseShardingSpec(*spec)
	if err != nil {
		relog.Fatal("multisnapshot failed: %v", err)
	}
	var tables []string
	if *tablesString != "" {
		tables = strings.Split(*tablesString, ",")
	}
	filenames, err := mysqld.CreateMultiSnapshot(shards, subFlags.Arg(0), subFlags.Arg(1), tabletAddr, false, *concurrency, tables)
	if err != nil {
		relog.Fatal("multisnapshot failed: %v", err)
	} else {
		relog.Info("manifest locations: %v", filenames)
	}
}

func multiRestoreCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	force := subFlags.Bool("force", false, "restore even if the schemas don't match")
	start := subFlags.String("start", "", "start of the key range")
	end := subFlags.String("end", "", "end of the key range")
	fetchRetryCount := subFlags.Int("fetch-retry-count", 3, "how many times to retry a failed transfer")
	concurrency := subFlags.Int("concurrency", 4, "how many concurrent jobs to run simultaneously")
	fetchConcurrency := subFlags.Int("fetch-concurrency", 4, "how many files to fetch simultaneously")

	subFlags.Parse(args)

	keyRange := key.KeyRange{Start: key.HexKeyspaceId(*start).Unhex(), End: key.HexKeyspaceId(*end).Unhex()}

	if subFlags.NArg() < 2 {
		relog.Fatal("multirestore requires <destination_dbname> <source_host>[/<source_dbname>]... %v", args)
	}
	dbName, dbis := subFlags.Arg(0), subFlags.Args()[1:]
	sources := make([]*url.URL, len(dbis))
	for i, dbi := range dbis {
		if !strings.HasPrefix(dbi, "vttp://") && !strings.HasPrefix(dbi, "http://") {
			dbi = "vttp://" + dbi
		}
		dbUrl, err := url.Parse(dbi)
		if err != nil {
			relog.Fatal("incorrect source url: %v", err)
		}
		sources[i] = dbUrl
	}
	if err := mysqld.RestoreFromMultiSnapshot(dbName, keyRange, sources, *concurrency, *fetchConcurrency, *fetchRetryCount, *force); err != nil {
		relog.Fatal("multirestore failed: %v", err)
	}
}

func restoreCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	dontWaitForSlaveStart := subFlags.Bool("dont-wait-for-slave-start", false, "won't wait for replication to start (useful when restoring from master server)")
	fetchConcurrency := subFlags.Int("fetch-concurrency", 3, "how many files to fetch simultaneously")
	fetchRetryCount := subFlags.Int("fetch-retry-count", 3, "how many times to retry a failed transfer")
	subFlags.Parse(args)
	if subFlags.NArg() != 1 {
		relog.Fatal("Command restore requires <snapshot manifest file>")
	}

	rs, err := mysqlctl.ReadSnapshotManifest(subFlags.Arg(0))
	if err == nil {
		err = mysqld.RestoreFromSnapshot(rs, *fetchConcurrency, *fetchRetryCount, *dontWaitForSlaveStart)
	}
	if err != nil {
		relog.Fatal("restore failed: %v", err)
	}
}

func shutdownCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	waitTime := subFlags.Duration("wait-time", mysqlctl.MysqlWaitTime, "how long to wait for shutdown")
	subFlags.Parse(args)

	if mysqlErr := mysqlctl.Shutdown(mysqld, true, *waitTime); mysqlErr != nil {
		relog.Fatal("failed shutdown mysql: %v", mysqlErr)
	}
}

func snapshotCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	concurrency := subFlags.Int("concurrency", 4, "how many compression jobs to run simultaneously")
	subFlags.Parse(args)
	if subFlags.NArg() != 1 {
		relog.Fatal("Command snapshot requires <db name>")
	}

	filename, _, _, err := mysqld.CreateSnapshot(subFlags.Arg(0), tabletAddr, false, *concurrency, false)
	if err != nil {
		relog.Fatal("snapshot failed: %v", err)
	} else {
		relog.Info("manifest location: %v", filename)
	}
}

func snapshotSourceStartCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	concurrency := subFlags.Int("concurrency", 4, "how many checksum jobs to run simultaneously")
	subFlags.Parse(args)
	if subFlags.NArg() != 1 {
		relog.Fatal("Command snapshotsourcestart requires <db name>")
	}

	filename, slaveStartRequired, readOnly, err := mysqld.CreateSnapshot(subFlags.Arg(0), tabletAddr, false, *concurrency, true)
	if err != nil {
		relog.Fatal("snapshot failed: %v", err)
	} else {
		relog.Info("manifest location: %v", filename)
		relog.Info("slave start required: %v", slaveStartRequired)
		relog.Info("read only: %v", readOnly)
	}
}

func snapshotSourceEndCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	slaveStartRequired := subFlags.Bool("slave-start", false, "will restart replication")
	readWrite := subFlags.Bool("read-write", false, "will make the server read-write")
	subFlags.Parse(args)

	err := mysqld.SnapshotSourceEnd(*slaveStartRequired, !(*readWrite), true)
	if err != nil {
		relog.Fatal("snapshotsourceend failed: %v", err)
	}
}

func startCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	waitTime := subFlags.Duration("wait-time", mysqlctl.MysqlWaitTime, "how long to wait for startup")
	subFlags.Parse(args)

	if err := mysqlctl.Start(mysqld, *waitTime); err != nil {
		relog.Fatal("failed start mysql: %v", err)
	}
}

func teardownCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	force := subFlags.Bool("force", false, "will remove the root directory even if mysqld shutdown fails")
	subFlags.Parse(args)

	if err := mysqlctl.Teardown(mysqld, *force); err != nil {
		relog.Fatal("failed teardown mysql (forced? %v): %v", *force, err)
	}
}

type command struct {
	name   string
	method func(*mysqlctl.Mysqld, *flag.FlagSet, []string)
	params string
	help   string
}

var commands = []command{
	command{"init", initCmd, "",
		"Initalizes the directory structure and starts mysqld"},
	command{"teardown", teardownCmd, "[-force]",
		"Shuts mysqld down, and removes the directory"},
	command{"start", startCmd, "[-wait-time=20s]",
		"Starts mysqld on an already 'init'-ed directory"},
	command{"shutdown", shutdownCmd, "[-wait-time=20s]",
		"Shuts down mysqld, does not remove any file"},

	command{"snapshot", snapshotCmd,
		"[-concurrency=4] <db name>",
		"Takes a full snapshot, copying the innodb data files"},
	command{"snapshotsourcestart", snapshotSourceStartCmd,
		"[-concurrency=4] <db name>",
		"Enters snapshot server mode (mysqld stopped, serving innodb data files)"},
	command{"snapshotsourceend", snapshotSourceEndCmd,
		"[-slave-start] [-read-write]",
		"Gets out of snapshot server mode"},
	command{"restore", restoreCmd,
		"[-fetch-concurrency=3] [-fetch-retry-count=3] [-dont-wait-for-slave-start] <snapshot manifest file>",
		"Restores a full snapshot"},
	command{"multirestore", multiRestoreCmd,
		"[-force] [-concurrency=3] [-fetch-concurrency=4] [-fetch-retry-count=3] [-start=''] [-end=''] <destination_dbname> <source_host>[/<source_dbname>]...",
		"Restores a snapshot form multiple hosts"},
	command{"partialsnapshot", partialSnapshotCmd,
		"[-start=<start key>] [-end=<end key>] [-concurrency=4] <db name> <key name>",
		"Takes a partial snapshot using 'select * into' commands"},
	command{"partialrestore", partialRestoreCmd,
		"[-fetch-concurrency=3] [-fetch-retry-count=3] <split snapshot manifest file>",
		"Restores a database from a partial snapshot"},
	command{"multisnapshot", multisnapshotCmd, "[-concurrency=3] [-spec='-'] [-tables=''] <db name> <key name>",
		"Makes a complete snapshot using 'select * into' commands."},
}

func main() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [global parameters] command [command parameters]\n", os.Args[0])

		fmt.Fprintf(os.Stderr, "\nThe global optional parameters are:\n")
		flag.PrintDefaults()

		fmt.Fprintf(os.Stderr, "\nThe commands are listed below. Use '%s <command> -h' for more help.\n\n", os.Args[0])
		for _, cmd := range commands {
			fmt.Fprintf(os.Stderr, "  %s", cmd.name)
			if cmd.params != "" {
				fmt.Fprintf(os.Stderr, " %s", cmd.params)
			}
			fmt.Fprintf(os.Stderr, "\n")
		}
		fmt.Fprintf(os.Stderr, "\n")
	}
	dbConfigsFile, dbCredentialsFile := dbconfigs.RegisterCommonFlags()
	flag.Parse()

	logger := relog.New(os.Stderr, "",
		log.Ldate|log.Lmicroseconds|log.Lshortfile,
		relog.LogNameToLogLevel(*logLevel))
	relog.SetLogger(logger)

	tabletAddr = fmt.Sprintf("%v:%v", "localhost", *port)
	mycnf := mysqlctl.NewMycnf(uint32(*tabletUid), *mysqlPort, mysqlctl.VtReplParams{})
	dbcfgs, err := dbconfigs.Init(mycnf.SocketFile, *dbConfigsFile, *dbCredentialsFile)
	if err != nil {
		relog.Fatal("%v", err)
	}
	mysqld := mysqlctl.NewMysqld(mycnf, dbcfgs.Dba, dbcfgs.Repl)

	action := flag.Arg(0)
	for _, cmd := range commands {
		if cmd.name == action {
			subFlags := flag.NewFlagSet(action, flag.ExitOnError)
			subFlags.Usage = func() {
				fmt.Fprintf(os.Stderr, "Usage: %s %s %s\n\n", os.Args[0], cmd.name, cmd.params)
				fmt.Fprintf(os.Stderr, "%s\n\n", cmd.help)
				subFlags.PrintDefaults()
			}

			cmd.method(mysqld, subFlags, flag.Args()[1:])
			return
		}
	}
	relog.Fatal("invalid action: %v", action)
}
<commit_msg>Add option to pass a socket file to mysqlctl.<commit_after>// Copyright 2012, Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"flag"
	"fmt"
	"log"
	"net/url"
	"os"
	"strings"

	"code.google.com/p/vitess/go/relog"
	"code.google.com/p/vitess/go/vt/dbconfigs"
	"code.google.com/p/vitess/go/vt/key"
	"code.google.com/p/vitess/go/vt/mysqlctl"
)

var port = flag.Int("port", 6612, "vtocc port")
var mysqlPort = flag.Int("mysql-port", 3306, "mysql port")
var tabletUid = flag.Uint("tablet-uid", 41983, "tablet uid")
var logLevel = flag.String("log.level", "WARNING", "set log level")
var mysqlSocket = flag.String("mysql-socket", "", "path to the mysql socket")
var tabletAddr string

func initCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	waitTime := subFlags.Duration("wait-time", mysqlctl.MysqlWaitTime, "how long to wait for startup")
	subFlags.Parse(args)

	if err := mysqlctl.Init(mysqld, *waitTime); err != nil {
		relog.Fatal("failed init mysql: %v", err)
	}
}

func partialRestoreCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	fetchConcurrency := subFlags.Int("fetch-concurrency", 3, "how many files to fetch simultaneously")
	fetchRetryCount := subFlags.Int("fetch-retry-count", 3, "how many times to retry a failed transfer")
	subFlags.Parse(args)
	if subFlags.NArg() != 1 {
		relog.Fatal("Command partialrestore requires <split snapshot manifest file>")
	}

	rs, err := mysqlctl.ReadSplitSnapshotManifest(subFlags.Arg(0))
	if err == nil {
		err = mysqld.RestoreFromPartialSnapshot(rs, *fetchConcurrency, *fetchRetryCount)
	}
	if err != nil {
		relog.Fatal("partialrestore failed: %v", err)
	}
}

func partialSnapshotCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	start := subFlags.String("start", "", "start of the key range")
	end := subFlags.String("end", "", "end of the key range")
	concurrency := subFlags.Int("concurrency", 4, "how many compression jobs to run simultaneously")
	subFlags.Parse(args)
	if subFlags.NArg() != 2 {
		relog.Fatal("action partialsnapshot requires <db name> <key name>")
	}

	filename, err := mysqld.CreateSplitSnapshot(subFlags.Arg(0), subFlags.Arg(1), key.HexKeyspaceId(*start), key.HexKeyspaceId(*end), tabletAddr, false, *concurrency)
	if err != nil {
		relog.Fatal("partialsnapshot failed: %v", err)
	} else {
		relog.Info("manifest location: %v", filename)
	}
}

func multisnapshotCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	concurrency := subFlags.Int("concurrency", 3, "how many compression jobs to run simultaneously")
	spec := subFlags.String("spec", "-", "shard specification")
	tablesString := subFlags.String("tables", "", "dump only this comma separated list of tables")
	subFlags.Parse(args)
	if subFlags.NArg() != 2 {
		relog.Fatal("action partialsnapshot requires <db name> <key name>")
	}
	shards, err := key.ParseShardingSpec(*spec)
	if err != nil {
		relog.Fatal("multisnapshot failed: %v", err)
	}
	var tables []string
	if *tablesString != "" {
		tables = strings.Split(*tablesString, ",")
	}
	filenames, err := mysqld.CreateMultiSnapshot(shards, subFlags.Arg(0), subFlags.Arg(1), tabletAddr, false, *concurrency, tables)
	if err != nil {
		relog.Fatal("multisnapshot failed: %v", err)
	} else {
		relog.Info("manifest locations: %v", filenames)
	}
}

func multiRestoreCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	force := subFlags.Bool("force", false, "restore even if the schemas don't match")
	start := subFlags.String("start", "", "start of the key range")
	end := subFlags.String("end", "", "end of the key range")
	fetchRetryCount := subFlags.Int("fetch-retry-count", 3, "how many times to retry a failed transfer")
	concurrency := subFlags.Int("concurrency", 4, "how many concurrent jobs to run simultaneously")
	fetchConcurrency := subFlags.Int("fetch-concurrency", 4, "how many files to fetch simultaneously")

	subFlags.Parse(args)

	keyRange := key.KeyRange{Start: key.HexKeyspaceId(*start).Unhex(), End: key.HexKeyspaceId(*end).Unhex()}

	if subFlags.NArg() < 2 {
		relog.Fatal("multirestore requires <destination_dbname> <source_host>[/<source_dbname>]... %v", args)
	}
	dbName, dbis := subFlags.Arg(0), subFlags.Args()[1:]
	sources := make([]*url.URL, len(dbis))
	for i, dbi := range dbis {
		if !strings.HasPrefix(dbi, "vttp://") && !strings.HasPrefix(dbi, "http://") {
			dbi = "vttp://" + dbi
		}
		dbUrl, err := url.Parse(dbi)
		if err != nil {
			relog.Fatal("incorrect source url: %v", err)
		}
		sources[i] = dbUrl
	}
	if err := mysqld.RestoreFromMultiSnapshot(dbName, keyRange, sources, *concurrency, *fetchConcurrency, *fetchRetryCount, *force); err != nil {
		relog.Fatal("multirestore failed: %v", err)
	}
}

func restoreCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	dontWaitForSlaveStart := subFlags.Bool("dont-wait-for-slave-start", false, "won't wait for replication to start (useful when restoring from master server)")
	fetchConcurrency := subFlags.Int("fetch-concurrency", 3, "how many files to fetch simultaneously")
	fetchRetryCount := subFlags.Int("fetch-retry-count", 3, "how many times to retry a failed transfer")
	subFlags.Parse(args)
	if subFlags.NArg() != 1 {
		relog.Fatal("Command restore requires <snapshot manifest file>")
	}

	rs, err := mysqlctl.ReadSnapshotManifest(subFlags.Arg(0))
	if err == nil {
		err = mysqld.RestoreFromSnapshot(rs, *fetchConcurrency, *fetchRetryCount, *dontWaitForSlaveStart)
	}
	if err != nil {
		relog.Fatal("restore failed: %v", err)
	}
}

func shutdownCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	waitTime := subFlags.Duration("wait-time", mysqlctl.MysqlWaitTime, "how long to wait for shutdown")
	subFlags.Parse(args)

	if mysqlErr := mysqlctl.Shutdown(mysqld, true, *waitTime); mysqlErr != nil {
		relog.Fatal("failed shutdown mysql: %v", mysqlErr)
	}
}

func snapshotCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	concurrency := subFlags.Int("concurrency", 4, "how many compression jobs to run simultaneously")
	subFlags.Parse(args)
	if subFlags.NArg() != 1 {
		relog.Fatal("Command snapshot requires <db name>")
	}

	filename, _, _, err := mysqld.CreateSnapshot(subFlags.Arg(0), tabletAddr, false, *concurrency, false)
	if err != nil {
		relog.Fatal("snapshot failed: %v", err)
	} else {
		relog.Info("manifest location: %v", filename)
	}
}

func snapshotSourceStartCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	concurrency := subFlags.Int("concurrency", 4, "how many checksum jobs to run simultaneously")
	subFlags.Parse(args)
	if subFlags.NArg() != 1 {
		relog.Fatal("Command snapshotsourcestart requires <db name>")
	}

	filename, slaveStartRequired, readOnly, err := mysqld.CreateSnapshot(subFlags.Arg(0), tabletAddr, false, *concurrency, true)
	if err != nil {
		relog.Fatal("snapshot failed: %v", err)
	} else {
		relog.Info("manifest location: %v", filename)
		relog.Info("slave start required: %v", slaveStartRequired)
		relog.Info("read only: %v", readOnly)
	}
}

func snapshotSourceEndCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	slaveStartRequired := subFlags.Bool("slave-start", false, "will restart replication")
	readWrite := subFlags.Bool("read-write", false, "will make the server read-write")
	subFlags.Parse(args)

	err := mysqld.SnapshotSourceEnd(*slaveStartRequired, !(*readWrite), true)
	if err != nil {
		relog.Fatal("snapshotsourceend failed: %v", err)
	}
}

func startCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	waitTime := subFlags.Duration("wait-time", mysqlctl.MysqlWaitTime, "how long to wait for startup")
	subFlags.Parse(args)

	if err := mysqlctl.Start(mysqld, *waitTime); err != nil {
		relog.Fatal("failed start mysql: %v", err)
	}
}

func teardownCmd(mysqld *mysqlctl.Mysqld, subFlags *flag.FlagSet, args []string) {
	force := subFlags.Bool("force", false, "will remove the root directory even if mysqld shutdown fails")
	subFlags.Parse(args)

	if err := mysqlctl.Teardown(mysqld, *force); err != nil {
		relog.Fatal("failed teardown mysql (forced? %v): %v", *force, err)
	}
}

type command struct {
	name   string
	method func(*mysqlctl.Mysqld, *flag.FlagSet, []string)
	params string
	help   string
}

var commands = []command{
	command{"init", initCmd, "",
		"Initalizes the directory structure and starts mysqld"},
	command{"teardown", teardownCmd, "[-force]",
		"Shuts mysqld down, and removes the directory"},
	command{"start", startCmd, "[-wait-time=20s]",
		"Starts mysqld on an already 'init'-ed directory"},
	command{"shutdown", shutdownCmd, "[-wait-time=20s]",
		"Shuts down mysqld, does not remove any file"},

	command{"snapshot", snapshotCmd,
		"[-concurrency=4] <db name>",
		"Takes a full snapshot, copying the innodb data files"},
	command{"snapshotsourcestart", snapshotSourceStartCmd,
		"[-concurrency=4] <db name>",
		"Enters snapshot server mode (mysqld stopped, serving innodb data files)"},
	command{"snapshotsourceend", snapshotSourceEndCmd,
		"[-slave-start] [-read-write]",
		"Gets out of snapshot server mode"},
	command{"restore", restoreCmd,
		"[-fetch-concurrency=3] [-fetch-retry-count=3] [-dont-wait-for-slave-start] <snapshot manifest file>",
		"Restores a full snapshot"},
	command{"multirestore", multiRestoreCmd,
		"[-force] [-concurrency=3] [-fetch-concurrency=4] [-fetch-retry-count=3] [-start=''] [-end=''] <destination_dbname> <source_host>[/<source_dbname>]...",
		"Restores a snapshot form multiple hosts"},
	command{"partialsnapshot", partialSnapshotCmd,
		"[-start=<start key>] [-end=<end key>] [-concurrency=4] <db name> <key name>",
		"Takes a partial snapshot using 'select * into' commands"},
	command{"partialrestore", partialRestoreCmd,
		"[-fetch-concurrency=3] [-fetch-retry-count=3] <split snapshot manifest file>",
		"Restores a database from a partial snapshot"},
	command{"multisnapshot", multisnapshotCmd, "[-concurrency=3] [-spec='-'] [-tables=''] <db name> <key name>",
		"Makes a complete snapshot using 'select * into' commands."},
}

func main() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [global parameters] command [command parameters]\n", os.Args[0])

		fmt.Fprintf(os.Stderr, "\nThe global optional parameters are:\n")
		flag.PrintDefaults()

		fmt.Fprintf(os.Stderr, "\nThe commands are listed below. Use '%s <command> -h' for more help.\n\n", os.Args[0])
		for _, cmd := range commands {
			fmt.Fprintf(os.Stderr, "  %s", cmd.name)
			if cmd.params != "" {
				fmt.Fprintf(os.Stderr, " %s", cmd.params)
			}
			fmt.Fprintf(os.Stderr, "\n")
		}
		fmt.Fprintf(os.Stderr, "\n")
	}
	dbConfigsFile, dbCredentialsFile := dbconfigs.RegisterCommonFlags()
	flag.Parse()

	logger := relog.New(os.Stderr, "",
		log.Ldate|log.Lmicroseconds|log.Lshortfile,
		relog.LogNameToLogLevel(*logLevel))
	relog.SetLogger(logger)

	tabletAddr = fmt.Sprintf("%v:%v", "localhost", *port)
	mycnf := mysqlctl.NewMycnf(uint32(*tabletUid), *mysqlPort, mysqlctl.VtReplParams{})

	if *mysqlSocket != "" {
		mycnf.SocketFile = *mysqlSocket
	}

	dbcfgs, err := dbconfigs.Init(mycnf.SocketFile, *dbConfigsFile, *dbCredentialsFile)
	if err != nil {
		relog.Fatal("%v", err)
	}
	mysqld := mysqlctl.NewMysqld(mycnf, dbcfgs.Dba, dbcfgs.Repl)

	action := flag.Arg(0)
	for _, cmd := range commands {
		if cmd.name == action {
			subFlags := flag.NewFlagSet(action, flag.ExitOnError)
			subFlags.Usage = func() {
				fmt.Fprintf(os.Stderr, "Usage: %s %s %s\n\n", os.Args[0], cmd.name, cmd.params)
				fmt.Fprintf(os.Stderr, "%s\n\n", cmd.help)
				subFlags.PrintDefaults()
			}

			cmd.method(mysqld, subFlags, flag.Args()[1:])
			return
		}
	}
	relog.Fatal("invalid action: %v", action)
}
<|endoftext|>


<commit_before>/*
Copyright 2017 Google 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.
*/

// vt tablet server: Serves queries and performs housekeeping jobs.
package main

import (
	"flag"

	"golang.org/x/net/context"
	"vitess.io/vitess/go/vt/dbconfigs"
	"vitess.io/vitess/go/vt/log"
	"vitess.io/vitess/go/vt/mysqlctl"
	"vitess.io/vitess/go/vt/servenv"
	"vitess.io/vitess/go/vt/tableacl"
	"vitess.io/vitess/go/vt/tableacl/simpleacl"
	"vitess.io/vitess/go/vt/topo"
	"vitess.io/vitess/go/vt/topo/topoproto"
	"vitess.io/vitess/go/vt/vttablet/tabletmanager"
	"vitess.io/vitess/go/vt/vttablet/tabletserver"
	"vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv"
)

var (
	enforceTableACLConfig = flag.Bool("enforce-tableacl-config", false, "if this flag is true, vttablet will fail to start if a valid tableacl config does not exist")
	tableACLConfig        = flag.String("table-acl-config", "", "path to table access checker config file; send SIGHUP to reload this file")
	tabletPath            = flag.String("tablet-path", "", "tablet alias")

	agent *tabletmanager.ActionAgent
)

func init() {
	servenv.RegisterDefaultFlags()
}

func main() {
	dbconfigs.RegisterFlags(dbconfigs.All...)
	mysqlctl.RegisterFlags()

	servenv.ParseFlags("vttablet")

	if err := tabletenv.VerifyConfig(); err != nil {
		log.Exitf("invalid config: %v", err)
	}

	tabletenv.Init()

	servenv.Init()

	if *tabletPath == "" {
		log.Exit("tabletPath required")
	}
	tabletAlias, err := topoproto.ParseTabletAlias(*tabletPath)
	if err != nil {
		log.Exitf("failed to parse -tablet-path: %v", err)
	}

	var mycnf *mysqlctl.Mycnf
	var socketFile string
	// If no connection parameters were specified, load the mycnf file
	// and use the socket from it. If connection parameters were specified,
	// we assume that the mysql is not local, and we skip loading mycnf.
	// This also means that backup and restore will not be allowed.
	if !dbconfigs.HasConnectionParams() {
		var err error
		if mycnf, err = mysqlctl.NewMycnfFromFlags(tabletAlias.Uid); err != nil {
			log.Exitf("mycnf read failed: %v", err)
		}
		socketFile = mycnf.SocketFile
	} else {
		log.Info("connection parameters were specified. Not loading my.cnf.")
	}

	// If connection parameters were specified, socketFile will be empty.
	// Otherwise, the socketFile (read from mycnf) will be used to initialize
	// dbconfigs.
	dbcfgs, err := dbconfigs.Init(socketFile)
	if err != nil {
		log.Warning(err)
	}

	if *tableACLConfig != "" {
		// To override default simpleacl, other ACL plugins must set themselves to be default ACL factory
		tableacl.Register("simpleacl", &simpleacl.Factory{})
	} else if *enforceTableACLConfig {
		log.Exit("table acl config has to be specified with table-acl-config flag because enforce-tableacl-config is set.")
	}

	// creates and registers the query service
	ts := topo.Open()
	qsc := tabletserver.NewServer(ts, *tabletAlias)
	servenv.OnRun(func() {
		qsc.Register()
		addStatusParts(qsc)
	})
	servenv.OnClose(func() {
		// We now leave the queryservice running during lameduck,
		// so stop it in OnClose(), after lameduck is over.
		qsc.StopService()
	})

	qsc.InitACL(*tableACLConfig, *enforceTableACLConfig)

	// Create mysqld and register the health reporter (needs to be done
	// before initializing the agent, so the initial health check
	// done by the agent has the right reporter)
	mysqld := mysqlctl.NewMysqld(dbcfgs)
	servenv.OnClose(mysqld.Close)

	// Depends on both query and updateStream.
	gRPCPort := int32(0)
	if servenv.GRPCPort != nil {
		gRPCPort = int32(*servenv.GRPCPort)
	}
	agent, err = tabletmanager.NewActionAgent(context.Background(), ts, mysqld, qsc, tabletAlias, dbcfgs, mycnf, int32(*servenv.Port), gRPCPort)
	if err != nil {
		log.Exitf("NewActionAgent() failed: %v", err)
	}

	servenv.OnClose(func() {
		// stop the agent so that our topo entry gets pruned properly
		agent.Close()

		// We will still use the topo server during lameduck period
		// to update our state, so closing it in OnClose()
		ts.Close()
	})

	servenv.RunDefault()
}
<commit_msg>Make it clear which flag is missing in the error msg.<commit_after>/*
Copyright 2017 Google 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.
*/

// vt tablet server: Serves queries and performs housekeeping jobs.
package main

import (
	"flag"

	"golang.org/x/net/context"
	"vitess.io/vitess/go/vt/dbconfigs"
	"vitess.io/vitess/go/vt/log"
	"vitess.io/vitess/go/vt/mysqlctl"
	"vitess.io/vitess/go/vt/servenv"
	"vitess.io/vitess/go/vt/tableacl"
	"vitess.io/vitess/go/vt/tableacl/simpleacl"
	"vitess.io/vitess/go/vt/topo"
	"vitess.io/vitess/go/vt/topo/topoproto"
	"vitess.io/vitess/go/vt/vttablet/tabletmanager"
	"vitess.io/vitess/go/vt/vttablet/tabletserver"
	"vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv"
)

var (
	enforceTableACLConfig = flag.Bool("enforce-tableacl-config", false, "if this flag is true, vttablet will fail to start if a valid tableacl config does not exist")
	tableACLConfig        = flag.String("table-acl-config", "", "path to table access checker config file; send SIGHUP to reload this file")
	tabletPath            = flag.String("tablet-path", "", "tablet alias")

	agent *tabletmanager.ActionAgent
)

func init() {
	servenv.RegisterDefaultFlags()
}

func main() {
	dbconfigs.RegisterFlags(dbconfigs.All...)
	mysqlctl.RegisterFlags()

	servenv.ParseFlags("vttablet")

	if err := tabletenv.VerifyConfig(); err != nil {
		log.Exitf("invalid config: %v", err)
	}

	tabletenv.Init()

	servenv.Init()

	if *tabletPath == "" {
		log.Exit("-tablet-path required")
	}
	tabletAlias, err := topoproto.ParseTabletAlias(*tabletPath)
	if err != nil {
		log.Exitf("failed to parse -tablet-path: %v", err)
	}

	var mycnf *mysqlctl.Mycnf
	var socketFile string
	// If no connection parameters were specified, load the mycnf file
	// and use the socket from it. If connection parameters were specified,
	// we assume that the mysql is not local, and we skip loading mycnf.
	// This also means that backup and restore will not be allowed.
	if !dbconfigs.HasConnectionParams() {
		var err error
		if mycnf, err = mysqlctl.NewMycnfFromFlags(tabletAlias.Uid); err != nil {
			log.Exitf("mycnf read failed: %v", err)
		}
		socketFile = mycnf.SocketFile
	} else {
		log.Info("connection parameters were specified. Not loading my.cnf.")
	}

	// If connection parameters were specified, socketFile will be empty.
	// Otherwise, the socketFile (read from mycnf) will be used to initialize
	// dbconfigs.
	dbcfgs, err := dbconfigs.Init(socketFile)
	if err != nil {
		log.Warning(err)
	}

	if *tableACLConfig != "" {
		// To override default simpleacl, other ACL plugins must set themselves to be default ACL factory
		tableacl.Register("simpleacl", &simpleacl.Factory{})
	} else if *enforceTableACLConfig {
		log.Exit("table acl config has to be specified with table-acl-config flag because enforce-tableacl-config is set.")
	}

	// creates and registers the query service
	ts := topo.Open()
	qsc := tabletserver.NewServer(ts, *tabletAlias)
	servenv.OnRun(func() {
		qsc.Register()
		addStatusParts(qsc)
	})
	servenv.OnClose(func() {
		// We now leave the queryservice running during lameduck,
		// so stop it in OnClose(), after lameduck is over.
		qsc.StopService()
	})

	qsc.InitACL(*tableACLConfig, *enforceTableACLConfig)

	// Create mysqld and register the health reporter (needs to be done
	// before initializing the agent, so the initial health check
	// done by the agent has the right reporter)
	mysqld := mysqlctl.NewMysqld(dbcfgs)
	servenv.OnClose(mysqld.Close)

	// Depends on both query and updateStream.
	gRPCPort := int32(0)
	if servenv.GRPCPort != nil {
		gRPCPort = int32(*servenv.GRPCPort)
	}
	agent, err = tabletmanager.NewActionAgent(context.Background(), ts, mysqld, qsc, tabletAlias, dbcfgs, mycnf, int32(*servenv.Port), gRPCPort)
	if err != nil {
		log.Exitf("NewActionAgent() failed: %v", err)
	}

	servenv.OnClose(func() {
		// stop the agent so that our topo entry gets pruned properly
		agent.Close()

		// We will still use the topo server during lameduck period
		// to update our state, so closing it in OnClose()
		ts.Close()
	})

	servenv.RunDefault()
}
<|endoftext|>