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

package cli

import (
	"crypto/tls"
	"fmt"
	"net/http"
	"net/url"
	"os"
	"path"
	"time"

	"github.com/go-openapi/strfmt"
	"github.com/prometheus/common/version"
	"golang.org/x/mod/semver"
	kingpin "gopkg.in/alecthomas/kingpin.v2"

	"github.com/prometheus/alertmanager/api/v2/client"
	"github.com/prometheus/alertmanager/cli/config"
	"github.com/prometheus/alertmanager/cli/format"

	clientruntime "github.com/go-openapi/runtime/client"
)

var (
	verbose               bool
	alertmanagerURL       *url.URL
	output                string
	timeout               time.Duration
	tlsInsecureSkipVerify bool
	versionCheck          bool

	configFiles = []string{os.ExpandEnv("$HOME/.config/amtool/config.yml"), "/etc/amtool/config.yml"}
	legacyFlags = map[string]string{"comment_required": "require-comment"}
)

func requireAlertManagerURL(pc *kingpin.ParseContext) error {
	// Return without error if any help flag is set.
	for _, elem := range pc.Elements {
		f, ok := elem.Clause.(*kingpin.FlagClause)
		if !ok {
			continue
		}
		name := f.Model().Name
		if name == "help" || name == "help-long" || name == "help-man" {
			return nil
		}
	}
	if alertmanagerURL == nil {
		kingpin.Fatalf("required flag --alertmanager.url not provided")
	}
	return nil
}

const (
	defaultAmHost      = "localhost"
	defaultAmPort      = "9093"
	defaultAmApiv2path = "/api/v2"
)

// NewAlertmanagerClient initializes an alertmanager client with the given URL
func NewAlertmanagerClient(amURL *url.URL) *client.Alertmanager {
	address := defaultAmHost + ":" + defaultAmPort
	schemes := []string{"http"}

	if amURL.Host != "" {
		address = amURL.Host // URL documents host as host or host:port
	}
	if amURL.Scheme != "" {
		schemes = []string{amURL.Scheme}
	}

	cr := clientruntime.New(address, path.Join(amURL.Path, defaultAmApiv2path), schemes)

	if tlsInsecureSkipVerify {
		transport := http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		}
		cr.Transport = &transport
	}

	if amURL.User != nil {
		password, _ := amURL.User.Password()
		cr.DefaultAuthentication = clientruntime.BasicAuth(amURL.User.Username(), password)
	}

	c := client.New(cr, strfmt.Default)

	if !versionCheck {
		return c
	}

	status, err := c.General.GetStatus(nil)
	if err != nil || status.Payload.VersionInfo == nil || version.Version == "" {
		// We can not get version info, or we do not know our own version. Let amtool continue.
		return c
	}

	if semver.MajorMinor("v"+*status.Payload.VersionInfo.Version) != semver.MajorMinor("v"+version.Version) {
		fmt.Fprintf(os.Stderr, "Warning: amtool version (%s) and alertmanager version (%s) are different.\n", version.Version, *status.Payload.VersionInfo.Version)
	}

	return c
}

// Execute is the main function for the amtool command
func Execute() {
	var (
		app = kingpin.New("amtool", helpRoot).UsageWriter(os.Stdout)
	)

	format.InitFormatFlags(app)

	app.Flag("verbose", "Verbose running information").Short('v').BoolVar(&verbose)
	app.Flag("alertmanager.url", "Alertmanager to talk to").URLVar(&alertmanagerURL)
	app.Flag("output", "Output formatter (simple, extended, json)").Short('o').Default("simple").EnumVar(&output, "simple", "extended", "json")
	app.Flag("timeout", "Timeout for the executed command").Default("30s").DurationVar(&timeout)
	app.Flag("tls.insecure.skip.verify", "Skip TLS certificate verification").BoolVar(&tlsInsecureSkipVerify)
	app.Flag("version-check", "Check alertmanager version. Use --no-version-check to disable.").Default("true").BoolVar(&versionCheck)

	app.Version(version.Print("amtool"))
	app.GetFlag("help").Short('h')
	app.UsageTemplate(kingpin.CompactUsageTemplate)

	resolver, err := config.NewResolver(configFiles, legacyFlags)
	if err != nil {
		kingpin.Fatalf("could not load config file: %v\n", err)
	}

	configureAlertCmd(app)
	configureSilenceCmd(app)
	configureCheckConfigCmd(app)
	configureClusterCmd(app)
	configureConfigCmd(app)
	configureTemplateCmd(app)

	err = resolver.Bind(app, os.Args[1:])
	if err != nil {
		kingpin.Fatalf("%v\n", err)
	}

	_, err = app.Parse(os.Args[1:])
	if err != nil {
		kingpin.Fatalf("%v\n", err)
	}
}

const (
	helpRoot = `View and modify the current Alertmanager state.

Config File:
The alertmanager tool will read a config file in YAML format from one of two
default config locations: $HOME/.config/amtool/config.yml or
/etc/amtool/config.yml

All flags can be given in the config file, but the following are the suited for
static configuration:

	alertmanager.url
		Set a default alertmanager url for each request

	author
		Set a default author value for new silences. If this argument is not
		specified then the username will be used

	require-comment
		Bool, whether to require a comment on silence creation. Defaults to true

	output
		Set a default output type. Options are (simple, extended, json)

	date.format
		Sets the output format for dates. Defaults to "2006-01-02 15:04:05 MST"

	tls.insecure.skip.verify
		Skips TLS certificate verification for all HTTPS requests.
		Defaults to false.
`
)
<commit_msg>Add client TLS configuration<commit_after>// Copyright 2018 Prometheus Team
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cli

import (
	"crypto/tls"
	"fmt"
	"net/http"
	"net/url"
	"os"
	"path"
	"time"

	"github.com/go-openapi/strfmt"
	promconfig "github.com/prometheus/common/config"
	"github.com/prometheus/common/version"
	"golang.org/x/mod/semver"
	kingpin "gopkg.in/alecthomas/kingpin.v2"

	"github.com/prometheus/alertmanager/api/v2/client"
	"github.com/prometheus/alertmanager/cli/config"
	"github.com/prometheus/alertmanager/cli/format"

	clientruntime "github.com/go-openapi/runtime/client"
)

var (
	verbose         bool
	alertmanagerURL *url.URL
	output          string
	timeout         time.Duration
	tlsConfig       *tls.Config
	versionCheck    bool

	configFiles = []string{os.ExpandEnv("$HOME/.config/amtool/config.yml"), "/etc/amtool/config.yml"}
	legacyFlags = map[string]string{"comment_required": "require-comment"}
)

func requireAlertManagerURL(pc *kingpin.ParseContext) error {
	// Return without error if any help flag is set.
	for _, elem := range pc.Elements {
		f, ok := elem.Clause.(*kingpin.FlagClause)
		if !ok {
			continue
		}
		name := f.Model().Name
		if name == "help" || name == "help-long" || name == "help-man" {
			return nil
		}
	}
	if alertmanagerURL == nil {
		kingpin.Fatalf("required flag --alertmanager.url not provided")
	}
	return nil
}

const (
	defaultAmHost      = "localhost"
	defaultAmPort      = "9093"
	defaultAmApiv2path = "/api/v2"
)

// NewAlertmanagerClient initializes an alertmanager client with the given URL
func NewAlertmanagerClient(amURL *url.URL) *client.Alertmanager {
	address := defaultAmHost + ":" + defaultAmPort
	schemes := []string{"http"}

	if amURL.Host != "" {
		address = amURL.Host // URL documents host as host or host:port
	}
	if amURL.Scheme != "" {
		schemes = []string{amURL.Scheme}
	}

	cr := clientruntime.New(address, path.Join(amURL.Path, defaultAmApiv2path), schemes)

	cr.Transport = &http.Transport{
		TLSClientConfig: tlsConfig,
	}

	if amURL.User != nil {
		password, _ := amURL.User.Password()
		cr.DefaultAuthentication = clientruntime.BasicAuth(amURL.User.Username(), password)
	}

	c := client.New(cr, strfmt.Default)

	if !versionCheck {
		return c
	}

	status, err := c.General.GetStatus(nil)
	if err != nil || status.Payload.VersionInfo == nil || version.Version == "" {
		// We can not get version info, or we do not know our own version. Let amtool continue.
		return c
	}

	if semver.MajorMinor("v"+*status.Payload.VersionInfo.Version) != semver.MajorMinor("v"+version.Version) {
		fmt.Fprintf(os.Stderr, "Warning: amtool version (%s) and alertmanager version (%s) are different.\n", version.Version, *status.Payload.VersionInfo.Version)
	}

	return c
}

// Execute is the main function for the amtool command
func Execute() {
	var (
		app = kingpin.New("amtool", helpRoot).UsageWriter(os.Stdout)
		tls = promconfig.TLSConfig{}
	)

	format.InitFormatFlags(app)

	app.Flag("verbose", "Verbose running information").Short('v').BoolVar(&verbose)
	app.Flag("alertmanager.url", "Alertmanager to talk to").URLVar(&alertmanagerURL)
	app.Flag("output", "Output formatter (simple, extended, json)").Short('o').Default("simple").EnumVar(&output, "simple", "extended", "json")
	app.Flag("timeout", "Timeout for the executed command").Default("30s").DurationVar(&timeout)
	app.Flag("tls.certfile", "TLS client certificate file").PlaceHolder("<filename>").ExistingFileVar(&tls.CertFile)
	app.Flag("tls.keyfile", "TLS client private key file").PlaceHolder("<filename>").ExistingFileVar(&tls.KeyFile)
	app.Flag("tls.cafile", "TLS trusted certificate authorities file").PlaceHolder("<filename>").ExistingFileVar(&tls.CAFile)
	app.Flag("tls.servername", "ServerName to verify hostname of alertmanager").PlaceHolder("<string>").StringVar(&tls.ServerName)
	app.Flag("tls.insecure.skip.verify", "Skip TLS certificate verification").Default("false").BoolVar(&tls.InsecureSkipVerify)
	app.Flag("version-check", "Check alertmanager version. Use --no-version-check to disable.").Default("true").BoolVar(&versionCheck)

	app.Version(version.Print("amtool"))
	app.GetFlag("help").Short('h')
	app.UsageTemplate(kingpin.CompactUsageTemplate)
	app.PreAction(func(pc *kingpin.ParseContext) (err error) {
		tlsConfig, err = promconfig.NewTLSConfig(&tls)
		return err
	})

	resolver, err := config.NewResolver(configFiles, legacyFlags)
	if err != nil {
		kingpin.Fatalf("could not load config file: %v\n", err)
	}

	configureAlertCmd(app)
	configureSilenceCmd(app)
	configureCheckConfigCmd(app)
	configureClusterCmd(app)
	configureConfigCmd(app)
	configureTemplateCmd(app)

	err = resolver.Bind(app, os.Args[1:])
	if err != nil {
		kingpin.Fatalf("%v\n", err)
	}

	_, err = app.Parse(os.Args[1:])
	if err != nil {
		kingpin.Fatalf("%v\n", err)
	}
}

const (
	helpRoot = `View and modify the current Alertmanager state.

Config File:
The alertmanager tool will read a config file in YAML format from one of two
default config locations: $HOME/.config/amtool/config.yml or
/etc/amtool/config.yml

All flags can be given in the config file, but the following are the suited for
static configuration:

	alertmanager.url
		Set a default alertmanager url for each request

	author
		Set a default author value for new silences. If this argument is not
		specified then the username will be used

	require-comment
		Bool, whether to require a comment on silence creation. Defaults to true

	output
		Set a default output type. Options are (simple, extended, json)

	date.format
		Sets the output format for dates. Defaults to "2006-01-02 15:04:05 MST"

	tls.certfile
		TLS client certificate file for mutual-TLS authentication.
		Requires tls.keyfile to be useful.

	tls.keyfile
		TLS client private key file for mutual-TLS authentication.
		Requires tls.certfile to be useful.

	tls.cafile
		TLS trusted certificate authorities file.

	tls.servername
		ServerName to verify hostname of alertmanager.

	tls.insecure.skip.verify
		Skips TLS certificate verification for all HTTPS requests.
		Defaults to false.
`
)
<|endoftext|>


<commit_before>// Package cloudlog provides a CloudLog client library
package cloudlog

import (
	"crypto/tls"
	"encoding/json"

	"time"

	"sync"

	"github.com/Shopify/sarama"
	"github.com/hashicorp/go-multierror"
)

// CloudLog is the CloudLog object to send logs
type CloudLog struct {
	brokers       []string
	tlsConfig     *tls.Config
	producerMutex sync.RWMutex
	producer      sarama.SyncProducer
	saramaConfig  sarama.Config
	indexName     string
	sourceHost    string
	eventEncoder  EventEncoder
}

// NewCloudLog initializes a new CloudLog instance
func NewCloudLog(indexName string, options ...Option) (cl *CloudLog, err error) {
	if indexName == "" {
		err = ErrIndexNotDefined
		return
	}

	cl = &CloudLog{
		tlsConfig: &tls.Config{},
		indexName: indexName,
	}

	// When returning an error ensure that we return a nil value as *CloudLog
	defer func() {
		if err != nil {
			cl = nil
		}
	}()

	// Apply all options, default options first
	options = append(defaultOptions, options...)
	for _, opt := range options {
		if optErr := opt(cl); optErr != nil {
			err = multierror.Append(err, optErr)
		}
	}

	// At least one option caused an error, bail out
	if err != nil {
		return
	}

	// Enforce TLS and the specific kafka version
	cl.saramaConfig.Version = sarama.V0_10_2_0
	cl.saramaConfig.Net.TLS.Enable = true
	cl.saramaConfig.Net.TLS.Config = cl.tlsConfig

	return
}

// InitCloudLog validates and initalizes the CloudLog client
func InitCloudLog(index string, ca string, cert string, key string) (*CloudLog, error) {
	return NewCloudLog(index, OptionCACertificateFile(ca), OptionClientCertificateFile(cert, key))
}

func (cl *CloudLog) getProducer() (sarama.SyncProducer, error) {
	var err error
	cl.producerMutex.RLock()
	defer cl.producerMutex.RUnlock()
	if cl.producer == nil {
		// Connection not yet established, establish connections now

		// First drop the rlock and obtain a wlock
		cl.producerMutex.RUnlock()
		cl.producerMutex.Lock()

		// Ensure that we drop the wlock again and obtain the rlock before returning,
		// so the deferred runlock will not cause a panic
		defer func() {
			cl.producerMutex.Unlock()
			cl.producerMutex.RLock()
		}()
		cl.producer, err = sarama.NewSyncProducer(cl.brokers, &cl.saramaConfig)
	}

	return cl.producer, err
}

// Close closes the connection
func (cl *CloudLog) Close() (err error) {
	cl.producerMutex.Lock()
	defer cl.producerMutex.Unlock()

	// Close should be a no-op if no connection has been established
	if cl.producer != nil {
		err = cl.producer.Close()
		cl.producer = nil
	}
	return
}

// PushEvents sends the supplied events to CloudLog
func (cl *CloudLog) PushEvents(event interface{}, events ...interface{}) (err error) {
	events = append([]interface{}{event}, events...)

	// Get the producer. This will lazily establish the connection on the first call
	var producer sarama.SyncProducer
	if producer, err = cl.getProducer(); err != nil {
		return
	}

	now := time.Now()
	// Encode the events
	messages := make([]*sarama.ProducerMessage, len(events))
	for i, ev := range events {
		var eventMap map[string]interface{}
		if eventMap, err = cl.eventEncoder.EncodeEvent(ev); err != nil {
			return err
		}

		eventMap["timestamp"] = now.String()
		eventMap["cloudlog_source_host"] = cl.sourceHost
		eventMap["cloudlog_client_type"] = "go-client"

		var eventData []byte
		eventData, err = json.Marshal(eventMap)
		if err != nil {
			return NewMarshalError(eventMap, err)
		}

		messages[i] = &sarama.ProducerMessage{
			Topic:     cl.indexName,
			Value:     sarama.StringEncoder(eventData),
			Timestamp: now,
		}
	}

	return producer.SendMessages(messages)
}

// PushEvent sends an event to CloudLog
func (cl *CloudLog) PushEvent(event interface{}) error {
	return cl.PushEvents(event)
}
<commit_msg>Fix typo in docstring<commit_after>// Package cloudlog provides a CloudLog client library
package cloudlog

import (
	"crypto/tls"
	"encoding/json"

	"time"

	"sync"

	"github.com/Shopify/sarama"
	"github.com/hashicorp/go-multierror"
)

// CloudLog is the CloudLog object to send logs
type CloudLog struct {
	brokers       []string
	tlsConfig     *tls.Config
	producerMutex sync.RWMutex
	producer      sarama.SyncProducer
	saramaConfig  sarama.Config
	indexName     string
	sourceHost    string
	eventEncoder  EventEncoder
}

// NewCloudLog initializes a new CloudLog instance
func NewCloudLog(indexName string, options ...Option) (cl *CloudLog, err error) {
	if indexName == "" {
		err = ErrIndexNotDefined
		return
	}

	cl = &CloudLog{
		tlsConfig: &tls.Config{},
		indexName: indexName,
	}

	// When returning an error ensure that we return a nil value as *CloudLog
	defer func() {
		if err != nil {
			cl = nil
		}
	}()

	// Apply all options, default options first
	options = append(defaultOptions, options...)
	for _, opt := range options {
		if optErr := opt(cl); optErr != nil {
			err = multierror.Append(err, optErr)
		}
	}

	// At least one option caused an error, bail out
	if err != nil {
		return
	}

	// Enforce TLS and the specific kafka version
	cl.saramaConfig.Version = sarama.V0_10_2_0
	cl.saramaConfig.Net.TLS.Enable = true
	cl.saramaConfig.Net.TLS.Config = cl.tlsConfig

	return
}

// InitCloudLog validates and initializes the CloudLog client
func InitCloudLog(index string, ca string, cert string, key string) (*CloudLog, error) {
	return NewCloudLog(index, OptionCACertificateFile(ca), OptionClientCertificateFile(cert, key))
}

func (cl *CloudLog) getProducer() (sarama.SyncProducer, error) {
	var err error
	cl.producerMutex.RLock()
	defer cl.producerMutex.RUnlock()
	if cl.producer == nil {
		// Connection not yet established, establish connections now

		// First drop the rlock and obtain a wlock
		cl.producerMutex.RUnlock()
		cl.producerMutex.Lock()

		// Ensure that we drop the wlock again and obtain the rlock before returning,
		// so the deferred runlock will not cause a panic
		defer func() {
			cl.producerMutex.Unlock()
			cl.producerMutex.RLock()
		}()
		cl.producer, err = sarama.NewSyncProducer(cl.brokers, &cl.saramaConfig)
	}

	return cl.producer, err
}

// Close closes the connection
func (cl *CloudLog) Close() (err error) {
	cl.producerMutex.Lock()
	defer cl.producerMutex.Unlock()

	// Close should be a no-op if no connection has been established
	if cl.producer != nil {
		err = cl.producer.Close()
		cl.producer = nil
	}
	return
}

// PushEvents sends the supplied events to CloudLog
func (cl *CloudLog) PushEvents(event interface{}, events ...interface{}) (err error) {
	events = append([]interface{}{event}, events...)

	// Get the producer. This will lazily establish the connection on the first call
	var producer sarama.SyncProducer
	if producer, err = cl.getProducer(); err != nil {
		return
	}

	now := time.Now()
	// Encode the events
	messages := make([]*sarama.ProducerMessage, len(events))
	for i, ev := range events {
		var eventMap map[string]interface{}
		if eventMap, err = cl.eventEncoder.EncodeEvent(ev); err != nil {
			return err
		}

		eventMap["timestamp"] = now.String()
		eventMap["cloudlog_source_host"] = cl.sourceHost
		eventMap["cloudlog_client_type"] = "go-client"

		var eventData []byte
		eventData, err = json.Marshal(eventMap)
		if err != nil {
			return NewMarshalError(eventMap, err)
		}

		messages[i] = &sarama.ProducerMessage{
			Topic:     cl.indexName,
			Value:     sarama.StringEncoder(eventData),
			Timestamp: now,
		}
	}

	return producer.SendMessages(messages)
}

// PushEvent sends an event to CloudLog
func (cl *CloudLog) PushEvent(event interface{}) error {
	return cl.PushEvents(event)
}
<|endoftext|>


<commit_before>package persist

import (
	"time"

	"github.com/NebulousLabs/bolt"
)

// BoltDatabase is a persist-level wrapper for the bolt database, providing
// extra information such as a version number.
type BoltDatabase struct {
	Metadata
	*bolt.DB
}

// updateDbMetadata will set the contents of the metadata bucket to be
// what is stored inside the metadata argument
func (db *BoltDatabase) updateMetadata(tx *bolt.Tx) error {
	bucket, err := tx.CreateBucketIfNotExists([]byte("Metadata"))
	if err != nil {
		return err
	}
	err = bucket.Put([]byte("Header"), []byte(db.Header))
	if err != nil {
		return err
	}
	err = bucket.Put([]byte("Version"), []byte(db.Version))
	if err != nil {
		return err
	}
	return nil
}

// checkDbMetadata confirms that the metadata in the database is
// correct. If there is no metadata, correct metadata is inserted
func (db *BoltDatabase) checkMetadata(md Metadata) error {
	err := db.Update(func(tx *bolt.Tx) error {
		// Check if the database has metadata. If not, create metadata for the
		// database.
		bucket := tx.Bucket([]byte("Metadata"))
		if bucket == nil {
			err := db.updateMetadata(tx)
			if err != nil {
				return err
			}
			return nil
		}

		// Verify that the metadata matches the expected metadata.
		header := bucket.Get([]byte("Header"))
		if string(header) != md.Header {
			return ErrBadHeader
		}
		version := bucket.Get([]byte("Version"))
		if string(version) != md.Version {
			return ErrBadVersion
		}
		return nil
	})
	return err
}

// CloseDatabase saves the bolt database to a file, and updates metadata
func (db *BoltDatabase) CloseDatabase() error {
	db.Close()
	return nil
}

// OpenDatabase opens a database filename and checks metadata
func OpenDatabase(md Metadata, filename string) (*BoltDatabase, error) {
	// Open the database using a 1 second timeout (without the timeout,
	// database will potentially hang indefinitely.
	db, err := bolt.Open(filename, 0600, &bolt.Options{Timeout: 3 * time.Second})
	if err != nil {
		return nil, err
	}

	boltDB := &BoltDatabase{
		Metadata: md,
		DB:       db,
	}
	err = boltDB.checkMetadata(md)
	if err != nil {
		return nil, err
	}
	return boltDB, nil
}
<commit_msg>rename CloseDatabase() to Close()<commit_after>package persist

import (
	"time"

	"github.com/NebulousLabs/bolt"
)

// BoltDatabase is a persist-level wrapper for the bolt database, providing
// extra information such as a version number.
type BoltDatabase struct {
	Metadata
	*bolt.DB
}

// updateDbMetadata will set the contents of the metadata bucket to be
// what is stored inside the metadata argument
func (db *BoltDatabase) updateMetadata(tx *bolt.Tx) error {
	bucket, err := tx.CreateBucketIfNotExists([]byte("Metadata"))
	if err != nil {
		return err
	}
	err = bucket.Put([]byte("Header"), []byte(db.Header))
	if err != nil {
		return err
	}
	err = bucket.Put([]byte("Version"), []byte(db.Version))
	if err != nil {
		return err
	}
	return nil
}

// checkDbMetadata confirms that the metadata in the database is
// correct. If there is no metadata, correct metadata is inserted
func (db *BoltDatabase) checkMetadata(md Metadata) error {
	err := db.Update(func(tx *bolt.Tx) error {
		// Check if the database has metadata. If not, create metadata for the
		// database.
		bucket := tx.Bucket([]byte("Metadata"))
		if bucket == nil {
			err := db.updateMetadata(tx)
			if err != nil {
				return err
			}
			return nil
		}

		// Verify that the metadata matches the expected metadata.
		header := bucket.Get([]byte("Header"))
		if string(header) != md.Header {
			return ErrBadHeader
		}
		version := bucket.Get([]byte("Version"))
		if string(version) != md.Version {
			return ErrBadVersion
		}
		return nil
	})
	return err
}

// CloseDatabase saves the bolt database to a file, and updates metadata
func (db *BoltDatabase) Close() error {
	return db.DB.Close()
}

// OpenDatabase opens a database filename and checks metadata
func OpenDatabase(md Metadata, filename string) (*BoltDatabase, error) {
	// Open the database using a 1 second timeout (without the timeout,
	// database will potentially hang indefinitely.
	db, err := bolt.Open(filename, 0600, &bolt.Options{Timeout: 3 * time.Second})
	if err != nil {
		return nil, err
	}

	boltDB := &BoltDatabase{
		Metadata: md,
		DB:       db,
	}
	err = boltDB.checkMetadata(md)
	if err != nil {
		return nil, err
	}
	return boltDB, nil
}
<|endoftext|>


<commit_before>// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package cmd

import (
	"bufio"
	"bytes"
	"os"
	"os/exec"
	"path/filepath"

	"github.com/urfave/cli"

	"github.com/gogits/gogs/models"
)

var (
	CmdHook = cli.Command{
		Name:        "hook",
		Usage:       "Delegate commands to corresponding Git hooks",
		Description: "All sub-commands should only be called by Git",
		Flags: []cli.Flag{
			stringFlag("config, c", "custom/conf/app.ini", "Custom configuration file path"),
		},
		Subcommands: []cli.Command{
			subcmdHookPreReceive,
			subcmdHookUpadte,
			subcmdHookPostReceive,
		},
	}

	subcmdHookPreReceive = cli.Command{
		Name:        "pre-receive",
		Usage:       "Delegate pre-receive Git hook",
		Description: "This command should only be called by Git",
		Action:      runHookPreReceive,
	}
	subcmdHookUpadte = cli.Command{
		Name:        "update",
		Usage:       "Delegate update Git hook",
		Description: "This command should only be called by Git",
		Action:      runHookUpdate,
	}
	subcmdHookPostReceive = cli.Command{
		Name:        "post-receive",
		Usage:       "Delegate post-receive Git hook",
		Description: "This command should only be called by Git",
		Action:      runHookPostReceive,
	}
)

func runHookPreReceive(c *cli.Context) error {
	if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
		return nil
	}
	setup(c, "hooks/pre-receive.log")

	buf := bytes.NewBuffer(nil)
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		buf.Write(scanner.Bytes())
		buf.WriteByte('\n')
	}

	customHooksPath := os.Getenv(_ENV_REPO_CUSTOM_HOOKS_PATH)
	hookCmd := exec.Command(filepath.Join(customHooksPath, "pre-receive"))
	hookCmd.Stdout = os.Stdout
	hookCmd.Stdin = buf
	hookCmd.Stderr = os.Stderr
	if err := hookCmd.Run(); err != nil {
		fail("Internal error", "Fail to execute custom pre-receive hook: %v", err)
	}
	return nil
}

func runHookUpdate(c *cli.Context) error {
	if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
		return nil
	}
	setup(c, "hooks/update.log")

	args := c.Args()
	if len(args) != 3 {
		fail("Arguments received are not equal to three", "Arguments received are not equal to three")
	} else if len(args[0]) == 0 {
		fail("First argument 'refName' is empty", "First argument 'refName' is empty")
	}

	uuid := os.Getenv(_ENV_UPDATE_TASK_UUID)
	if err := models.AddUpdateTask(&models.UpdateTask{
		UUID:        uuid,
		RefName:     args[0],
		OldCommitID: args[1],
		NewCommitID: args[2],
	}); err != nil {
		fail("Internal error", "Fail to add update task '%s': %v", uuid, err)
	}

	customHooksPath := os.Getenv(_ENV_REPO_CUSTOM_HOOKS_PATH)
	hookCmd := exec.Command(filepath.Join(customHooksPath, "update"), args...)
	hookCmd.Stdout = os.Stdout
	hookCmd.Stdin = os.Stdin
	hookCmd.Stderr = os.Stderr
	if err := hookCmd.Run(); err != nil {
		fail("Internal error", "Fail to execute custom pre-receive hook: %v", err)
	}
	return nil
}

func runHookPostReceive(c *cli.Context) error {
	if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
		return nil
	}
	setup(c, "hooks/post-receive.log")

	customHooksPath := os.Getenv(_ENV_REPO_CUSTOM_HOOKS_PATH)
	hookCmd := exec.Command(filepath.Join(customHooksPath, "post-receive"))
	hookCmd.Stdout = os.Stdout
	hookCmd.Stdin = os.Stdin
	hookCmd.Stderr = os.Stderr
	if err := hookCmd.Run(); err != nil {
		fail("Internal error", "Fail to execute custom post-receive hook: %v", err)
	}
	return nil
}
<commit_msg>cmd/hook: check existence before call custom hook<commit_after>// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package cmd

import (
	"bufio"
	"bytes"
	"os"
	"os/exec"
	"path/filepath"

	"github.com/Unknwon/com"
	"github.com/urfave/cli"

	"github.com/gogits/gogs/models"
)

var (
	CmdHook = cli.Command{
		Name:        "hook",
		Usage:       "Delegate commands to corresponding Git hooks",
		Description: "All sub-commands should only be called by Git",
		Flags: []cli.Flag{
			stringFlag("config, c", "custom/conf/app.ini", "Custom configuration file path"),
		},
		Subcommands: []cli.Command{
			subcmdHookPreReceive,
			subcmdHookUpadte,
			subcmdHookPostReceive,
		},
	}

	subcmdHookPreReceive = cli.Command{
		Name:        "pre-receive",
		Usage:       "Delegate pre-receive Git hook",
		Description: "This command should only be called by Git",
		Action:      runHookPreReceive,
	}
	subcmdHookUpadte = cli.Command{
		Name:        "update",
		Usage:       "Delegate update Git hook",
		Description: "This command should only be called by Git",
		Action:      runHookUpdate,
	}
	subcmdHookPostReceive = cli.Command{
		Name:        "post-receive",
		Usage:       "Delegate post-receive Git hook",
		Description: "This command should only be called by Git",
		Action:      runHookPostReceive,
	}
)

func runHookPreReceive(c *cli.Context) error {
	if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
		return nil
	}
	setup(c, "hooks/pre-receive.log")

	buf := bytes.NewBuffer(nil)
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		buf.Write(scanner.Bytes())
		buf.WriteByte('\n')
	}

	customHooksPath := os.Getenv(_ENV_REPO_CUSTOM_HOOKS_PATH)
	if !com.IsFile(customHooksPath) {
		return nil
	}

	hookCmd := exec.Command(filepath.Join(customHooksPath, "pre-receive"))
	hookCmd.Stdout = os.Stdout
	hookCmd.Stdin = buf
	hookCmd.Stderr = os.Stderr
	if err := hookCmd.Run(); err != nil {
		fail("Internal error", "Fail to execute custom pre-receive hook: %v", err)
	}
	return nil
}

func runHookUpdate(c *cli.Context) error {
	if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
		return nil
	}
	setup(c, "hooks/update.log")

	args := c.Args()
	if len(args) != 3 {
		fail("Arguments received are not equal to three", "Arguments received are not equal to three")
	} else if len(args[0]) == 0 {
		fail("First argument 'refName' is empty", "First argument 'refName' is empty")
	}

	uuid := os.Getenv(_ENV_UPDATE_TASK_UUID)
	if err := models.AddUpdateTask(&models.UpdateTask{
		UUID:        uuid,
		RefName:     args[0],
		OldCommitID: args[1],
		NewCommitID: args[2],
	}); err != nil {
		fail("Internal error", "Fail to add update task '%s': %v", uuid, err)
	}

	customHooksPath := os.Getenv(_ENV_REPO_CUSTOM_HOOKS_PATH)
	if !com.IsFile(customHooksPath) {
		return nil
	}

	hookCmd := exec.Command(filepath.Join(customHooksPath, "update"), args...)
	hookCmd.Stdout = os.Stdout
	hookCmd.Stdin = os.Stdin
	hookCmd.Stderr = os.Stderr
	if err := hookCmd.Run(); err != nil {
		fail("Internal error", "Fail to execute custom pre-receive hook: %v", err)
	}
	return nil
}

func runHookPostReceive(c *cli.Context) error {
	if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
		return nil
	}
	setup(c, "hooks/post-receive.log")

	customHooksPath := os.Getenv(_ENV_REPO_CUSTOM_HOOKS_PATH)
	if !com.IsFile(customHooksPath) {
		return nil
	}

	hookCmd := exec.Command(filepath.Join(customHooksPath, "post-receive"))
	hookCmd.Stdout = os.Stdout
	hookCmd.Stdin = os.Stdin
	hookCmd.Stderr = os.Stderr
	if err := hookCmd.Run(); err != nil {
		fail("Internal error", "Fail to execute custom post-receive hook: %v", err)
	}
	return nil
}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"
	builtin "github.com/hivdb/nucamino/alignmentprofile/builtin"
	"github.com/spf13/cobra"
	"log"
	"os"
	"regexp"
)

// listCmd represents the list command
var listCmd = &cobra.Command{
	Use:   "list [pattern]",
	Short: "List available built-in alignment profiles",
	Long: `This command lists the available built-in alignment profiles. These
names can be passed to the align command to use the built-in profiles
when aligning sequences.

The pattern argument is used to filter the list. It's interpreted as a
regular expression. For example:

    nucamino profile list '^hiv'            List all profiles that start with 'hiv'
    nucamino profile list hiv               List all profiles that contain 'hiv' anywhere
    nucamino profile list '.*1[abc]$'       List all profiles end in 1a, 1b, or 1c
    nucamino profile list 'hcv1.'           List all profiles that match 'hcv1' followed by
                                            any other letter

See https://github.com/google/re2/wiki/Syntax for the exact details of
the regular expression syntax.`,
	Args: cobra.RangeArgs(0, 1),
	Run: func(cmd *cobra.Command, args []string) {
		profileNames := builtin.List()
		if len(args) == 1 {
			var pattern *regexp.Regexp
			patternSrc := args[0]
			pattern, err := regexp.Compile(patternSrc)
			if err != nil {
				log.Printf("Error in pattern: %v", err)
				os.Exit(1)
				return
			}
			matchingProfileNames := make([]string, 0, len(profileNames))
			for _, name := range profileNames {
				if pattern.MatchString(name) {
					matchingProfileNames = append(matchingProfileNames, name)
				}
			}
			profileNames = matchingProfileNames
		}
		for _, name := range profileNames {
			fmt.Println(name)
		}
	},
}

func init() {
	profileCmd.AddCommand(listCmd)
}
<commit_msg>Use cobra.Command.RunE to fail in cmd/list.go<commit_after>package cmd

import (
	"fmt"
	"github.com/hivdb/nucamino/alignmentprofile/builtin"
	"github.com/spf13/cobra"
	"log"
	"regexp"
)

// listCmd represents the list command
var listCmd = &cobra.Command{
	Use:   "list [pattern]",
	Short: "List available built-in alignment profiles",
	Long: `This command lists the available built-in alignment profiles. These
names can be passed to the align command to use the built-in profiles
when aligning sequences.

The pattern argument is used to filter the list. It's interpreted as a
regular expression. For example:

    nucamino profile list '^hiv'            List all profiles that start with 'hiv'
    nucamino profile list hiv               List all profiles that contain 'hiv' anywhere
    nucamino profile list '.*1[abc]$'       List all profiles end in 1a, 1b, or 1c
    nucamino profile list 'hcv1.'           List all profiles that match 'hcv1' followed by
                                            any other letter

See https://github.com/google/re2/wiki/Syntax for the exact details of
the regular expression syntax.`,
	Args: cobra.RangeArgs(0, 1),
	RunE: func(cmd *cobra.Command, args []string) error {
		profileNames := builtin.List()
		if len(args) == 1 {
			var pattern *regexp.Regexp
			patternSrc := args[0]
			pattern, err := regexp.Compile(patternSrc)
			if err != nil {
				log.Printf("Error in pattern: %v", err)
				return err
			}
			matchingProfileNames := make([]string, 0, len(profileNames))
			for _, name := range profileNames {
				if pattern.MatchString(name) {
					matchingProfileNames = append(matchingProfileNames, name)
				}
			}
			profileNames = matchingProfileNames
		}
		for _, name := range profileNames {
			fmt.Println(name)
		}
		return nil
	},
}

func init() {
	profileCmd.AddCommand(listCmd)
}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"

	"strings"

	"github.com/evandroflores/claimr/model"
	"github.com/evandroflores/claimr/utils"
	"github.com/shomali11/slacker"
	log "github.com/sirupsen/logrus"
)

func init() {
	Register("list", "List all containers.", list)
}

func list(request *slacker.Request, response slacker.ResponseWriter) {
	response.Typing()

	isDirect, msg := checkDirect(request.Event.Channel)
	if isDirect {
		response.Reply(msg.Error())
		return
	}

	containers, err := model.GetContainers(request.Event.Team, request.Event.Channel)

	if err != nil {
		response.Reply("Fail to list containers.")
		log.Error(err)
		return
	}

	if len(containers) == 0 {
		response.Reply("No containers to list.")
		return
	}

	containerList := []string{"Here is a list of containers for this channel:"}
	for _, container := range containers {
		line := fmt.Sprintf("`%s`\t%s %s", container.Name,
			utils.IfThenElse(container.InUseBy != "", "in use", "_available_"),
			utils.IfThenElse(container.InUseForReason != "", fmt.Sprintf("- %s", container.InUseForReason), ""),
		)
		containerList = append(containerList, line)
	}
	response.Reply(strings.Join(containerList, "\n"))
}
<commit_msg>Changing how to get event cmd.list<commit_after>package cmd

import (
	"fmt"

	"strings"

	"github.com/evandroflores/claimr/model"
	"github.com/evandroflores/claimr/utils"
	"github.com/shomali11/slacker"
	log "github.com/sirupsen/logrus"
)

func init() {
	Register("list", "List all containers.", list)
}

func list(request *slacker.Request, response slacker.ResponseWriter) {
	response.Typing()

	event := getEvent(request)
	isDirect, msg := checkDirect(event.Channel)
	if isDirect {
		response.Reply(msg.Error())
		return
	}

	containers, err := model.GetContainers(event.Team, event.Channel)

	if err != nil {
		response.Reply("Fail to list containers.")
		log.Error(err)
		return
	}

	if len(containers) == 0 {
		response.Reply("No containers to list.")
		return
	}

	containerList := []string{"Here is a list of containers for this channel:"}
	for _, container := range containers {
		line := fmt.Sprintf("`%s`\t%s %s", container.Name,
			utils.IfThenElse(container.InUseBy != "", "in use", "_available_"),
			utils.IfThenElse(container.InUseForReason != "", fmt.Sprintf("- %s", container.InUseForReason), ""),
		)
		containerList = append(containerList, line)
	}
	response.Reply(strings.Join(containerList, "\n"))
}
<|endoftext|>


<commit_before>package cmd

import (
	"context"
	"fmt"
	"os"
	"sort"
	"strconv"
	"sync"
	"text/tabwriter"

	"github.com/urfave/cli"

	"github.com/manifoldco/torus-cli/api"
	"github.com/manifoldco/torus-cli/apitypes"
	"github.com/manifoldco/torus-cli/config"
	"github.com/manifoldco/torus-cli/envelope"
	"github.com/manifoldco/torus-cli/errs"
	"github.com/manifoldco/torus-cli/hints"
	"github.com/manifoldco/torus-cli/identity"
	"github.com/manifoldco/torus-cli/primitive"
)

func init() {
	orgs := cli.Command{
		Name:     "orgs",
		Usage:    "View and create organizations",
		Category: "ORGANIZATIONS",
		Subcommands: []cli.Command{
			{
				Name:      "create",
				Usage:     "Create a new organization",
				ArgsUsage: "<name>",
				Action:    chain(ensureDaemon, ensureSession, orgsCreate),
			},
			{
				Name:   "list",
				Usage:  "List organizations associated with your account",
				Action: chain(ensureDaemon, ensureSession, orgsListCmd),
			},
			{
				Name:      "remove",
				Usage:     "Remove a user from an org",
				ArgsUsage: "<username>",
				Flags: []cli.Flag{
					orgFlag("org to remove the user from", true),
				},
				Action: chain(
					ensureDaemon, ensureSession, loadDirPrefs, loadPrefDefaults,
					setUserEnv, checkRequiredFlags, orgsRemove,
				),
			},
			{
				Name:  "members",
				Usage: "List all members in an org",
				Flags: []cli.Flag{
					orgFlag("Use this organization.", false),
				},
				Action: chain(
					ensureDaemon, ensureSession, loadDirPrefs, loadPrefDefaults,
					setUserEnv, checkRequiredFlags, orgsMembersListCmd,
				),
			},
		},
	}
	Cmds = append(Cmds, orgs)
}

const orgCreateFailed = "Org creation failed."

func orgsCreate(ctx *cli.Context) error {
	args := ctx.Args()
	if len(args) > 1 {
		return errs.NewUsageExitError("Too many arguments", ctx)
	}

	var name string
	var err error

	if len(args) == 1 {
		name = args[0]
	}

	label := "Org name"
	autoAccept := name != ""
	name, err = NamePrompt(&label, name, autoAccept)
	if err != nil {
		return handleSelectError(err, orgCreateFailed)
	}

	c := context.Background()

	cfg, err := config.LoadConfig()
	if err != nil {
		return errs.NewErrorExitError(orgCreateFailed, err)
	}

	client := api.NewClient(cfg)

	_, err = createOrgByName(c, ctx, client, name)
	if err != nil {
		return err
	}

	hints.Display(hints.InvitesSend, hints.Projects, hints.Link)
	return nil
}

func createOrgByName(c context.Context, ctx *cli.Context, client *api.Client, name string) (*envelope.Org, error) {
	org, err := client.Orgs.Create(c, name)
	if err != nil {
		return nil, errs.NewErrorExitError(orgCreateFailed, err)
	}

	err = generateKeypairsForOrg(c, ctx, client, org.ID, false)
	if err != nil {
		msg := fmt.Sprintf("Could not generate keypairs for org. Run '%s keypairs generate' to fix.", ctx.App.Name)
		return nil, errs.NewExitError(msg)
	}

	fmt.Println("Org " + org.Body.Name + " created.")
	return org, nil
}

func orgsListCmd(ctx *cli.Context) error {
	orgs, session, err := orgsList()
	if err != nil {
		return err
	}

	withoutPersonal := orgs

	if session.Type() == apitypes.UserSession {
		for i, o := range orgs {
			if o.Body.Name == session.Username() {
				fmt.Printf("  %s [personal]\n", o.Body.Name)
				withoutPersonal = append(orgs[:i], orgs[i+1:]...)
			}
		}
	}

	for _, o := range withoutPersonal {
		fmt.Printf("  %s\n", o.Body.Name)
	}

	return nil
}

func orgsList() ([]envelope.Org, *api.Session, error) {
	cfg, err := config.LoadConfig()
	if err != nil {
		return nil, nil, err
	}

	client := api.NewClient(cfg)

	var wg sync.WaitGroup
	wg.Add(2)

	var orgs []envelope.Org
	var session *api.Session
	var oErr, sErr error

	go func() {
		orgs, oErr = client.Orgs.List(context.Background())
		wg.Done()
	}()

	go func() {
		session, sErr = client.Session.Who(context.Background())
		wg.Done()
	}()

	wg.Wait()
	if oErr != nil || sErr != nil {
		return nil, nil, errs.NewExitError("Error fetching orgs list")
	}

	return orgs, session, nil
}

func orgsRemove(ctx *cli.Context) error {
	args := ctx.Args()
	if len(args) < 1 || args[0] == "" {
		return errs.NewUsageExitError("Missing username", ctx)
	}
	if len(args) > 1 {
		return errs.NewUsageExitError("Too many arguments", ctx)
	}
	username := args[0]

	cfg, err := config.LoadConfig()
	if err != nil {
		return err
	}

	client := api.NewClient(cfg)
	c := context.Background()

	const userNotFound = "User not found."
	const orgsRemoveFailed = "Could not remove user from the org."

	org, err := client.Orgs.GetByName(c, ctx.String("org"))
	if err != nil {
		return errs.NewErrorExitError(orgsRemoveFailed, err)
	}
	if org == nil {
		return errs.NewExitError("Org not found.")
	}

	profile, err := client.Profiles.ListByName(c, username)
	if apitypes.IsNotFoundError(err) {
		return errs.NewExitError(userNotFound)
	}
	if err != nil {
		return errs.NewErrorExitError(orgsRemoveFailed, err)
	}
	if profile == nil {
		return errs.NewExitError(userNotFound)
	}

	err = client.Orgs.RemoveMember(c, *org.ID, *profile.ID)
	if apitypes.IsNotFoundError(err) {
		fmt.Println("User is not a member of the org.")
		return nil
	}
	if err != nil {
		return errs.NewErrorExitError(orgsRemoveFailed, err)
	}

	fmt.Println("User has been removed from the org.")
	return nil
}

func orgsMembersListCmd(ctx *cli.Context) error {

	cfg, err := config.LoadConfig()
	if err != nil {
		return errs.NewExitError("Failed to load config.")
	}

	client := api.NewClient(cfg)
	c := context.Background()

	var org *envelope.Org
	var orgs []envelope.Org

	// Retrieve the org name supplied via the --org flag.
	// This flag is optional. If none was supplied, then
	// orgFlagArgument will be set to "". In this case,
	// prompt the user to select an org.
	orgName := ctx.String("org")

	if orgName == "" {
		// Retrieve list of available orgs
		orgs, err = client.Orgs.List(c)
		if err != nil {
			return errs.NewExitError("Failed to retrieve orgs list.")
		}

		// Prompt user to select from list of existing orgs
		idx, _, err := SelectExistingOrgPrompt(orgs)
		if err != nil {
			return errs.NewExitError("Failed to select org.")
		}

		org = &orgs[idx]

	} else {
		// If org flag was used, identify the org supplied.
		org, err = client.Orgs.GetByName(c, orgName)
		if org == nil {
			return errs.NewExitError("org" + orgName + "not found.")
		}
	}

	// Retrieve teams, memberships and the current session concurrently
	var teams []envelope.Team
	var memberships []envelope.Membership
	var session *api.Session
	var tErr, mErr, sErr error

	var getMembersTeamsSession sync.WaitGroup
	getMembersTeamsSession.Add(3)

	go func() {
		// Retrieve list of teams in org
		teams, tErr = client.Teams.List(c, org.ID, "", primitive.AnyTeamType)
		if tErr != nil {
			tErr = errs.NewExitError("Could not retrieve list of teams.")
			getMembersTeamsSession.Done()
			return
		}

		getMembersTeamsSession.Done()
	}()

	go func() {
		// Retrieve list of memberships in org
		memberships, mErr = client.Memberships.List(c, org.ID, nil, nil)
		if mErr != nil {
			tErr = errs.NewExitError("Could not retrieve list of memberships.")
			getMembersTeamsSession.Done()
			return
		}
		getMembersTeamsSession.Done()
	}()

	go func() {
		// Get current session - Who am I
		session, err = client.Session.Who(c)
		if sErr != nil {
			sErr = errs.NewExitError("Failed to get current session.")
			getMembersTeamsSession.Done()
			return
		}
		getMembersTeamsSession.Done()
	}()

	getMembersTeamsSession.Wait()
	if tErr != nil || mErr != nil || sErr != nil {
		return cli.NewMultiError(
			tErr,
			mErr,
			sErr,
		)
	}

	if len(memberships) == 0 {
		return errs.NewExitError(org.Body.Name + " has no members.")
	}

	// Map team IDs to Team objects
	teamsIdx := make(map[identity.ID]envelope.Team)
	for _, team := range teams {
		teamsIdx[*team.ID] = team
	}

	userTeamIdx := make(map[identity.ID][]identity.ID) // Mapping from user ID to team IDs
	membershipUserIDs := make(map[identity.ID]bool)    // Set of unique user IDs

	// Create:
	//	- Set of unqiue user IDs in membershipUserIDs
	// 	- Mapping from user IDs to team IDs in userTeamIdx (1:m mapping)
	for _, membership := range memberships {
		// Skip memberships not associated with teams within org
		team, ok := teamsIdx[*membership.Body.TeamID]
		if !ok {
			panic("Attemped to access membership with no associated team.")
		}

		// Skip memberships associated with machine team
		if isMachineTeam(team.Body) {
			continue
		}

		// Add to set of unique user IDs
		membershipUserIDs[*membership.Body.OwnerID] = true

		// For each new user ID, create mapping to teams that the user is in
		_, ok = userTeamIdx[*membership.Body.OwnerID]
		if !ok {
			// For new user IDs (not yet in userTeamIdx) create an empty list of team IDs
			userTeamIdx[*membership.Body.OwnerID] = []identity.ID{}
		}
		// Add current membership's team ID to user's list
		userTeamIdx[*membership.Body.OwnerID] = append(userTeamIdx[*membership.Body.OwnerID], *membership.Body.TeamID)
	}

	// Create unique list of user IDs
	var userIDs []identity.ID
	for id := range membershipUserIDs {
		userIDs = append(userIDs, id)
	}

	users, err := client.Profiles.ListByID(c, userIDs)
	if err != nil {
		return errs.NewExitError("Could not list teams.")
	}
	if users == nil {
		return errs.NewExitError("User not found.")
	}

	fmt.Println("")
	w := tabwriter.NewWriter(os.Stdout, 2, 0, 3, ' ', 0)
	fmt.Fprintf(w, " \tUSERNAME\tNAME\tTEAM\n")
	for _, user := range users {
		me := ""
		if session.Username() == user.Body.Username {
			me = "*"
		}

		// Sort teams by precedence
		userTeams := []envelope.Team{}
		for _, teamID := range userTeamIdx[*user.ID] {
			userTeams = append(userTeams, teamsIdx[teamID])
		}

		sort.Sort(ByTeamPrecedence(userTeams))

		// Create string containing all team names associated with each user
		teamString := ""
		for _, t := range userTeams {
			teamString += t.Body.Name + ", "
		}
		// Remove trailing comma and space character
		teamString = teamString[:len(teamString)-2]
		fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", me, user.Body.Username, user.Body.Name, teamString)
	}

	w.Flush()

	count := strconv.Itoa(len(userIDs))
	countString := "org " + org.Body.Name + " has (" + count + ") members."

	fmt.Println("")
	fmt.Println(countString)
	fmt.Println("")
	return nil
}

func getOrg(ctx context.Context, client *api.Client, name string) (*envelope.Org, error) {
	org, err := client.Orgs.GetByName(ctx, name)
	if err != nil {
		return nil, errs.NewErrorExitError("Unable to lookup org.", err)
	}
	if org == nil {
		return nil, errs.NewExitError("Org not found.")
	}

	return org, nil
}
<commit_msg>Removed unecessary actions from orgs memebrs action chain<commit_after>package cmd

import (
	"context"
	"fmt"
	"os"
	"sort"
	"strconv"
	"sync"
	"text/tabwriter"

	"github.com/urfave/cli"

	"github.com/manifoldco/torus-cli/api"
	"github.com/manifoldco/torus-cli/apitypes"
	"github.com/manifoldco/torus-cli/config"
	"github.com/manifoldco/torus-cli/envelope"
	"github.com/manifoldco/torus-cli/errs"
	"github.com/manifoldco/torus-cli/hints"
	"github.com/manifoldco/torus-cli/identity"
	"github.com/manifoldco/torus-cli/primitive"
)

func init() {
	orgs := cli.Command{
		Name:     "orgs",
		Usage:    "View and create organizations",
		Category: "ORGANIZATIONS",
		Subcommands: []cli.Command{
			{
				Name:      "create",
				Usage:     "Create a new organization",
				ArgsUsage: "<name>",
				Action:    chain(ensureDaemon, ensureSession, orgsCreate),
			},
			{
				Name:   "list",
				Usage:  "List organizations associated with your account",
				Action: chain(ensureDaemon, ensureSession, orgsListCmd),
			},
			{
				Name:      "remove",
				Usage:     "Remove a user from an org",
				ArgsUsage: "<username>",
				Flags: []cli.Flag{
					orgFlag("org to remove the user from", true),
				},
				Action: chain(
					ensureDaemon, ensureSession, loadDirPrefs, loadPrefDefaults,
					setUserEnv, checkRequiredFlags, orgsRemove,
				),
			},
			{
				Name:  "members",
				Usage: "List all members in an org",
				Flags: []cli.Flag{
					orgFlag("Use this organization.", false),
				},
				Action: chain(
					ensureDaemon, ensureSession, loadDirPrefs, loadPrefDefaults,
					orgsMembersListCmd,
				),
			},
		},
	}
	Cmds = append(Cmds, orgs)
}

const orgCreateFailed = "Org creation failed."

func orgsCreate(ctx *cli.Context) error {
	args := ctx.Args()
	if len(args) > 1 {
		return errs.NewUsageExitError("Too many arguments", ctx)
	}

	var name string
	var err error

	if len(args) == 1 {
		name = args[0]
	}

	label := "Org name"
	autoAccept := name != ""
	name, err = NamePrompt(&label, name, autoAccept)
	if err != nil {
		return handleSelectError(err, orgCreateFailed)
	}

	c := context.Background()

	cfg, err := config.LoadConfig()
	if err != nil {
		return errs.NewErrorExitError(orgCreateFailed, err)
	}

	client := api.NewClient(cfg)

	_, err = createOrgByName(c, ctx, client, name)
	if err != nil {
		return err
	}

	hints.Display(hints.InvitesSend, hints.Projects, hints.Link)
	return nil
}

func createOrgByName(c context.Context, ctx *cli.Context, client *api.Client, name string) (*envelope.Org, error) {
	org, err := client.Orgs.Create(c, name)
	if err != nil {
		return nil, errs.NewErrorExitError(orgCreateFailed, err)
	}

	err = generateKeypairsForOrg(c, ctx, client, org.ID, false)
	if err != nil {
		msg := fmt.Sprintf("Could not generate keypairs for org. Run '%s keypairs generate' to fix.", ctx.App.Name)
		return nil, errs.NewExitError(msg)
	}

	fmt.Println("Org " + org.Body.Name + " created.")
	return org, nil
}

func orgsListCmd(ctx *cli.Context) error {
	orgs, session, err := orgsList()
	if err != nil {
		return err
	}

	withoutPersonal := orgs

	if session.Type() == apitypes.UserSession {
		for i, o := range orgs {
			if o.Body.Name == session.Username() {
				fmt.Printf("  %s [personal]\n", o.Body.Name)
				withoutPersonal = append(orgs[:i], orgs[i+1:]...)
			}
		}
	}

	for _, o := range withoutPersonal {
		fmt.Printf("  %s\n", o.Body.Name)
	}

	return nil
}

func orgsList() ([]envelope.Org, *api.Session, error) {
	cfg, err := config.LoadConfig()
	if err != nil {
		return nil, nil, err
	}

	client := api.NewClient(cfg)

	var wg sync.WaitGroup
	wg.Add(2)

	var orgs []envelope.Org
	var session *api.Session
	var oErr, sErr error

	go func() {
		orgs, oErr = client.Orgs.List(context.Background())
		wg.Done()
	}()

	go func() {
		session, sErr = client.Session.Who(context.Background())
		wg.Done()
	}()

	wg.Wait()
	if oErr != nil || sErr != nil {
		return nil, nil, errs.NewExitError("Error fetching orgs list")
	}

	return orgs, session, nil
}

func orgsRemove(ctx *cli.Context) error {
	args := ctx.Args()
	if len(args) < 1 || args[0] == "" {
		return errs.NewUsageExitError("Missing username", ctx)
	}
	if len(args) > 1 {
		return errs.NewUsageExitError("Too many arguments", ctx)
	}
	username := args[0]

	cfg, err := config.LoadConfig()
	if err != nil {
		return err
	}

	client := api.NewClient(cfg)
	c := context.Background()

	const userNotFound = "User not found."
	const orgsRemoveFailed = "Could not remove user from the org."

	org, err := client.Orgs.GetByName(c, ctx.String("org"))
	if err != nil {
		return errs.NewErrorExitError(orgsRemoveFailed, err)
	}
	if org == nil {
		return errs.NewExitError("Org not found.")
	}

	profile, err := client.Profiles.ListByName(c, username)
	if apitypes.IsNotFoundError(err) {
		return errs.NewExitError(userNotFound)
	}
	if err != nil {
		return errs.NewErrorExitError(orgsRemoveFailed, err)
	}
	if profile == nil {
		return errs.NewExitError(userNotFound)
	}

	err = client.Orgs.RemoveMember(c, *org.ID, *profile.ID)
	if apitypes.IsNotFoundError(err) {
		fmt.Println("User is not a member of the org.")
		return nil
	}
	if err != nil {
		return errs.NewErrorExitError(orgsRemoveFailed, err)
	}

	fmt.Println("User has been removed from the org.")
	return nil
}

func orgsMembersListCmd(ctx *cli.Context) error {

	cfg, err := config.LoadConfig()
	if err != nil {
		return errs.NewExitError("Failed to load config.")
	}

	client := api.NewClient(cfg)
	c := context.Background()

	var org *envelope.Org
	var orgs []envelope.Org

	// Retrieve the org name supplied via the --org flag.
	// This flag is optional. If none was supplied, then
	// orgFlagArgument will be set to "". In this case,
	// prompt the user to select an org.
	orgName := ctx.String("org")

	if orgName == "" {
		// Retrieve list of available orgs
		orgs, err = client.Orgs.List(c)
		if err != nil {
			return errs.NewExitError("Failed to retrieve orgs list.")
		}

		// Prompt user to select from list of existing orgs
		idx, _, err := SelectExistingOrgPrompt(orgs)
		if err != nil {
			return errs.NewExitError("Failed to select org.")
		}

		org = &orgs[idx]

	} else {
		// If org flag was used, identify the org supplied.
		org, err = client.Orgs.GetByName(c, orgName)
		if org == nil {
			return errs.NewExitError("org" + orgName + "not found.")
		}
	}

	// Retrieve teams, memberships and the current session concurrently
	var teams []envelope.Team
	var memberships []envelope.Membership
	var session *api.Session
	var tErr, mErr, sErr error

	var getMembersTeamsSession sync.WaitGroup
	getMembersTeamsSession.Add(3)

	go func() {
		// Retrieve list of teams in org
		teams, tErr = client.Teams.List(c, org.ID, "", primitive.AnyTeamType)
		if tErr != nil {
			tErr = errs.NewExitError("Could not retrieve list of teams.")
			getMembersTeamsSession.Done()
			return
		}

		getMembersTeamsSession.Done()
	}()

	go func() {
		// Retrieve list of memberships in org
		memberships, mErr = client.Memberships.List(c, org.ID, nil, nil)
		if mErr != nil {
			tErr = errs.NewExitError("Could not retrieve list of memberships.")
			getMembersTeamsSession.Done()
			return
		}
		getMembersTeamsSession.Done()
	}()

	go func() {
		// Get current session - Who am I
		session, err = client.Session.Who(c)
		if sErr != nil {
			sErr = errs.NewExitError("Failed to get current session.")
			getMembersTeamsSession.Done()
			return
		}
		getMembersTeamsSession.Done()
	}()

	getMembersTeamsSession.Wait()
	if tErr != nil || mErr != nil || sErr != nil {
		return cli.NewMultiError(
			tErr,
			mErr,
			sErr,
		)
	}

	if len(memberships) == 0 {
		return errs.NewExitError(org.Body.Name + " has no members.")
	}

	// Map team IDs to Team objects
	teamsIdx := make(map[identity.ID]envelope.Team)
	for _, team := range teams {
		teamsIdx[*team.ID] = team
	}

	userTeamIdx := make(map[identity.ID][]identity.ID) // Mapping from user ID to team IDs
	membershipUserIDs := make(map[identity.ID]bool)    // Set of unique user IDs

	// Create:
	//	- Set of unqiue user IDs in membershipUserIDs
	// 	- Mapping from user IDs to team IDs in userTeamIdx (1:m mapping)
	for _, membership := range memberships {
		// Skip memberships not associated with teams within org
		team, ok := teamsIdx[*membership.Body.TeamID]
		if !ok {
			panic("Attemped to access membership with no associated team.")
		}

		// Skip memberships associated with machine team
		if isMachineTeam(team.Body) {
			continue
		}

		// Add to set of unique user IDs
		membershipUserIDs[*membership.Body.OwnerID] = true

		// For each new user ID, create mapping to teams that the user is in
		_, ok = userTeamIdx[*membership.Body.OwnerID]
		if !ok {
			// For new user IDs (not yet in userTeamIdx) create an empty list of team IDs
			userTeamIdx[*membership.Body.OwnerID] = []identity.ID{}
		}
		// Add current membership's team ID to user's list
		userTeamIdx[*membership.Body.OwnerID] = append(userTeamIdx[*membership.Body.OwnerID], *membership.Body.TeamID)
	}

	// Create unique list of user IDs
	var userIDs []identity.ID
	for id := range membershipUserIDs {
		userIDs = append(userIDs, id)
	}

	users, err := client.Profiles.ListByID(c, userIDs)
	if err != nil {
		return errs.NewExitError("Could not list teams.")
	}
	if users == nil {
		return errs.NewExitError("User not found.")
	}

	fmt.Println("")
	w := tabwriter.NewWriter(os.Stdout, 2, 0, 3, ' ', 0)
	fmt.Fprintf(w, " \tUSERNAME\tNAME\tTEAM\n")
	for _, user := range users {
		me := ""
		if session.Username() == user.Body.Username {
			me = "*"
		}

		// Sort teams by precedence
		userTeams := []envelope.Team{}
		for _, teamID := range userTeamIdx[*user.ID] {
			userTeams = append(userTeams, teamsIdx[teamID])
		}

		sort.Sort(ByTeamPrecedence(userTeams))

		// Create string containing all team names associated with each user
		teamString := ""
		for _, t := range userTeams {
			teamString += t.Body.Name + ", "
		}
		// Remove trailing comma and space character
		teamString = teamString[:len(teamString)-2]
		fmt.Fprintf(w, "%s\t%s\t%s\t%s\n", me, user.Body.Username, user.Body.Name, teamString)
	}

	w.Flush()

	count := strconv.Itoa(len(userIDs))
	countString := "org " + org.Body.Name + " has (" + count + ") members."

	fmt.Println("")
	fmt.Println(countString)
	fmt.Println("")
	return nil
}

func getOrg(ctx context.Context, client *api.Client, name string) (*envelope.Org, error) {
	org, err := client.Orgs.GetByName(ctx, name)
	if err != nil {
		return nil, errs.NewErrorExitError("Unable to lookup org.", err)
	}
	if org == nil {
		return nil, errs.NewExitError("Org not found.")
	}

	return org, nil
}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"
	"os"

	"github.com/gesquive/git-user/cli"
	"github.com/gesquive/git-user/git"
	"github.com/spf13/cobra"
)

var userProfileConfig *git.UserProfileConfig
var gitRepo *git.Repo
var cfgFilePath string
var projectPath string
var displayVersion string
var appName string

var logDebug bool
var showVersion bool

var global bool

// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
	Use:   "git-user",
	Short: "Allows you to save multiple user profiles and set them as git project defaults",
	Long:  `git-user lets you quickly switch between multiple git user profiles`,
	Run:   listRun,
}

// Execute adds all child commands to the root command sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute(version string) {
	displayVersion = version
	if err := RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}

func init() {
	cobra.OnInitialize(initConfig)

	defaultConfigPath := "~/.git-profiles"
	defaultProjectPath, _ := os.Getwd()

	RootCmd.PersistentFlags().StringVarP(&cfgFilePath, "config", "c",
		cli.ShortenHomeDir(defaultConfigPath), "config file")
	RootCmd.PersistentFlags().StringVarP(&projectPath, "path", "p",
		cli.ShortenHomeDir(defaultProjectPath), "The project to get/set the user")
	RootCmd.PersistentFlags().BoolVarP(&logDebug, "debug", "D", false,
		"Write debug messages to console")
	RootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "v", false,
		"Show the version and exit")

	RootCmd.PersistentFlags().MarkHidden("debug")
}

func initConfig() {
	if logDebug {
		cli.PrintDebug = true
	}
	if showVersion {
		cli.Infof(displayVersion)
		os.Exit(0)
	}
	appName = os.Args[0]
	if appName == "git-user" {
		appName = "git user"
	}

	cfgFilePath = cli.ExpandHomeDir(cfgFilePath)
	projectPath = cli.ExpandHomeDir(projectPath)
	cli.Debugf("cfgFilePath='%s' projectPath='%s'", cfgFilePath, projectPath)
	var err error
	userProfileConfig, err = git.NewUserProfileConfig(cfgFilePath)
	if err != nil {
		cli.Errorf("%v", err)
		os.Exit(2)
	}
	cli.Debugf("profileConfigPath=%s", userProfileConfig.Path())
	gitRepo = git.NewGitRepo(projectPath)
	cli.Debugf("gitRepo=%+v", gitRepo)
}
<commit_msg>change version print flag<commit_after>package cmd

import (
	"fmt"
	"os"

	"github.com/gesquive/git-user/cli"
	"github.com/gesquive/git-user/git"
	"github.com/spf13/cobra"
)

var userProfileConfig *git.UserProfileConfig
var gitRepo *git.Repo
var cfgFilePath string
var projectPath string
var displayVersion string
var appName string

var logDebug bool
var showVersion bool

var global bool

// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
	Use:   "git-user",
	Short: "Allows you to save multiple user profiles and set them as git project defaults",
	Long:  `git-user lets you quickly switch between multiple git user profiles`,
	Run:   listRun,
}

// Execute adds all child commands to the root command sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute(version string) {
	displayVersion = version
	if err := RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}

func init() {
	cobra.OnInitialize(initConfig)

	defaultConfigPath := "~/.git-profiles"
	defaultProjectPath, _ := os.Getwd()

	RootCmd.PersistentFlags().StringVarP(&cfgFilePath, "config", "c",
		cli.ShortenHomeDir(defaultConfigPath), "config file")
	RootCmd.PersistentFlags().StringVarP(&projectPath, "path", "p",
		cli.ShortenHomeDir(defaultProjectPath), "The project to get/set the user")
	RootCmd.PersistentFlags().BoolVarP(&logDebug, "debug", "D", false,
		"Write debug messages to console")
	RootCmd.PersistentFlags().BoolVarP(&showVersion, "version", "V", false,
		"Show the version and exit")

	RootCmd.PersistentFlags().MarkHidden("debug")
}

func initConfig() {
	if logDebug {
		cli.PrintDebug = true
	}
	if showVersion {
		cli.Infof(displayVersion)
		os.Exit(0)
	}
	appName = os.Args[0]
	if appName == "git-user" {
		appName = "git user"
	}

	cfgFilePath = cli.ExpandHomeDir(cfgFilePath)
	projectPath = cli.ExpandHomeDir(projectPath)
	cli.Debugf("cfgFilePath='%s' projectPath='%s'", cfgFilePath, projectPath)
	var err error
	userProfileConfig, err = git.NewUserProfileConfig(cfgFilePath)
	if err != nil {
		cli.Errorf("%v", err)
		os.Exit(2)
	}
	cli.Debugf("profileConfigPath=%s", userProfileConfig.Path())
	gitRepo = git.NewGitRepo(projectPath)
	cli.Debugf("gitRepo=%+v", gitRepo)
}
<|endoftext|>


<commit_before>// Copyright © 2017 Apptio
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package cmd

import (
	"fmt"
	"os"
	"os/user"
	"strings"

	"github.com/apptio/breakglass/vault"
	"github.com/bgentry/speakeasy"
	"github.com/hashicorp/vault/api"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"

	log "github.com/Sirupsen/logrus"
)

var cfgFile string
var vaultHost string
var vaultPort int

var userName string
var authMethod string
var userPass string

var debug bool
var execConn bool

var Version string

// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
	Use:   "breakglass",
	Short: "Get credentials from Hashicorp Vault",
	Long: `breakglass allows you to get login credentials for a variety of
Vault backends, such as databases servers, Linux servers (ssh credentials)
and AWS IAM roles`,
	// Uncomment the following line if your bare application
	// has an action associated with it:
	//	Run: func(cmd *cobra.Command, args []string) { },
}

// Execute adds all child commands to the root command sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute(version string) {
	Version = version
	if err := RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}

func init() {
	cobra.OnInitialize(initConfig)

	RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.breakglass/config.yaml)")
	RootCmd.PersistentFlags().StringVarP(&vaultHost, "vault", "v", "", "vault host to authenticate against")
	RootCmd.PersistentFlags().IntVarP(&vaultPort, "port", "p", 8200, "port of vault servers to use when authenticating")
	RootCmd.PersistentFlags().BoolVarP(&debug, "debug", "", false, "enable debug logging")
	RootCmd.PersistentFlags().BoolVarP(&execConn, "exec", "", false, "Initiate connection with credentials")
	RootCmd.PersistentFlags().StringVarP(&userName, "username", "", "", "username to authenticate to vault with")
	viper.BindPFlag("vault", RootCmd.PersistentFlags().Lookup("vault"))
	viper.BindPFlag("username", RootCmd.PersistentFlags().Lookup("username"))
	viper.BindPFlag("debug", RootCmd.PersistentFlags().Lookup("debug"))
	viper.BindPFlag("exec", RootCmd.PersistentFlags().Lookup("exec"))
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
	if cfgFile != "" { // enable ability to specify config file via flag
		viper.SetConfigFile(cfgFile)
	}

	viper.SetConfigName("config") // name of config file (without extension)
	viper.AddConfigPath("/etc/breakglass")
	viper.AddConfigPath("$HOME/.breakglass") // adding home directory as first search path
	viper.AddConfigPath(".")
	viper.AutomaticEnv() // read in environment variables that match

	// If a config file is found, read it in.
	if err := viper.ReadInConfig(); err == nil {
		log.Debug("Using config file:", viper.ConfigFileUsed())
	}

	// get the current logged in user for defaults
	currentUser, err := user.Current()

	if err != nil {
		log.Fatal("Error retrieving current user: ", err)
	}

	// set some sane defaults
	viper.SetDefault("username", currentUser.Username)
	viper.SetDefault("authmethod", "ldap")

}

func getPassword() string {
	password, _ := speakeasy.Ask("Please enter your password: ")
	return strings.TrimSpace(password)
}

func getVaultClient() *api.Client {
	// get main auth info
	userName = viper.GetString("username")
	authMethod = viper.GetString("authmethod")
	vaultHost = viper.GetString("vault")

	if vaultHost == "" {
		log.Fatal("No Vault host specified. See --help")
	}

	// get password
	log.WithFields(log.Fields{"username": userName,
		"authmethod": authMethod,
		"vaulthost":  vaultHost,
		"vaultport":  vaultPort}).Debug("prompting for password")

	userPass = getPassword()

	// create client
	client, err := vault.New(userName, userPass, authMethod, vaultHost, vaultPort)

	if err != nil {
		log.Fatal("Error logging into vault: ", err)
	}

	return client
}
<commit_msg>Fixes #4<commit_after>// Copyright © 2017 Apptio
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package cmd

import (
	"fmt"
	"os"
	"os/user"
	"strings"

	"github.com/apptio/breakglass/vault"
	"github.com/bgentry/speakeasy"
	"github.com/hashicorp/vault/api"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"

	log "github.com/Sirupsen/logrus"
)

var cfgFile string
var vaultHost string
var vaultPort int

var userName string
var authMethod string
var userPass string

var debug bool
var execConn bool

var Version string

// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
	Use:   "breakglass",
	Short: "Get credentials from Hashicorp Vault",
	Long: `breakglass allows you to get login credentials for a variety of
Vault backends, such as databases servers, Linux servers (ssh credentials)
and AWS IAM roles`,
	// Uncomment the following line if your bare application
	// has an action associated with it:
	//	Run: func(cmd *cobra.Command, args []string) { },
}

// Execute adds all child commands to the root command sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute(version string) {
	Version = version
	if err := RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}

func init() {
	cobra.OnInitialize(initConfig)

	RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.breakglass/config.yaml)")
	RootCmd.PersistentFlags().StringVarP(&vaultHost, "vault", "v", "vault", "vault host to authenticate against")
	RootCmd.PersistentFlags().IntVarP(&vaultPort, "port", "p", 8200, "port of vault servers to use when authenticating")
	RootCmd.PersistentFlags().BoolVarP(&debug, "debug", "", false, "enable debug logging")
	RootCmd.PersistentFlags().BoolVarP(&execConn, "exec", "", false, "Initiate connection with credentials")
	RootCmd.PersistentFlags().StringVarP(&userName, "username", "", "", "username to authenticate to vault with")
	viper.BindPFlag("vault", RootCmd.PersistentFlags().Lookup("vault"))
	viper.BindPFlag("username", RootCmd.PersistentFlags().Lookup("username"))
	viper.BindPFlag("debug", RootCmd.PersistentFlags().Lookup("debug"))
	viper.BindPFlag("exec", RootCmd.PersistentFlags().Lookup("exec"))
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
	if cfgFile != "" { // enable ability to specify config file via flag
		viper.SetConfigFile(cfgFile)
	}

	viper.SetConfigName("config") // name of config file (without extension)
	viper.AddConfigPath("/etc/breakglass")
	viper.AddConfigPath("$HOME/.breakglass") // adding home directory as first search path
	viper.AddConfigPath(".")
	viper.AutomaticEnv() // read in environment variables that match

	// If a config file is found, read it in.
	if err := viper.ReadInConfig(); err == nil {
		log.Debug("Using config file:", viper.ConfigFileUsed())
	}

	// get the current logged in user for defaults
	currentUser, err := user.Current()

	if err != nil {
		log.Fatal("Error retrieving current user: ", err)
	}

	// set some sane defaults
	viper.SetDefault("username", currentUser.Username)
	viper.SetDefault("authmethod", "ldap")

}

func getPassword() string {
	password, _ := speakeasy.Ask("Please enter your password: ")
	return strings.TrimSpace(password)
}

func getVaultClient() *api.Client {
	// get main auth info
	userName = viper.GetString("username")
	authMethod = viper.GetString("authmethod")
	vaultHost = viper.GetString("vault")

	if vaultHost == "" {
		log.Fatal("No Vault host specified. See --help")
	}

	// get password
	log.WithFields(log.Fields{"username": userName,
		"authmethod": authMethod,
		"vaulthost":  vaultHost,
		"vaultport":  vaultPort}).Debug("prompting for password")

	userPass = getPassword()

	// create client
	client, err := vault.New(userName, userPass, authMethod, vaultHost, vaultPort)

	if err != nil {
		log.Fatal("Error logging into vault: ", err)
	}

	return client
}
<|endoftext|>


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

package cmd

import (
	"fmt"
	"os"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/informers"

	"gitlab.jetstack.net/marshal/colonel/cmd/app"
	intinformers "gitlab.jetstack.net/marshal/colonel/pkg/informers"
	"gitlab.jetstack.net/marshal/colonel/pkg/kube"
)

var cfgFile string

// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
	Use:   "colonel",
	Short: "A brief description of your application",
	Long: `A longer description that spans multiple lines and likely contains
examples and usage of using your application. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,

	// TODO: Refactor this function from this package
	Run: func(cmd *cobra.Command, args []string) {
		server := "http://localhost:8082"
		cl, err := kube.NewKubernetesClient(server)

		if err != nil {
			logrus.Fatalf("error creating kubernetes client: %s", err.Error())
		}

		tprClient, err := kube.NewMarshalRESTClient(server)

		if err != nil {
			logrus.Fatalf("error creating third party resource client: %s", err.Error())
		}

		ctx := app.ControllerContext{
			Client:                 cl,
			TPRClient:              tprClient,
			InformerFactory:        informers.NewSharedInformerFactory(cl, time.Second*30),
			MarshalInformerFactory: intinformers.NewSharedInformerFactory(tprClient, time.Second*30),
			Namespace:              metav1.NamespaceAll,
			Stop:                   make(<-chan struct{}),
		}

		err = app.StartControllers(
			&ctx,
			app.Known(),
			ctx.Stop,
		)

		if err != nil {
			logrus.Fatalf("error running controllers: %s", err.Error())
		}
	},
}

// Execute adds all child commands to the root command sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
	if err := RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}

func init() {
	cobra.OnInitialize(initConfig)

	// Here you will define your flags and configuration settings.
	// Cobra supports Persistent Flags, which, if defined here,
	// will be global for your application.

	RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.colonel.yaml)")
	// Cobra also supports local flags, which will only run
	// when this action is called directly.
	RootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
	if cfgFile != "" { // enable ability to specify config file via flag
		viper.SetConfigFile(cfgFile)
	}

	viper.SetConfigName(".colonel") // name of config file (without extension)
	viper.AddConfigPath("$HOME")    // adding home directory as first search path
	viper.AutomaticEnv()            // read in environment variables that match

	// If a config file is found, read it in.
	if err := viper.ReadInConfig(); err == nil {
		fmt.Println("Using config file:", viper.ConfigFileUsed())
	}
}
<commit_msg>Add apiServerHost argument<commit_after>// Copyright © 2017 NAME HERE <EMAIL ADDRESS>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
	"fmt"
	"os"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/informers"

	"gitlab.jetstack.net/marshal/colonel/cmd/app"
	intinformers "gitlab.jetstack.net/marshal/colonel/pkg/informers"
	"gitlab.jetstack.net/marshal/colonel/pkg/kube"
)

var cfgFile string
var apiServerHost string

// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
	Use:   "colonel",
	Short: "A brief description of your application",
	Long: `A longer description that spans multiple lines and likely contains
examples and usage of using your application. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,

	// TODO: Refactor this function from this package
	Run: func(cmd *cobra.Command, args []string) {
		cl, err := kube.NewKubernetesClient(apiServerHost)

		if err != nil {
			logrus.Fatalf("error creating kubernetes client: %s", err.Error())
		}

		tprClient, err := kube.NewMarshalRESTClient(apiServerHost)

		if err != nil {
			logrus.Fatalf("error creating third party resource client: %s", err.Error())
		}

		ctx := app.ControllerContext{
			Client:                 cl,
			TPRClient:              tprClient,
			InformerFactory:        informers.NewSharedInformerFactory(cl, time.Second*30),
			MarshalInformerFactory: intinformers.NewSharedInformerFactory(tprClient, time.Second*30),
			Namespace:              metav1.NamespaceAll,
			Stop:                   make(<-chan struct{}),
		}

		err = app.StartControllers(
			&ctx,
			app.Known(),
			ctx.Stop,
		)

		if err != nil {
			logrus.Fatalf("error running controllers: %s", err.Error())
		}
	},
}

// Execute adds all child commands to the root command sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
	if err := RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}

func init() {
	cobra.OnInitialize(initConfig)

	// Here you will define your flags and configuration settings.
	// Cobra supports Persistent Flags, which, if defined here,
	// will be global for your application.

	RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.colonel.yaml)")
	RootCmd.PersistentFlags().StringVar(&apiServerHost, "apiServerHost", "", "optional api server hostname override")
	// Cobra also supports local flags, which will only run
	// when this action is called directly.
	RootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
	if cfgFile != "" { // enable ability to specify config file via flag
		viper.SetConfigFile(cfgFile)
	}

	viper.SetConfigName(".colonel") // name of config file (without extension)
	viper.AddConfigPath("$HOME")    // adding home directory as first search path
	viper.AutomaticEnv()            // read in environment variables that match

	// If a config file is found, read it in.
	if err := viper.ReadInConfig(); err == nil {
		fmt.Println("Using config file:", viper.ConfigFileUsed())
	}
}
<|endoftext|>


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

package cmd

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
)

var cfgFile string

// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
	Use:   "goperator",
	Short: "Manage your AWS resources in a easy way",
	Long: `Goperator is a CLI applications that allows you to manage AWS infrastructure
without having to deal with the Console or the aws Python CLI`,
}

func Execute() {
	if err := RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}
<commit_msg>remove unused var<commit_after>// Copyright © 2017 Miguel Ángel García <mgarcia.inf@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
)

// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
	Use:   "goperator",
	Short: "Manage your AWS resources in a easy way",
	Long: `Goperator is a CLI applications that allows you to manage AWS infrastructure
without having to deal with the Console or the aws Python CLI`,
}

func Execute() {
	if err := RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}
<|endoftext|>


<commit_before>package cmd

import (
	"github.com/spf13/cobra"

	"github.com/antham/doc-hunt/file"
	"github.com/antham/doc-hunt/ui"
	"github.com/antham/doc-hunt/util"
)

// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
	Use:   "doc-hunt",
	Short: "Ensure your documentation is up to date",
}

// Execute adds all child commands to the root command sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
	if err := file.Initialize(); err != nil {
		ui.Error(err)

		util.ErrorExit()
	}

	if err := RootCmd.Execute(); err != nil {
		ui.Error(err)
		util.ErrorExit()
	}
}
<commit_msg>feat(cmd) : check major version on init<commit_after>package cmd

import (
	"github.com/spf13/cobra"

	"github.com/antham/doc-hunt/file"
	"github.com/antham/doc-hunt/ui"
	"github.com/antham/doc-hunt/util"
)

// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
	Use:   "doc-hunt",
	Short: "Ensure your documentation is up to date",
}

// Execute adds all child commands to the root command sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
	if err := file.Initialize(); err != nil {
		ui.Error(err)
		util.ErrorExit()
	}

	if ok, err := file.HasMajorVersionEqualFrom(); !ok {
		ui.Error(err)
		util.ErrorExit()
	}

	if err := RootCmd.Execute(); err != nil {
		ui.Error(err)
		util.ErrorExit()
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"io"
	"os/exec"
	"strings"

	"github.com/cep21/gobuild/internal/golang.org/x/net/context"
)

type duplCmd struct {
	verboseLog logger
	htmlOut    io.Writer
	consoleOut io.Writer
	tmpl       *buildTemplate
	dirs       []string
}

func (d *duplCmd) Run(ctx context.Context) error {
	d.verboseLog.Printf("Running dupl -plumbing command")
	regDuplOut, err := d.runDupl(ctx, []string{"-plumbing"})
	if err != nil {
		d.verboseLog.Printf("Regular dupl output: %s", string(regDuplOut))
		return wraperr(err, "unable to correctly run regular dupl")
	}

	d.verboseLog.Printf("Running dupl -html command")
	htmlDuplOut, err := d.runDupl(ctx, []string{"-html"})
	if err != nil {
		d.verboseLog.Printf("html dupl output: %s", string(htmlDuplOut))
		return wraperr(err, "unable to correctly run html dupl")
	}
	n, err := d.consoleOut.Write(regDuplOut)
	if err != nil {
		return wraperr(err, "could not copy dupl output, wrote %d", n)
	}
	n, err = d.htmlOut.Write(htmlDuplOut)
	if err != nil {
		return wraperr(err, "could not copy html dupl output, wrote %d", n)
	}
	return nil
}

func (d *duplCmd) runDupl(ctx context.Context, extraArgs []string) ([]byte, error) {
	cmdName := "dupl"
	args := append(d.tmpl.DuplArgs(), extraArgs...)
	goFiles, err := filesWithGlobInDir(d.dirs, "*.go")
	if err != nil {
		return nil, wraperr(err, "dupl *.go glob search failed for %s", strings.Join(d.dirs, ", "))
	}
	buf := bytes.Buffer{}
	_, err = io.Copy(&buf, bytes.NewBufferString(strings.Join(goFiles, "\n")))
	if err != nil {
		return nil, wraperr(err, "could not copy gofiles into buffer")
	}
	cmd := exec.Command(cmdName, args...)
	cmd.Stdin = &buf
	return cmd.CombinedOutput()
}
<commit_msg>Detect errors on dupl command<commit_after>package main

import (
	"bytes"
	"io"
	"os/exec"
	"strings"

	"github.com/cep21/gobuild/internal/golang.org/x/net/context"
"errors"
)

type duplCmd struct {
	verboseLog logger
	htmlOut    io.Writer
	consoleOut io.Writer
	tmpl       *buildTemplate
	dirs       []string
}

func (d *duplCmd) Run(ctx context.Context) error {
	d.verboseLog.Printf("Running dupl -plumbing command")
	regDuplOut, err := d.runDupl(ctx, []string{"-plumbing"})
	if err != nil {
		d.verboseLog.Printf("Regular dupl output: %s", string(regDuplOut))
		return wraperr(err, "unable to correctly run regular dupl")
	}

	d.verboseLog.Printf("Running dupl -html command")
	htmlDuplOut, err := d.runDupl(ctx, []string{"-html"})
	if err != nil {
		d.verboseLog.Printf("html dupl output: %s", string(htmlDuplOut))
		return wraperr(err, "unable to correctly run html dupl")
	}
	n, err := d.consoleOut.Write(regDuplOut)
	if err != nil {
		return wraperr(err, "could not copy dupl output, wrote %d", n)
	}
	n, err = d.htmlOut.Write(htmlDuplOut)
	if err != nil {
		return wraperr(err, "could not copy html dupl output, wrote %d", n)
	}
	if len(regDuplOut) > 2 {
		return errDuplicatesDetected
	}
	return nil
}

var errDuplicatesDetected = errors.New("duplicates detected in files")

func (d *duplCmd) runDupl(ctx context.Context, extraArgs []string) ([]byte, error) {
	cmdName := "dupl"
	args := append(d.tmpl.DuplArgs(), extraArgs...)
	goFiles, err := filesWithGlobInDir(d.dirs, "*.go")
	if err != nil {
		return nil, wraperr(err, "dupl *.go glob search failed for %s", strings.Join(d.dirs, ", "))
	}
	buf := bytes.Buffer{}
	_, err = io.Copy(&buf, bytes.NewBufferString(strings.Join(goFiles, "\n")))
	if err != nil {
		return nil, wraperr(err, "could not copy gofiles into buffer")
	}
	cmd := exec.Command(cmdName, args...)
	cmd.Stdin = &buf
	return cmd.CombinedOutput()
}
<|endoftext|>


<commit_before>package coal

import (
	"go.mongodb.org/mongo-driver/bson"
)

// Map represents a raw BSON object that can be used to marshal and unmarshal
// concrete types.
type Map map[string]interface{}

// MustMap will encode the specified object as a map and panic if there was an
// error.
func MustMap(from interface{}) Map {
	var m Map
	m.MustMarshal(from)
	return m
}

// Unmarshal will unmarshal the raw value to the type pointed by val.
func (m *Map) Unmarshal(to interface{}) error {
	// marshal to BSON
	bytes, err := bson.Marshal(*m)
	if err != nil {
		return err
	}

	// unmarshal BSON
	return bson.Unmarshal(bytes, to)
}

// MustUnmarshal will unmarshal and panic on error.
func (m *Map) MustUnmarshal(to interface{}) {
	// unmarshal and panic on error
	err := m.Unmarshal(to)
	if err != nil {
		panic(err)
	}
}

// Marshal will encode the type pointed by val and store the result.
func (m *Map) Marshal(from interface{}) error {
	// marshal to BSON
	bytes, err := bson.Marshal(from)
	if err != nil {
		return err
	}

	// reset
	*m = nil

	// unmarshal BSON
	return bson.Unmarshal(bytes, m)
}

// MustMarshal will marshal and panic on error.
func (m *Map) MustMarshal(from interface{}) {
	// marshal and panic on error
	err := m.Marshal(from)
	if err != nil {
		panic(err)
	}
}
<commit_msg>fix docs<commit_after>package coal

import (
	"go.mongodb.org/mongo-driver/bson"
)

// Map represents a simple BSON map. In contrast to bson.M it provides methods
// to marshal and unmarshal concrete types to and from the map.
type Map map[string]interface{}

// MustMap will marshal the specified object to a map and panic on any error.
func MustMap(from interface{}) Map {
	var m Map
	m.MustMarshal(from)
	return m
}

// Unmarshal will unmarshal the raw value to the type pointed by val.
func (m *Map) Unmarshal(to interface{}) error {
	// marshal to BSON
	bytes, err := bson.Marshal(*m)
	if err != nil {
		return err
	}

	// unmarshal BSON
	return bson.Unmarshal(bytes, to)
}

// MustUnmarshal will unmarshal and panic on error.
func (m *Map) MustUnmarshal(to interface{}) {
	// unmarshal and panic on error
	err := m.Unmarshal(to)
	if err != nil {
		panic(err)
	}
}

// Marshal will encode the type pointed by val and store the result.
func (m *Map) Marshal(from interface{}) error {
	// marshal to BSON
	bytes, err := bson.Marshal(from)
	if err != nil {
		return err
	}

	// reset
	*m = nil

	// unmarshal BSON
	return bson.Unmarshal(bytes, m)
}

// MustMarshal will marshal and panic on error.
func (m *Map) MustMarshal(from interface{}) {
	// marshal and panic on error
	err := m.Marshal(from)
	if err != nil {
		panic(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"strings"
)

type NodeType int

const (
	ndError NodeType = iota
	ndBlock
	ndCharacter
	ndExtVarDecl
	ndExtVarInit
	ndFunction
	ndInteger
	ndString
	ndVarDecl
)

type Node interface {
	Type() NodeType
	String() string
}

// '{' node* '}'
type BlockNode struct {
	nodes []Node
}

func (b BlockNode) Type() NodeType { return ndBlock }
func (b BlockNode) String() string {
	str := "{\n"

	for _, node := range b.nodes {
		str += fmt.Sprintf("\t%v\n", node)
	}

	str += "}"
	return str
}

type CharacterNode struct {
	value string
}

func (c CharacterNode) Type() NodeType { return ndCharacter }
func (c CharacterNode) String() string { return fmt.Sprintf("'%s'", c.value) }

type ExternVarDeclNode struct {
	names []string
}

func (e ExternVarDeclNode) Type() NodeType { return ndExtVarDecl }
func (e ExternVarDeclNode) String() string {
	return fmt.Sprintf("extrn %s;", strings.Join(e.names, ", "))
}

// name value ';'
type ExternVarInitNode struct {
	name  string
	value Node
}

func (e ExternVarInitNode) Type() NodeType { return ndExtVarInit }
func (e ExternVarInitNode) String() string {
	return fmt.Sprintf("%s %v;", e.name, e.value)
}

// name '(' (var (',' var)*) ? ')' block
type FunctionNode struct {
	name   string
	params []string
	block  BlockNode
}

func (f FunctionNode) Type() NodeType { return ndFunction }
func (f FunctionNode) String() string {
	return fmt.Sprintf("%s(%s) %s",
		f.name, strings.Join(f.params, ", "), f.block)
}

type IntegerNode struct {
	value string
}

func (i IntegerNode) Type() NodeType { return ndInteger }
func (i IntegerNode) String() string { return i.value }

type VarDeclNode struct {
	vars []string
}

type StringNode struct {
	value string
}

func (s StringNode) Type() NodeType { return ndString }
func (s StringNode) String() string { return fmt.Sprintf("\"%s\"", s.value) }

func (v VarDeclNode) Type() NodeType { return ndVarDecl }
func (v VarDeclNode) String() string {
	return fmt.Sprintf("auto %s;", strings.Join(v.vars, ", "))
}
<commit_msg>Add array access node<commit_after>package main

import (
	"fmt"
	"strings"
)

type NodeType int

const (
	ndError NodeType = iota
	ndArrayAccess
	ndBlock
	ndCharacter
	ndExtVarDecl
	ndExtVarInit
	ndFunction
	ndInteger
	ndString
	ndVarDecl
)

type Node interface {
	Type() NodeType
	String() string
}

type ArrayAccessNode struct {
	array Node
	index Node
}

func (a ArrayAccessNode) Type() NodeType { return ndArrayAccess }
func (a ArrayAccessNode) String() string {
	return fmt.Sprintf("%s[%s]", a.array, a.index)
}

// '{' node* '}'
type BlockNode struct {
	nodes []Node
}

func (b BlockNode) Type() NodeType { return ndBlock }
func (b BlockNode) String() string {
	str := "{\n"

	for _, node := range b.nodes {
		str += fmt.Sprintf("\t%v\n", node)
	}

	str += "}"
	return str
}

type CharacterNode struct {
	value string
}

func (c CharacterNode) Type() NodeType { return ndCharacter }
func (c CharacterNode) String() string { return fmt.Sprintf("'%s'", c.value) }

type ExternVarDeclNode struct {
	names []string
}

func (e ExternVarDeclNode) Type() NodeType { return ndExtVarDecl }
func (e ExternVarDeclNode) String() string {
	return fmt.Sprintf("extrn %s;", strings.Join(e.names, ", "))
}

// name value ';'
type ExternVarInitNode struct {
	name  string
	value Node
}

func (e ExternVarInitNode) Type() NodeType { return ndExtVarInit }
func (e ExternVarInitNode) String() string {
	return fmt.Sprintf("%s %v;", e.name, e.value)
}

// name '(' (var (',' var)*) ? ')' block
type FunctionNode struct {
	name   string
	params []string
	block  BlockNode
}

func (f FunctionNode) Type() NodeType { return ndFunction }
func (f FunctionNode) String() string {
	return fmt.Sprintf("%s(%s) %s",
		f.name, strings.Join(f.params, ", "), f.block)
}

type IntegerNode struct {
	value string
}

func (i IntegerNode) Type() NodeType { return ndInteger }
func (i IntegerNode) String() string { return i.value }

type StringNode struct {
	value string
}

func (s StringNode) Type() NodeType { return ndString }
func (s StringNode) String() string { return fmt.Sprintf("\"%s\"", s.value) }

func (v VarDeclNode) Type() NodeType { return ndVarDecl }
func (v VarDeclNode) String() string {
	return fmt.Sprintf("auto %s;", strings.Join(v.vars, ", "))
}
<|endoftext|>