<commit_before>package credentials

import (
	"fmt"
	"os"

	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/internal/ini"
	"github.com/aws/aws-sdk-go/internal/shareddefaults"
)

// SharedCredsProviderName provides a name of SharedCreds provider
const SharedCredsProviderName = "SharedCredentialsProvider"

var (
	// ErrSharedCredentialsHomeNotFound is emitted when the user directory cannot be found.
	ErrSharedCredentialsHomeNotFound = awserr.New("UserHomeNotFound", "user home directory not found.", nil)
)

// A SharedCredentialsProvider retrieves credentials from the current user's home
// directory, and keeps track if those credentials are expired.
//
// Profile ini file example: $HOME/.aws/credentials
type SharedCredentialsProvider struct {
	// Path to the shared credentials file.
	//
	// If empty will look for "AWS_SHARED_CREDENTIALS_FILE" env variable. If the
	// env value is empty will default to current user's home directory.
	// Linux/OSX: "$HOME/.aws/credentials"
	// Windows:   "%USERPROFILE%\.aws\credentials"
	Filename string

	// AWS Profile to extract credentials from the shared credentials file. If empty
	// will default to environment variable "AWS_PROFILE" or "default" if
	// environment variable is also not set.
	Profile string

	// retrieved states if the credentials have been successfully retrieved.
	retrieved bool
}

// NewSharedCredentials returns a pointer to a new Credentials object
// wrapping the Profile file provider.
func NewSharedCredentials(filename, profile string) *Credentials {
	return NewCredentials(&SharedCredentialsProvider{
		Filename: filename,
		Profile:  profile,
	})
}

// Retrieve reads and extracts the shared credentials from the current
// users home directory.
func (p *SharedCredentialsProvider) Retrieve() (Value, error) {
	p.retrieved = false

	filename, err := p.filename()
	if err != nil {
		return Value{ProviderName: SharedCredsProviderName}, err
	}

	creds, err := loadProfile(filename, p.profile())
	if err != nil {
		return Value{ProviderName: SharedCredsProviderName}, err
	}

	p.retrieved = true
	return creds, nil
}

// IsExpired returns if the shared credentials have expired.
func (p *SharedCredentialsProvider) IsExpired() bool {
	return !p.retrieved
}

// loadProfiles loads from the file pointed to by shared credentials filename for profile.
// The credentials retrieved from the profile will be returned or error. Error will be
// returned if it fails to read from the file, or the data is invalid.
func loadProfile(filename, profile string) (Value, error) {
	config, err := ini.OpenFile(filename)
	if err != nil {
		return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to load shared credentials file", err)
	}

	iniProfile, ok := config.GetSection(profile)
	if !ok {
		return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to get profile", nil)
	}

	id := iniProfile.String("aws_access_key_id")
	if len(id) == 0 {
		return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsAccessKey",
			fmt.Sprintf("shared credentials %s in %s did not contain aws_access_key_id", profile, filename),
			nil)
	}

	secret := iniProfile.String("aws_secret_access_key")
	if len(secret) == 0 {
		return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsSecret",
			fmt.Sprintf("shared credentials %s in %s did not contain aws_secret_access_key", profile, filename),
			nil)
	}

	// Default to empty string if not found
	token := iniProfile.String("aws_session_token")

	return Value{
		AccessKeyID:     id,
		SecretAccessKey: secret,
		SessionToken:    token,
		ProviderName:    SharedCredsProviderName,
	}, nil
}

// filename returns the filename to use to read AWS shared credentials.
//
// Will return an error if the user's home directory path cannot be found.
func (p *SharedCredentialsProvider) filename() (string, error) {
	if len(p.Filename) != 0 {
		return p.Filename, nil
	}

	if p.Filename = os.Getenv("AWS_SHARED_CREDENTIALS_FILE"); len(p.Filename) != 0 {
		return p.Filename, nil
	}

	if home := shareddefaults.UserHomeDir(); len(home) == 0 {
		// Backwards compatibility of home directly not found error being returned.
		// This error is too verbose, failure when opening the file would of been
		// a better error to return.
		return "", ErrSharedCredentialsHomeNotFound
	}

	p.Filename = shareddefaults.SharedCredentialsFilename()

	return p.Filename, nil
}

// profile returns the AWS shared credentials profile.  If empty will read
// environment variable "AWS_PROFILE". If that is not set profile will
// return "default".
func (p *SharedCredentialsProvider) profile() string {
	if p.Profile == "" {
		p.Profile = os.Getenv("AWS_PROFILE")
	}
	if p.Profile == "" {
		p.Profile = "default"
	}

	return p.Profile
}
<commit_msg>aws/credentials: Update shared creds provider docs<commit_after>package credentials

import (
	"fmt"
	"os"

	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/internal/ini"
	"github.com/aws/aws-sdk-go/internal/shareddefaults"
)

// SharedCredsProviderName provides a name of SharedCreds provider
const SharedCredsProviderName = "SharedCredentialsProvider"

var (
	// ErrSharedCredentialsHomeNotFound is emitted when the user directory cannot be found.
	ErrSharedCredentialsHomeNotFound = awserr.New("UserHomeNotFound", "user home directory not found.", nil)
)

// A SharedCredentialsProvider retrieves access key pair (access key ID,
// secret access key, and session token if present) credentials from the current
// user's home directory, and keeps track if those credentials are expired.
//
// Profile ini file example: $HOME/.aws/credentials
type SharedCredentialsProvider struct {
	// Path to the shared credentials file.
	//
	// If empty will look for "AWS_SHARED_CREDENTIALS_FILE" env variable. If the
	// env value is empty will default to current user's home directory.
	// Linux/OSX: "$HOME/.aws/credentials"
	// Windows:   "%USERPROFILE%\.aws\credentials"
	Filename string

	// AWS Profile to extract credentials from the shared credentials file. If empty
	// will default to environment variable "AWS_PROFILE" or "default" if
	// environment variable is also not set.
	Profile string

	// retrieved states if the credentials have been successfully retrieved.
	retrieved bool
}

// NewSharedCredentials returns a pointer to a new Credentials object
// wrapping the Profile file provider.
func NewSharedCredentials(filename, profile string) *Credentials {
	return NewCredentials(&SharedCredentialsProvider{
		Filename: filename,
		Profile:  profile,
	})
}

// Retrieve reads and extracts the shared credentials from the current
// users home directory.
func (p *SharedCredentialsProvider) Retrieve() (Value, error) {
	p.retrieved = false

	filename, err := p.filename()
	if err != nil {
		return Value{ProviderName: SharedCredsProviderName}, err
	}

	creds, err := loadProfile(filename, p.profile())
	if err != nil {
		return Value{ProviderName: SharedCredsProviderName}, err
	}

	p.retrieved = true
	return creds, nil
}

// IsExpired returns if the shared credentials have expired.
func (p *SharedCredentialsProvider) IsExpired() bool {
	return !p.retrieved
}

// loadProfiles loads from the file pointed to by shared credentials filename for profile.
// The credentials retrieved from the profile will be returned or error. Error will be
// returned if it fails to read from the file, or the data is invalid.
func loadProfile(filename, profile string) (Value, error) {
	config, err := ini.OpenFile(filename)
	if err != nil {
		return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to load shared credentials file", err)
	}

	iniProfile, ok := config.GetSection(profile)
	if !ok {
		return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to get profile", nil)
	}

	id := iniProfile.String("aws_access_key_id")
	if len(id) == 0 {
		return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsAccessKey",
			fmt.Sprintf("shared credentials %s in %s did not contain aws_access_key_id", profile, filename),
			nil)
	}

	secret := iniProfile.String("aws_secret_access_key")
	if len(secret) == 0 {
		return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsSecret",
			fmt.Sprintf("shared credentials %s in %s did not contain aws_secret_access_key", profile, filename),
			nil)
	}

	// Default to empty string if not found
	token := iniProfile.String("aws_session_token")

	return Value{
		AccessKeyID:     id,
		SecretAccessKey: secret,
		SessionToken:    token,
		ProviderName:    SharedCredsProviderName,
	}, nil
}

// filename returns the filename to use to read AWS shared credentials.
//
// Will return an error if the user's home directory path cannot be found.
func (p *SharedCredentialsProvider) filename() (string, error) {
	if len(p.Filename) != 0 {
		return p.Filename, nil
	}

	if p.Filename = os.Getenv("AWS_SHARED_CREDENTIALS_FILE"); len(p.Filename) != 0 {
		return p.Filename, nil
	}

	if home := shareddefaults.UserHomeDir(); len(home) == 0 {
		// Backwards compatibility of home directly not found error being returned.
		// This error is too verbose, failure when opening the file would of been
		// a better error to return.
		return "", ErrSharedCredentialsHomeNotFound
	}

	p.Filename = shareddefaults.SharedCredentialsFilename()

	return p.Filename, nil
}

// profile returns the AWS shared credentials profile.  If empty will read
// environment variable "AWS_PROFILE". If that is not set profile will
// return "default".
func (p *SharedCredentialsProvider) profile() string {
	if p.Profile == "" {
		p.Profile = os.Getenv("AWS_PROFILE")
	}
	if p.Profile == "" {
		p.Profile = "default"
	}

	return p.Profile
}
<|endoftext|>


<commit_before>package ble

import (
	"bytes"
	"fmt"

	"github.com/hybridgroup/gobot"
)

var _ gobot.Driver = (*SpheroOllieDriver)(nil)

type SpheroOllieDriver struct {
	name       string
	connection gobot.Connection
	gobot.Eventer
}

const (
	// service IDs
	SpheroBLEService = "22bb746f2bb075542d6f726568705327"

	// characteristic IDs
	WakeCharacteristic = "22bb746f2bbf75542d6f726568705327"
	TXPowerCharacteristic = "22bb746f2bb275542d6f726568705327"
	AntiDosCharacteristic = "22bb746f2bbd75542d6f726568705327"
	RobotControlService = "22bb746f2ba075542d6f726568705327"
	CommandsCharacteristic = "22bb746f2ba175542d6f726568705327"
	ResponseCharacteristic = "22bb746f2ba675542d6f726568705327"
)

// NewSpheroOllieDriver creates a SpheroOllieDriver by name
func NewSpheroOllieDriver(a *BLEClientAdaptor, name string) *SpheroOllieDriver {
	n := &SpheroOllieDriver{
		name:       name,
		connection: a,
		Eventer: gobot.NewEventer(),
	}

	return n
}
func (b *SpheroOllieDriver) Connection() gobot.Connection { return b.connection }
func (b *SpheroOllieDriver) Name() string                 { return b.name }

// adaptor returns BLE adaptor
func (b *SpheroOllieDriver) adaptor() *BLEClientAdaptor {
	return b.Connection().(*BLEClientAdaptor)
}

// Start tells driver to get ready to do work
func (b *SpheroOllieDriver) Start() (errs []error) {
	b.Init()

	return
}

// Halt stops Ollie driver (void)
func (b *SpheroOllieDriver) Halt() (errs []error) {
	return
}

func (b *SpheroOllieDriver) Init() (err error) {
	b.AntiDOSOff()
	b.SetTXPower(7)
	b.Wake()

	// subscribe to Sphero response notifications
	b.adaptor().Subscribe(RobotControlService, ResponseCharacteristic, b.HandleResponses)

	return
}

// Turns off Anti-DOS code so we can control Ollie
func (b *SpheroOllieDriver) AntiDOSOff() (err error) {
	str := "011i3"
	buf := &bytes.Buffer{}
	buf.WriteString(str)

	err = b.adaptor().WriteCharacteristic(SpheroBLEService, AntiDosCharacteristic, buf.Bytes())
	if err != nil {
		fmt.Println("AntiDOSOff error:", err)
		return err
	}

	return
}

// Wakes Ollie up so we can play
func (b *SpheroOllieDriver) Wake() (err error) {
	buf := []byte{0x01}

	err = b.adaptor().WriteCharacteristic(SpheroBLEService, WakeCharacteristic, buf)
	if err != nil {
		fmt.Println("Wake error:", err)
		return err
	}

	return
}

// Sets transmit level
func (b *SpheroOllieDriver) SetTXPower(level int) (err error) {
	buf := []byte{byte(level)}

	err = b.adaptor().WriteCharacteristic(SpheroBLEService, TXPowerCharacteristic, buf)
	if err != nil {
		fmt.Println("SetTXLevel error:", err)
		return err
	}

	return
}

// Handle responses returned from Ollie
func (b *SpheroOllieDriver) HandleResponses(data []byte, e error) {
	fmt.Println("response data:", data)

	return
}

// SetRGB sets the Ollie to the given r, g, and b values
func (s *SpheroOllieDriver) SetRGB(r uint8, g uint8, b uint8) {
	fmt.Println("setrgb")
}

// Tells the Ollie to roll
func (s *SpheroOllieDriver) Roll(speed uint8, heading uint16) {
	fmt.Println("roll", speed, heading)
}

// Tells the Ollie to stop
func (s *SpheroOllieDriver) Stop() {
	s.Roll(0, 0)
}
<commit_msg>[ble] Can setrgb commands to Ollie<commit_after>package ble

import (
	"bytes"
	"fmt"

	"github.com/hybridgroup/gobot"
)

var _ gobot.Driver = (*SpheroOllieDriver)(nil)

type SpheroOllieDriver struct {
	name       string
	connection gobot.Connection
	seq             uint8
	packetChannel   chan *packet
	gobot.Eventer
}

const (
	// service IDs
	SpheroBLEService = "22bb746f2bb075542d6f726568705327"
	RobotControlService = "22bb746f2ba075542d6f726568705327"

	// characteristic IDs
	WakeCharacteristic = "22bb746f2bbf75542d6f726568705327"
	TXPowerCharacteristic = "22bb746f2bb275542d6f726568705327"
	AntiDosCharacteristic = "22bb746f2bbd75542d6f726568705327"

	CommandsCharacteristic = "22bb746f2ba175542d6f726568705327"
	ResponseCharacteristic = "22bb746f2ba675542d6f726568705327"

	// gobot events
	SensorData = "sensordata"
	Collision  = "collision"
	Error      = "error"
)

type packet struct {
	header   []uint8
	body     []uint8
	checksum uint8
}

// NewSpheroOllieDriver creates a SpheroOllieDriver by name
func NewSpheroOllieDriver(a *BLEClientAdaptor, name string) *SpheroOllieDriver {
	n := &SpheroOllieDriver{
		name:       name,
		connection: a,
		Eventer: gobot.NewEventer(),
		packetChannel:   make(chan *packet, 1024),
	}

	return n
}
func (b *SpheroOllieDriver) Connection() gobot.Connection { return b.connection }
func (b *SpheroOllieDriver) Name() string                 { return b.name }

// adaptor returns BLE adaptor
func (b *SpheroOllieDriver) adaptor() *BLEClientAdaptor {
	return b.Connection().(*BLEClientAdaptor)
}

// Start tells driver to get ready to do work
func (s *SpheroOllieDriver) Start() (errs []error) {
	s.Init()

	// send commands
	go func() {
		for {
			packet := <-s.packetChannel
			err := s.write(packet)
			if err != nil {
				gobot.Publish(s.Event(Error), err)
			}
		}
	}()

	return
}

// Halt stops Ollie driver (void)
func (b *SpheroOllieDriver) Halt() (errs []error) {
	return
}

func (b *SpheroOllieDriver) Init() (err error) {
	b.AntiDOSOff()
	b.SetTXPower(7)
	b.Wake()

	// subscribe to Sphero response notifications
	b.adaptor().Subscribe(RobotControlService, ResponseCharacteristic, b.HandleResponses)

	return
}

// Turns off Anti-DOS code so we can control Ollie
func (b *SpheroOllieDriver) AntiDOSOff() (err error) {
	str := "011i3"
	buf := &bytes.Buffer{}
	buf.WriteString(str)

	err = b.adaptor().WriteCharacteristic(SpheroBLEService, AntiDosCharacteristic, buf.Bytes())
	if err != nil {
		fmt.Println("AntiDOSOff error:", err)
		return err
	}

	return
}

// Wakes Ollie up so we can play
func (b *SpheroOllieDriver) Wake() (err error) {
	buf := []byte{0x01}

	err = b.adaptor().WriteCharacteristic(SpheroBLEService, WakeCharacteristic, buf)
	if err != nil {
		fmt.Println("Wake error:", err)
		return err
	}

	return
}

// Sets transmit level
func (b *SpheroOllieDriver) SetTXPower(level int) (err error) {
	buf := []byte{byte(level)}

	err = b.adaptor().WriteCharacteristic(SpheroBLEService, TXPowerCharacteristic, buf)
	if err != nil {
		fmt.Println("SetTXLevel error:", err)
		return err
	}

	return
}

// Handle responses returned from Ollie
func (b *SpheroOllieDriver) HandleResponses(data []byte, e error) {
	fmt.Println("response data:", data)

	return
}

// SetRGB sets the Ollie to the given r, g, and b values
func (s *SpheroOllieDriver) SetRGB(r uint8, g uint8, b uint8) {
	fmt.Println("setrgb")
	s.packetChannel <- s.craftPacket([]uint8{r, g, b, 0x01}, 0x02, 0x20)
}

// Tells the Ollie to roll
func (s *SpheroOllieDriver) Roll(speed uint8, heading uint16) {
	fmt.Println("roll", speed, heading)
}

// Tells the Ollie to stop
func (s *SpheroOllieDriver) Stop() {
	s.Roll(0, 0)
}

func (s *SpheroOllieDriver) write(packet *packet) (err error) {
	buf := append(packet.header, packet.body...)
	buf = append(buf, packet.checksum)
	err = s.adaptor().WriteCharacteristic(RobotControlService, CommandsCharacteristic, buf)
	if err != nil {
		fmt.Println("send command error:", err)
		return err
	}

	s.seq++
	return
}

func (s *SpheroOllieDriver) craftPacket(body []uint8, did byte, cid byte) *packet {
	packet := new(packet)
	packet.body = body
	dlen := len(packet.body) + 1
	packet.header = []uint8{0xFF, 0xFF, did, cid, s.seq, uint8(dlen)}
	packet.checksum = s.calculateChecksum(packet)
	return packet
}

func (s *SpheroOllieDriver) calculateChecksum(packet *packet) uint8 {
	buf := append(packet.header, packet.body...)
	return calculateChecksum(buf[2:])
}

func calculateChecksum(buf []byte) byte {
	var calculatedChecksum uint16
	for i := range buf {
		calculatedChecksum += uint16(buf[i])
	}
	return uint8(^(calculatedChecksum % 256))
}
<|endoftext|>


<commit_before>package main

import (
    "fmt"
    "menteslibres.net/gosexy/redis"
)

func main() {

    var client  *redis.Client
    var err error

    client = redis.New()

    err = client.Connect("127.0.0.1",6379)

    if err != nil {
        fmt.Println("Connect failed: %s\n")
        return
    }

    fmt.Println("Connected to redis-server.")

    fmt.Println("Welcome to my Coffee Counter. You can see how many times I've made coffee with the given brew type. Then you can increment one when you've made another cup")
  // Get list of Current coffee Items
    cl,err := client.LLen("coffees")// cl is a variable to store length of "coffees"
    // grab "coffees" list and store it in "Coffees" array
    Coffees := make([]string,int(cl))
    Coffees,err = client.LRange("coffees",0,-1)
    //print out each of the items
    var value string
    var n int64
    for n = 0; n < cl; n++ {
        value,err = client.Get(Coffees[n])
        option := string(n+1) + ". " + Coffees[n] + " : " + value + " Cups"
        fmt.Println(option)
    }

    client.Quit()

}

<commit_msg>Working on output formatting<commit_after>package main

import (
    "fmt"
    "menteslibres.net/gosexy/redis"
)

func main() {

    var client  *redis.Client
    var err error

    client = redis.New()

    err = client.Connect("127.0.0.1",6379)

    if err != nil {
        fmt.Println("Connect failed: %s\n")
        return
    }

    fmt.Println("Connected to redis-server.")

    fmt.Println("Welcome to my Coffee Counter. You can see how many times I've made coffee with the given brew type. Then you can increment one when you've made another cup")
  // Get list of Current coffee Items
    cl,err := client.LLen("coffees")// cl is a variable to store length of "coffees"
    // grab "coffees" list and store it in "Coffees" array
    Coffees := make([]string,int(cl))
    Coffees,err = client.LRange("coffees",0,-1)
    //print out each of the items
    var value string
    var n int64
    for n = 0; n < cl; n++ {
        value,err = client.Get(Coffees[n])
        option := string(int(n+1)) + ". " + Coffees[n] + " : " + value + " Cups"
        fmt.Println(option)
    }

    client.Quit()

}

<|endoftext|>


<commit_before>// +build windows

package collector

import (
	"strings"

	"github.com/StackExchange/wmi"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/common/log"
	"gopkg.in/alecthomas/kingpin.v2"
)

func init() {
	Factories["msmq"] = NewMSMQCollector
}

var (
	msmqWhereClause = kingpin.Flag("collector.msmq.msmq-where", "WQL 'where' clause to use in WMI metrics query. Limits the response to the msmqs you specify and reduces the size of the response.").String()
)

// A Win32_PerfRawData_MSMQ_MSMQQueueCollector is a Prometheus collector for WMI Win32_PerfRawData_MSMQ_MSMQQueue metrics
type Win32_PerfRawData_MSMQ_MSMQQueueCollector struct {
	BytesinJournalQueue    *prometheus.Desc
	BytesinQueue           *prometheus.Desc
	MessagesinJournalQueue *prometheus.Desc
	MessagesinQueue        *prometheus.Desc

	queryWhereClause string
}

// NewWin32_PerfRawData_MSMQ_MSMQQueueCollector ...
func NewMSMQCollector() (Collector, error) {
	const subsystem = "msmq"

	if *msmqWhereClause != "" {
		log.Warn("No where-clause specified for msmq collector. This will generate a very large number of metrics!")
	}

	return &Win32_PerfRawData_MSMQ_MSMQQueueCollector{
		BytesinJournalQueue: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "bytes_in_journal_queue"),
			"Size of queue journal in bytes",
			[]string{"name"},
			nil,
		),
		BytesinQueue: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "bytes_in_queue"),
			"Size of queue in bytes",
			[]string{"name"},
			nil,
		),
		MessagesinJournalQueue: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "messages_in_journal_queue"),
			"Count messages in queue journal",
			[]string{"name"},
			nil,
		),
		MessagesinQueue: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "messages_in_queue"),
			"Count messages in queue",
			[]string{"name"},
			nil,
		),
		queryWhereClause: *msmqWhereClause,
	}, nil
}

// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *Win32_PerfRawData_MSMQ_MSMQQueueCollector) Collect(ch chan<- prometheus.Metric) error {
	if desc, err := c.collect(ch); err != nil {
		log.Error("failed collecting msmq metrics:", desc, err)
		return err
	}
	return nil
}

type Win32_PerfRawData_MSMQ_MSMQQueue struct {
	Name string

	BytesinJournalQueue    uint64
	BytesinQueue           uint64
	MessagesinJournalQueue uint64
	MessagesinQueue        uint64
}

func (c *Win32_PerfRawData_MSMQ_MSMQQueueCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
	var dst []Win32_PerfRawData_MSMQ_MSMQQueue
	q := queryAllWhere(&dst, c.queryWhereClause)
	if err := wmi.Query(q, &dst); err != nil {
		return nil, err
	}

	for _, msmq := range dst {

		if msmq.Name == "Computer Queues" {
			continue
		}

		ch <- prometheus.MustNewConstMetric(
			c.BytesinJournalQueue,
			prometheus.GaugeValue,
			float64(msmq.BytesinJournalQueue),
			strings.ToLower(msmq.Name),
		)
		ch <- prometheus.MustNewConstMetric(
			c.BytesinQueue,
			prometheus.GaugeValue,
			float64(msmq.BytesinQueue),
			strings.ToLower(msmq.Name),
		)
		ch <- prometheus.MustNewConstMetric(
			c.MessagesinJournalQueue,
			prometheus.GaugeValue,
			float64(msmq.MessagesinJournalQueue),
			strings.ToLower(msmq.Name),
		)
		ch <- prometheus.MustNewConstMetric(
			c.MessagesinQueue,
			prometheus.GaugeValue,
			float64(msmq.MessagesinQueue),
			strings.ToLower(msmq.Name),
		)
	}
	return nil, nil
}
<commit_msg>msmq - incorrect condition to log a warning<commit_after>// +build windows

package collector

import (
	"strings"

	"github.com/StackExchange/wmi"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/common/log"
	"gopkg.in/alecthomas/kingpin.v2"
)

func init() {
	Factories["msmq"] = NewMSMQCollector
}

var (
	msmqWhereClause = kingpin.Flag("collector.msmq.msmq-where", "WQL 'where' clause to use in WMI metrics query. Limits the response to the msmqs you specify and reduces the size of the response.").String()
)

// A Win32_PerfRawData_MSMQ_MSMQQueueCollector is a Prometheus collector for WMI Win32_PerfRawData_MSMQ_MSMQQueue metrics
type Win32_PerfRawData_MSMQ_MSMQQueueCollector struct {
	BytesinJournalQueue    *prometheus.Desc
	BytesinQueue           *prometheus.Desc
	MessagesinJournalQueue *prometheus.Desc
	MessagesinQueue        *prometheus.Desc

	queryWhereClause string
}

// NewWin32_PerfRawData_MSMQ_MSMQQueueCollector ...
func NewMSMQCollector() (Collector, error) {
	const subsystem = "msmq"

	if *msmqWhereClause == "" {
		log.Warn("No where-clause specified for msmq collector. This will generate a very large number of metrics!")
	}

	return &Win32_PerfRawData_MSMQ_MSMQQueueCollector{
		BytesinJournalQueue: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "bytes_in_journal_queue"),
			"Size of queue journal in bytes",
			[]string{"name"},
			nil,
		),
		BytesinQueue: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "bytes_in_queue"),
			"Size of queue in bytes",
			[]string{"name"},
			nil,
		),
		MessagesinJournalQueue: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "messages_in_journal_queue"),
			"Count messages in queue journal",
			[]string{"name"},
			nil,
		),
		MessagesinQueue: prometheus.NewDesc(
			prometheus.BuildFQName(Namespace, subsystem, "messages_in_queue"),
			"Count messages in queue",
			[]string{"name"},
			nil,
		),
		queryWhereClause: *msmqWhereClause,
	}, nil
}

// Collect sends the metric values for each metric
// to the provided prometheus Metric channel.
func (c *Win32_PerfRawData_MSMQ_MSMQQueueCollector) Collect(ch chan<- prometheus.Metric) error {
	if desc, err := c.collect(ch); err != nil {
		log.Error("failed collecting msmq metrics:", desc, err)
		return err
	}
	return nil
}

type Win32_PerfRawData_MSMQ_MSMQQueue struct {
	Name string

	BytesinJournalQueue    uint64
	BytesinQueue           uint64
	MessagesinJournalQueue uint64
	MessagesinQueue        uint64
}

func (c *Win32_PerfRawData_MSMQ_MSMQQueueCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) {
	var dst []Win32_PerfRawData_MSMQ_MSMQQueue
	q := queryAllWhere(&dst, c.queryWhereClause)
	if err := wmi.Query(q, &dst); err != nil {
		return nil, err
	}

	for _, msmq := range dst {

		if msmq.Name == "Computer Queues" {
			continue
		}

		ch <- prometheus.MustNewConstMetric(
			c.BytesinJournalQueue,
			prometheus.GaugeValue,
			float64(msmq.BytesinJournalQueue),
			strings.ToLower(msmq.Name),
		)
		ch <- prometheus.MustNewConstMetric(
			c.BytesinQueue,
			prometheus.GaugeValue,
			float64(msmq.BytesinQueue),
			strings.ToLower(msmq.Name),
		)
		ch <- prometheus.MustNewConstMetric(
			c.MessagesinJournalQueue,
			prometheus.GaugeValue,
			float64(msmq.MessagesinJournalQueue),
			strings.ToLower(msmq.Name),
		)
		ch <- prometheus.MustNewConstMetric(
			c.MessagesinQueue,
			prometheus.GaugeValue,
			float64(msmq.MessagesinQueue),
			strings.ToLower(msmq.Name),
		)
	}
	return nil, nil
}
<|endoftext|>


<commit_before>package command

import (
	"bytes"
	"encoding/gob"
	"fmt"
	"strings"
	"time"

	"github.com/hashicorp/nomad/api"
	"github.com/hashicorp/nomad/nomad/structs"
)

type StatusCommand struct {
	Meta
}

func (c *StatusCommand) Help() string {
	helpText := `
Usage: nomad status [options] [job]

  Display status information about jobs. If no job ID is given,
  a list of all known jobs will be dumped.

General Options:

  ` + generalOptionsUsage() + `

Status Options:

  -short
    Display short output. Used only when a single job is being
    queried, and drops verbose information about allocations
    and evaluations.
`
	return strings.TrimSpace(helpText)
}

func (c *StatusCommand) Synopsis() string {
	return "Display status information about jobs"
}

func (c *StatusCommand) Run(args []string) int {
	var short bool

	flags := c.Meta.FlagSet("status", FlagSetClient)
	flags.Usage = func() { c.Ui.Output(c.Help()) }
	flags.BoolVar(&short, "short", false, "")

	if err := flags.Parse(args); err != nil {
		return 1
	}

	// Check that we either got no jobs or exactly one.
	args = flags.Args()
	if len(args) > 1 {
		c.Ui.Error(c.Help())
		return 1
	}

	// Get the HTTP client
	client, err := c.Meta.Client()
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
		return 1
	}

	// Invoke list mode if no job ID.
	if len(args) == 0 {
		jobs, _, err := client.Jobs().List(nil)
		if err != nil {
			c.Ui.Error(fmt.Sprintf("Error querying jobs: %s", err))
			return 1
		}

		// No output if we have no jobs
		if len(jobs) == 0 {
			return 0
		}

		out := make([]string, len(jobs)+1)
		out[0] = "ID|Type|Priority|Status"
		for i, job := range jobs {
			out[i+1] = fmt.Sprintf("%s|%s|%d|%s",
				job.ID,
				job.Type,
				job.Priority,
				job.Status)
		}
		c.Ui.Output(formatList(out))
		return 0
	}

	// Try querying the job
	jobID := args[0]
	job, _, err := client.Jobs().Info(jobID, nil)
	if err != nil {
		jobs, _, err := client.Jobs().PrefixList(jobID)
		if err != nil {
			c.Ui.Error(fmt.Sprintf("Error querying job: %s", err))
			return 1
		}
		if len(jobs) == 0 {
			c.Ui.Error(fmt.Sprintf("No job(s) with prefix or id %q found", jobID))
			return 1
		}
		if len(jobs) > 1 {
			out := make([]string, len(jobs)+1)
			out[0] = "ID|Type|Priority|Status"
			for i, job := range jobs {
				out[i+1] = fmt.Sprintf("%s|%s|%d|%s",
					job.ID,
					job.Type,
					job.Priority,
					job.Status)
			}
			c.Ui.Output(fmt.Sprintf("Prefix matched multiple jobs\n\n%s", formatList(out)))
			return 0
		}
		// Prefix lookup matched a single job
		job, _, err = client.Jobs().Info(jobs[0].ID, nil)
		if err != nil {
			c.Ui.Error(fmt.Sprintf("Error querying job: %s", err))
			return 1
		}
	}

	// Check if it is periodic
	sJob, err := convertApiJob(job)
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Error converting job: %s", err))
		return 1
	}
	periodic := sJob.IsPeriodic()

	// Format the job info
	basic := []string{
		fmt.Sprintf("ID|%s", job.ID),
		fmt.Sprintf("Name|%s", job.Name),
		fmt.Sprintf("Type|%s", job.Type),
		fmt.Sprintf("Priority|%d", job.Priority),
		fmt.Sprintf("Datacenters|%s", strings.Join(job.Datacenters, ",")),
		fmt.Sprintf("Status|%s", job.Status),
		fmt.Sprintf("Periodic|%v", periodic),
	}

	if periodic {
		basic = append(basic, fmt.Sprintf("Next Periodic Launch|%v",
			sJob.Periodic.Next(time.Now())))
	}

	c.Ui.Output(formatKV(basic))

	// Exit early
	if short {
		return 0
	}

	// Print periodic job information
	if periodic {
		if err := c.outputPeriodicInfo(client, job); err != nil {
			c.Ui.Error(err.Error())
			return 1
		}

		return 0
	}

	if err := c.outputJobInfo(client, job); err != nil {
		c.Ui.Error(err.Error())
		return 1
	}

	return 0
}

// outputPeriodicInfo prints information about the passed periodic job. If a
// request fails, an error is returned.
func (c *StatusCommand) outputPeriodicInfo(client *api.Client, job *api.Job) error {
	// Generate the prefix that matches launched jobs from the periodic job.
	prefix := fmt.Sprintf("%s%s", job.ID, structs.PeriodicLaunchSuffix)
	children, _, err := client.Jobs().PrefixList(prefix)
	if err != nil {
		return fmt.Errorf("Error querying job: %s", err)
	}

	if len(children) == 0 {
		c.Ui.Output("\nNo instances of periodic job found")
		return nil
	}

	out := make([]string, 1)
	out[0] = "ID|Status"
	for _, child := range children {
		// Ensure that we are only showing jobs whose parent is the requested
		// job.
		if child.ParentID != job.ID {
			continue
		}

		out = append(out, fmt.Sprintf("%s|%s",
			child.ID,
			child.Status))
	}

	c.Ui.Output(fmt.Sprintf("\nPreviously launched jobs:\n%s", formatList(out)))
	return nil
}

// outputJobInfo prints information about the passed non-periodic job. If a
// request fails, an error is returned.
func (c *StatusCommand) outputJobInfo(client *api.Client, job *api.Job) error {
	var evals, allocs []string

	// Query the evaluations
	jobEvals, _, err := client.Jobs().Evaluations(job.ID, nil)
	if err != nil {
		return fmt.Errorf("Error querying job evaluations: %s", err)
	}

	// Query the allocations
	jobAllocs, _, err := client.Jobs().Allocations(job.ID, nil)
	if err != nil {
		return fmt.Errorf("Error querying job allocations: %s", err)
	}

	// Format the evals
	evals = make([]string, len(jobEvals)+1)
	evals[0] = "ID|Priority|TriggeredBy|Status"
	for i, eval := range jobEvals {
		evals[i+1] = fmt.Sprintf("%s|%d|%s|%s",
			eval.ID,
			eval.Priority,
			eval.TriggeredBy,
			eval.Status)
	}

	// Format the allocs
	allocs = make([]string, len(jobAllocs)+1)
	allocs[0] = "ID|EvalID|NodeID|TaskGroup|Desired|Status"
	for i, alloc := range jobAllocs {
		allocs[i+1] = fmt.Sprintf("%s|%s|%s|%s|%s|%s",
			alloc.ID,
			alloc.EvalID,
			alloc.NodeID,
			alloc.TaskGroup,
			alloc.DesiredStatus,
			alloc.ClientStatus)
	}

	c.Ui.Output("\n==> Evaluations")
	c.Ui.Output(formatList(evals))
	c.Ui.Output("\n==> Allocations")
	c.Ui.Output(formatList(allocs))
	return nil
}

// convertApiJob is used to take a *api.Job and convert it to an *struct.Job.
// This function is just a hammer and probably needs to be revisited.
func convertApiJob(in *api.Job) (*structs.Job, error) {
	gob.Register(map[string]interface{}{})
	gob.Register([]interface{}{})
	var structJob *structs.Job
	buf := new(bytes.Buffer)
	if err := gob.NewEncoder(buf).Encode(in); err != nil {
		return nil, err
	}
	if err := gob.NewDecoder(buf).Decode(&structJob); err != nil {
		return nil, err
	}
	return structJob, nil
}
<commit_msg>Add message to nomad status when there are no jobs<commit_after>package command

import (
	"bytes"
	"encoding/gob"
	"fmt"
	"strings"
	"time"

	"github.com/hashicorp/nomad/api"
	"github.com/hashicorp/nomad/nomad/structs"
)

type StatusCommand struct {
	Meta
}

func (c *StatusCommand) Help() string {
	helpText := `
Usage: nomad status [options] [job]

  Display status information about jobs. If no job ID is given,
  a list of all known jobs will be dumped.

General Options:

  ` + generalOptionsUsage() + `

Status Options:

  -short
    Display short output. Used only when a single job is being
    queried, and drops verbose information about allocations
    and evaluations.
`
	return strings.TrimSpace(helpText)
}

func (c *StatusCommand) Synopsis() string {
	return "Display status information about jobs"
}

func (c *StatusCommand) Run(args []string) int {
	var short bool

	flags := c.Meta.FlagSet("status", FlagSetClient)
	flags.Usage = func() { c.Ui.Output(c.Help()) }
	flags.BoolVar(&short, "short", false, "")

	if err := flags.Parse(args); err != nil {
		return 1
	}

	// Check that we either got no jobs or exactly one.
	args = flags.Args()
	if len(args) > 1 {
		c.Ui.Error(c.Help())
		return 1
	}

	// Get the HTTP client
	client, err := c.Meta.Client()
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
		return 1
	}

	// Invoke list mode if no job ID.
	if len(args) == 0 {
		jobs, _, err := client.Jobs().List(nil)
		if err != nil {
			c.Ui.Error(fmt.Sprintf("Error querying jobs: %s", err))
			return 1
		}

		// No output if we have no jobs
		if len(jobs) == 0 {
			c.Ui.Output("No running jobs")
			return 0
		}

		out := make([]string, len(jobs)+1)
		out[0] = "ID|Type|Priority|Status"
		for i, job := range jobs {
			out[i+1] = fmt.Sprintf("%s|%s|%d|%s",
				job.ID,
				job.Type,
				job.Priority,
				job.Status)
		}
		c.Ui.Output(formatList(out))
		return 0
	}

	// Try querying the job
	jobID := args[0]
	job, _, err := client.Jobs().Info(jobID, nil)
	if err != nil {
		jobs, _, err := client.Jobs().PrefixList(jobID)
		if err != nil {
			c.Ui.Error(fmt.Sprintf("Error querying job: %s", err))
			return 1
		}
		if len(jobs) == 0 {
			c.Ui.Error(fmt.Sprintf("No job(s) with prefix or id %q found", jobID))
			return 1
		}
		if len(jobs) > 1 {
			out := make([]string, len(jobs)+1)
			out[0] = "ID|Type|Priority|Status"
			for i, job := range jobs {
				out[i+1] = fmt.Sprintf("%s|%s|%d|%s",
					job.ID,
					job.Type,
					job.Priority,
					job.Status)
			}
			c.Ui.Output(fmt.Sprintf("Prefix matched multiple jobs\n\n%s", formatList(out)))
			return 0
		}
		// Prefix lookup matched a single job
		job, _, err = client.Jobs().Info(jobs[0].ID, nil)
		if err != nil {
			c.Ui.Error(fmt.Sprintf("Error querying job: %s", err))
			return 1
		}
	}

	// Check if it is periodic
	sJob, err := convertApiJob(job)
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Error converting job: %s", err))
		return 1
	}
	periodic := sJob.IsPeriodic()

	// Format the job info
	basic := []string{
		fmt.Sprintf("ID|%s", job.ID),
		fmt.Sprintf("Name|%s", job.Name),
		fmt.Sprintf("Type|%s", job.Type),
		fmt.Sprintf("Priority|%d", job.Priority),
		fmt.Sprintf("Datacenters|%s", strings.Join(job.Datacenters, ",")),
		fmt.Sprintf("Status|%s", job.Status),
		fmt.Sprintf("Periodic|%v", periodic),
	}

	if periodic {
		basic = append(basic, fmt.Sprintf("Next Periodic Launch|%v",
			sJob.Periodic.Next(time.Now())))
	}

	c.Ui.Output(formatKV(basic))

	// Exit early
	if short {
		return 0
	}

	// Print periodic job information
	if periodic {
		if err := c.outputPeriodicInfo(client, job); err != nil {
			c.Ui.Error(err.Error())
			return 1
		}

		return 0
	}

	if err := c.outputJobInfo(client, job); err != nil {
		c.Ui.Error(err.Error())
		return 1
	}

	return 0
}

// outputPeriodicInfo prints information about the passed periodic job. If a
// request fails, an error is returned.
func (c *StatusCommand) outputPeriodicInfo(client *api.Client, job *api.Job) error {
	// Generate the prefix that matches launched jobs from the periodic job.
	prefix := fmt.Sprintf("%s%s", job.ID, structs.PeriodicLaunchSuffix)
	children, _, err := client.Jobs().PrefixList(prefix)
	if err != nil {
		return fmt.Errorf("Error querying job: %s", err)
	}

	if len(children) == 0 {
		c.Ui.Output("\nNo instances of periodic job found")
		return nil
	}

	out := make([]string, 1)
	out[0] = "ID|Status"
	for _, child := range children {
		// Ensure that we are only showing jobs whose parent is the requested
		// job.
		if child.ParentID != job.ID {
			continue
		}

		out = append(out, fmt.Sprintf("%s|%s",
			child.ID,
			child.Status))
	}

	c.Ui.Output(fmt.Sprintf("\nPreviously launched jobs:\n%s", formatList(out)))
	return nil
}

// outputJobInfo prints information about the passed non-periodic job. If a
// request fails, an error is returned.
func (c *StatusCommand) outputJobInfo(client *api.Client, job *api.Job) error {
	var evals, allocs []string

	// Query the evaluations
	jobEvals, _, err := client.Jobs().Evaluations(job.ID, nil)
	if err != nil {
		return fmt.Errorf("Error querying job evaluations: %s", err)
	}

	// Query the allocations
	jobAllocs, _, err := client.Jobs().Allocations(job.ID, nil)
	if err != nil {
		return fmt.Errorf("Error querying job allocations: %s", err)
	}

	// Format the evals
	evals = make([]string, len(jobEvals)+1)
	evals[0] = "ID|Priority|TriggeredBy|Status"
	for i, eval := range jobEvals {
		evals[i+1] = fmt.Sprintf("%s|%d|%s|%s",
			eval.ID,
			eval.Priority,
			eval.TriggeredBy,
			eval.Status)
	}

	// Format the allocs
	allocs = make([]string, len(jobAllocs)+1)
	allocs[0] = "ID|EvalID|NodeID|TaskGroup|Desired|Status"
	for i, alloc := range jobAllocs {
		allocs[i+1] = fmt.Sprintf("%s|%s|%s|%s|%s|%s",
			alloc.ID,
			alloc.EvalID,
			alloc.NodeID,
			alloc.TaskGroup,
			alloc.DesiredStatus,
			alloc.ClientStatus)
	}

	c.Ui.Output("\n==> Evaluations")
	c.Ui.Output(formatList(evals))
	c.Ui.Output("\n==> Allocations")
	c.Ui.Output(formatList(allocs))
	return nil
}

// convertApiJob is used to take a *api.Job and convert it to an *struct.Job.
// This function is just a hammer and probably needs to be revisited.
func convertApiJob(in *api.Job) (*structs.Job, error) {
	gob.Register(map[string]interface{}{})
	gob.Register([]interface{}{})
	var structJob *structs.Job
	buf := new(bytes.Buffer)
	if err := gob.NewEncoder(buf).Encode(in); err != nil {
		return nil, err
	}
	if err := gob.NewDecoder(buf).Decode(&structJob); err != nil {
		return nil, err
	}
	return structJob, nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"net/http"
	"text/template"
)

type CommandCenter struct {
	server
	tld     string
	apps    []*App
	servers []Server
}

func NewCommandCenter(tld, appsDir string, aliases map[string]int) *CommandCenter {
	cc := &CommandCenter{tld: tld}
	cc.name = "bam"
	cc.servers = createServers(aliases)
	cc.apps = LoadApps(appsDir)
	return cc
}

func (cc *CommandCenter) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Header().Add("Content-Type", "text/html")
	data := map[string]interface{}{
		"Tld":     cc.tld,
		"Servers": cc.servers,
	}
	tmpl, err := template.New("-").Parse(baseHTML)
	log.Print(err)
	tmpl.Execute(w, data)
}

func (cc *CommandCenter) Start() error {
	port, _ := FreePort()
	cc.port = port
	go func() {
		for _, app := range cc.apps {
			log.Printf("Starting app %s\n", app.Name())
			go app.Start()
		}
	}()
	return http.ListenAndServe(fmt.Sprintf(":%d", cc.port), cc)
}

func (cc *CommandCenter) List() []Server {
	return cc.servers
}

func createServers(aliases map[string]int) []Server {
	servers := []Server{}
	for name, port := range aliases {
		servers = append(servers, NewServer(name, port))
	}
	return servers
}

const baseHTML = `

    <title>Bam's Command Center</title>

Applications

				{{$tld := .Tld}}
				{{range .Servers}}

{{.Name}}

				{{end}}

`
<commit_msg>show all servers: aliased and apps<commit_after>package main

import (
	"fmt"
	"log"
	"net/http"
	"text/template"
)

type CommandCenter struct {
	server
	tld     string
	apps    []*App
	servers []Server
}

var tmpl *template.Template

func init() {
	t, err := template.New("-").Parse(baseHTML)
	fail(err)
	tmpl = t
}

func NewCommandCenter(tld, appsDir string, aliases map[string]int) *CommandCenter {
	cc := &CommandCenter{tld: tld}
	cc.name = "bam"
	cc.servers = createAliasedServers(aliases)
	cc.apps = LoadApps(appsDir)
	return cc
}

func (cc *CommandCenter) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Header().Add("Content-Type", "text/html")
	data := map[string]interface{}{
		"Tld":     cc.tld,
		"Servers": cc.List(),
	}
	tmpl.Execute(w, data)
}

func (cc *CommandCenter) Start() error {
	port, _ := FreePort()
	cc.port = port
	go func() {
		for _, app := range cc.apps {
			log.Printf("Starting app %s\n", app.Name())
			go app.Start()
		}
	}()
	return http.ListenAndServe(fmt.Sprintf(":%d", cc.port), cc)
}

func (cc *CommandCenter) List() []Server {
	s := cc.servers
	s = append(s, cc)
	for _, app := range cc.apps {
		s = append(s, app)
	}
	return s
}

func createAliasedServers(aliases map[string]int) []Server {
	servers := []Server{}
	for name, port := range aliases {
		servers = append(servers, NewServer(name, port))
	}
	return servers
}

const baseHTML = `

    <title>Bam's Command Center</title>

Applications

				{{$tld := .Tld}}
				{{range .Servers}}

{{.Name}}

				{{end}}

`
<|endoftext|>


<commit_before>package runtime

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"reflect"

	"github.com/golang/protobuf/jsonpb"
	"github.com/golang/protobuf/proto"
)

// JSONPb is a Marshaler which marshals/unmarshals into/from JSON
// with the "github.com/golang/protobuf/jsonpb".
// It supports fully functionality of protobuf unlike JSONBuiltin.
type JSONPb jsonpb.Marshaler

// ContentType always returns "application/json".
func (*JSONPb) ContentType() string {
	return "application/json"
}

// Marshal marshals "v" into JSON
// Currently it can marshal only proto.Message.
// TODO(yugui) Support fields of primitive types in a message.
func (j *JSONPb) Marshal(v interface{}) ([]byte, error) {
	if _, ok := v.(proto.Message); !ok {
		return j.marshalNonProtoField(v)
	}

	var buf bytes.Buffer
	if err := j.marshalTo(&buf, v); err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

func (j *JSONPb) marshalTo(w io.Writer, v interface{}) error {
	p, ok := v.(proto.Message)
	if !ok {
		buf, err := j.marshalNonProtoField(v)
		if err != nil {
			return err
		}
		_, err = w.Write(buf)
		return err
	}
	return (*jsonpb.Marshaler)(j).Marshal(w, p)
}

// marshalNonProto marshals a non-message field of a protobuf message.
// This function does not correctly marshals arbitary data structure into JSON,
// but it is only capable of marshaling non-message field values of protobuf,
// i.e. primitive types, enums; pointers to primitives or enums; maps from
// integer/string types to primitives/enums/pointers to messages.
func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) {
	rv := reflect.ValueOf(v)
	for rv.Kind() == reflect.Ptr {
		if rv.IsNil() {
			return []byte("null"), nil
		}
		rv = rv.Elem()
	}

	if rv.Kind() == reflect.Map {
		m := make(map[string]*json.RawMessage)
		for _, k := range rv.MapKeys() {
			buf, err := j.Marshal(rv.MapIndex(k).Interface())
			if err != nil {
				return nil, err
			}
			m[fmt.Sprintf("%v", k.Interface())] = (*json.RawMessage)(&buf)
		}
		if j.Indent != "" {
			return json.MarshalIndent(m, "", j.Indent)
		}
		return json.Marshal(m)
	}
	if enum, ok := rv.Interface().(protoEnum); ok && !j.EnumsAsInts {
		return json.Marshal(enum.String())
	}
	return json.Marshal(rv.Interface())
}

// Unmarshal unmarshals JSON "data" into "v"
// Currently it can marshal only proto.Message.
// TODO(yugui) Support fields of primitive types in a message.
func (j *JSONPb) Unmarshal(data []byte, v interface{}) error {
	return unmarshalJSONPb(data, v)
}

// NewDecoder returns a Decoder which reads JSON stream from "r".
func (j *JSONPb) NewDecoder(r io.Reader) Decoder {
	d := json.NewDecoder(r)
	return DecoderFunc(func(v interface{}) error { return decodeJSONPb(d, v) })
}

// NewEncoder returns an Encoder which writes JSON stream into "w".
func (j *JSONPb) NewEncoder(w io.Writer) Encoder {
	return EncoderFunc(func(v interface{}) error { return j.marshalTo(w, v) })
}

func unmarshalJSONPb(data []byte, v interface{}) error {
	d := json.NewDecoder(bytes.NewReader(data))
	return decodeJSONPb(d, v)
}

func decodeJSONPb(d *json.Decoder, v interface{}) error {
	p, ok := v.(proto.Message)
	if !ok {
		return decodeNonProtoField(d, v)
	}
	unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: true}
	return unmarshaler.UnmarshalNext(d, p)
}

func decodeNonProtoField(d *json.Decoder, v interface{}) error {
	rv := reflect.ValueOf(v)
	if rv.Kind() != reflect.Ptr {
		return fmt.Errorf("%T is not a pointer", v)
	}
	for rv.Kind() == reflect.Ptr {
		if rv.IsNil() {
			rv.Set(reflect.New(rv.Type().Elem()))
		}
		if rv.Type().ConvertibleTo(typeProtoMessage) {
			return jsonpb.UnmarshalNext(d, rv.Interface().(proto.Message))
		}
		rv = rv.Elem()
	}
	if rv.Kind() == reflect.Map {
		if rv.IsNil() {
			rv.Set(reflect.MakeMap(rv.Type()))
		}
		conv, ok := convFromType[rv.Type().Key().Kind()]
		if !ok {
			return fmt.Errorf("unsupported type of map field key: %v", rv.Type().Key())
		}

		m := make(map[string]*json.RawMessage)
		if err := d.Decode(&m); err != nil {
			return err
		}
		for k, v := range m {
			result := conv.Call([]reflect.Value{reflect.ValueOf(k)})
			if err := result[1].Interface(); err != nil {
				return err.(error)
			}
			bk := result[0]
			bv := reflect.New(rv.Type().Elem())
			if err := unmarshalJSONPb([]byte(*v), bv.Interface()); err != nil {
				return err
			}
			rv.SetMapIndex(bk, bv.Elem())
		}
		return nil
	}
	if _, ok := rv.Interface().(protoEnum); ok {
		var repr interface{}
		if err := d.Decode(&repr); err != nil {
			return err
		}
		switch repr.(type) {
		case string:
			// TODO(yugui) Should use proto.StructProperties?
			return fmt.Errorf("unmarshaling of symbolic enum %q not supported: %T", repr, rv.Interface())
		case float64:
			rv.Set(reflect.ValueOf(int32(repr.(float64))).Convert(rv.Type()))
			return nil
		default:
			return fmt.Errorf("cannot assign %#v into Go type %T", repr, rv.Interface())
		}
	}
	return d.Decode(v)
}

type protoEnum interface {
	fmt.Stringer
	EnumDescriptor() ([]byte, []int)
}

var typeProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem()
<commit_msg>Allowing unknown fields in json unmarshal<commit_after>package runtime

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"reflect"

	"github.com/golang/protobuf/jsonpb"
	"github.com/golang/protobuf/proto"
)

// JSONPb is a Marshaler which marshals/unmarshals into/from JSON
// with the "github.com/golang/protobuf/jsonpb".
// It supports fully functionality of protobuf unlike JSONBuiltin.
type JSONPb jsonpb.Marshaler

// ContentType always returns "application/json".
func (*JSONPb) ContentType() string {
	return "application/json"
}

// Marshal marshals "v" into JSON
// Currently it can marshal only proto.Message.
// TODO(yugui) Support fields of primitive types in a message.
func (j *JSONPb) Marshal(v interface{}) ([]byte, error) {
	if _, ok := v.(proto.Message); !ok {
		return j.marshalNonProtoField(v)
	}

	var buf bytes.Buffer
	if err := j.marshalTo(&buf, v); err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

func (j *JSONPb) marshalTo(w io.Writer, v interface{}) error {
	p, ok := v.(proto.Message)
	if !ok {
		buf, err := j.marshalNonProtoField(v)
		if err != nil {
			return err
		}
		_, err = w.Write(buf)
		return err
	}
	return (*jsonpb.Marshaler)(j).Marshal(w, p)
}

// marshalNonProto marshals a non-message field of a protobuf message.
// This function does not correctly marshals arbitary data structure into JSON,
// but it is only capable of marshaling non-message field values of protobuf,
// i.e. primitive types, enums; pointers to primitives or enums; maps from
// integer/string types to primitives/enums/pointers to messages.
func (j *JSONPb) marshalNonProtoField(v interface{}) ([]byte, error) {
	rv := reflect.ValueOf(v)
	for rv.Kind() == reflect.Ptr {
		if rv.IsNil() {
			return []byte("null"), nil
		}
		rv = rv.Elem()
	}

	if rv.Kind() == reflect.Map {
		m := make(map[string]*json.RawMessage)
		for _, k := range rv.MapKeys() {
			buf, err := j.Marshal(rv.MapIndex(k).Interface())
			if err != nil {
				return nil, err
			}
			m[fmt.Sprintf("%v", k.Interface())] = (*json.RawMessage)(&buf)
		}
		if j.Indent != "" {
			return json.MarshalIndent(m, "", j.Indent)
		}
		return json.Marshal(m)
	}
	if enum, ok := rv.Interface().(protoEnum); ok && !j.EnumsAsInts {
		return json.Marshal(enum.String())
	}
	return json.Marshal(rv.Interface())
}

// Unmarshal unmarshals JSON "data" into "v"
// Currently it can marshal only proto.Message.
// TODO(yugui) Support fields of primitive types in a message.
func (j *JSONPb) Unmarshal(data []byte, v interface{}) error {
	return unmarshalJSONPb(data, v)
}

// NewDecoder returns a Decoder which reads JSON stream from "r".
func (j *JSONPb) NewDecoder(r io.Reader) Decoder {
	d := json.NewDecoder(r)
	return DecoderFunc(func(v interface{}) error { return decodeJSONPb(d, v) })
}

// NewEncoder returns an Encoder which writes JSON stream into "w".
func (j *JSONPb) NewEncoder(w io.Writer) Encoder {
	return EncoderFunc(func(v interface{}) error { return j.marshalTo(w, v) })
}

func unmarshalJSONPb(data []byte, v interface{}) error {
	d := json.NewDecoder(bytes.NewReader(data))
	return decodeJSONPb(d, v)
}

func decodeJSONPb(d *json.Decoder, v interface{}) error {
	p, ok := v.(proto.Message)
	if !ok {
		return decodeNonProtoField(d, v)
	}
	unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: true}
	return unmarshaler.UnmarshalNext(d, p)
}

func decodeNonProtoField(d *json.Decoder, v interface{}) error {
	rv := reflect.ValueOf(v)
	if rv.Kind() != reflect.Ptr {
		return fmt.Errorf("%T is not a pointer", v)
	}
	for rv.Kind() == reflect.Ptr {
		if rv.IsNil() {
			rv.Set(reflect.New(rv.Type().Elem()))
		}
		if rv.Type().ConvertibleTo(typeProtoMessage) {
			unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: true}
			return unmarshaler.UnmarshalNext(d, rv.Interface().(proto.Message))
		}
		rv = rv.Elem()
	}
	if rv.Kind() == reflect.Map {
		if rv.IsNil() {
			rv.Set(reflect.MakeMap(rv.Type()))
		}
		conv, ok := convFromType[rv.Type().Key().Kind()]
		if !ok {
			return fmt.Errorf("unsupported type of map field key: %v", rv.Type().Key())
		}

		m := make(map[string]*json.RawMessage)
		if err := d.Decode(&m); err != nil {
			return err
		}
		for k, v := range m {
			result := conv.Call([]reflect.Value{reflect.ValueOf(k)})
			if err := result[1].Interface(); err != nil {
				return err.(error)
			}
			bk := result[0]
			bv := reflect.New(rv.Type().Elem())
			if err := unmarshalJSONPb([]byte(*v), bv.Interface()); err != nil {
				return err
			}
			rv.SetMapIndex(bk, bv.Elem())
		}
		return nil
	}
	if _, ok := rv.Interface().(protoEnum); ok {
		var repr interface{}
		if err := d.Decode(&repr); err != nil {
			return err
		}
		switch repr.(type) {
		case string:
			// TODO(yugui) Should use proto.StructProperties?
			return fmt.Errorf("unmarshaling of symbolic enum %q not supported: %T", repr, rv.Interface())
		case float64:
			rv.Set(reflect.ValueOf(int32(repr.(float64))).Convert(rv.Type()))
			return nil
		default:
			return fmt.Errorf("cannot assign %#v into Go type %T", repr, rv.Interface())
		}
	}
	return d.Decode(v)
}

type protoEnum interface {
	fmt.Stringer
	EnumDescriptor() ([]byte, []int)
}

var typeProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem()
<|endoftext|>


<commit_before>package awsimages

import (
	"errors"
	"fmt"
	"log"
	"sync"
	"time"

	"github.com/awslabs/aws-sdk-go/aws"
	"github.com/awslabs/aws-sdk-go/service/ec2"
	"github.com/hashicorp/go-multierror"
)

type multiFunc func(svc *ec2.EC2, images []string) error

// multiCall calls the given function concurrently for each region. It fetches
// and matches the region to each image automatically.
func (a *AwsImages) multiCall(fn multiFunc, images ...string) error {
	// for one region just assume all image ids belong to the this region
	// (which `list` returns already)
	if len(a.services.regions) == 1 {
		svc, err := a.singleSvc()
		if err != nil {
			return err
		}

		return fn(svc, images)
	}

	// so we have multiple regions, the given images might belong to different
	// regions. Fetch all images and match each image id to the given region.
	matchedImages, err := a.matchImages(images...)
	if err != nil {
		return err
	}

	var (
		wg          sync.WaitGroup
		mu          sync.Mutex // protects multiErrors
		multiErrors error
	)

	for r, i := range matchedImages {
		wg.Add(1)
		go func(region string, images []string) {
			defer wg.Done()

			svc, err := a.svcFromRegion(region)
			if err != nil {
				mu.Lock()
				multiErrors = multierror.Append(multiErrors, err)
				mu.Unlock()
				return
			}

			if err := fn(svc, images); err != nil {
				mu.Lock()
				multiErrors = multierror.Append(multiErrors, err)
				mu.Unlock()
			}
		}(r, i)
	}

	wg.Wait()
	return multiErrors

}

// matchImages matches the given images to their respective regions and returns
// map of region to images.
func (a *AwsImages) matchImages(images ...string) (map[string][]string, error) {
	if err := a.Fetch(nil); err != nil {
		return nil, err
	}

	matchedImages := make(map[string][]string)
	for _, imageId := range images {
		region, err := a.imageRegion(imageId)
		if err != nil {
			return nil, err
		}

		ids := matchedImages[region]
		ids = append(ids, imageId)
		matchedImages[region] = ids
	}

	return matchedImages, nil
}

// singleSvc returns a single *ec2.EC2 service from the list of regions.
func (a *AwsImages) singleSvc() (*ec2.EC2, error) {
	if len(a.services.regions) > 1 {
		return nil, errors.New("multiple regions are available for singleSvc")
	}

	var svc *ec2.EC2
	for _, s := range a.services.regions {
		svc = s
	}

	return svc, nil
}

// svcFromRegion returns a *ec2.EC2 service with the given region
func (a *AwsImages) svcFromRegion(region string) (*ec2.EC2, error) {
	for r, s := range a.services.regions {
		if r == region {
			return s, nil
		}
	}

	return nil, fmt.Errorf("no svc found for region '%s'")
}

// imageRegion returns the given imageId's region
func (a *AwsImages) imageRegion(imageId string) (string, error) {
	if len(a.images) == 0 {
		return "", errors.New("images are not fetched")
	}

	for region, images := range a.images {
		for _, image := range images {
			if *image.ImageID == imageId {
				return region, nil
			}
		}
	}

	return "", fmt.Errorf("no region found for image id '%s'", imageId)
}

// byTime implements sort.Interface for []*ec2.Image based on the CreationDate field.
type byTime []*ec2.Image

func (a byTime) Len() int      { return len(a) }
func (a byTime) Swap(i, j int) { *a[i], *a[j] = *a[j], *a[i] }
func (a byTime) Less(i, j int) bool {
	it, err := time.Parse(time.RFC3339, *a[i].CreationDate)
	if err != nil {
		log.Println("aws: sorting err: ", err)
	}

	jt, err := time.Parse(time.RFC3339, *a[j].CreationDate)
	if err != nil {
		log.Println("aws: sorting err: ", err)
	}

	return it.Before(jt)
}

// stringSlice is an helper method to convert a slice of strings into a slice
// of pointer of strings. Needed for various aws/ec2 commands.
func stringSlice(vals ...string) []*string {
	a := make([]*string, len(vals))

	for i, v := range vals {
		a[i] = aws.String(v)
	}

	return a
}
<commit_msg>awsimages: fix go vet warning<commit_after>package awsimages

import (
	"errors"
	"fmt"
	"log"
	"sync"
	"time"

	"github.com/awslabs/aws-sdk-go/aws"
	"github.com/awslabs/aws-sdk-go/service/ec2"
	"github.com/hashicorp/go-multierror"
)

type multiFunc func(svc *ec2.EC2, images []string) error

// multiCall calls the given function concurrently for each region. It fetches
// and matches the region to each image automatically.
func (a *AwsImages) multiCall(fn multiFunc, images ...string) error {
	// for one region just assume all image ids belong to the this region
	// (which `list` returns already)
	if len(a.services.regions) == 1 {
		svc, err := a.singleSvc()
		if err != nil {
			return err
		}

		return fn(svc, images)
	}

	// so we have multiple regions, the given images might belong to different
	// regions. Fetch all images and match each image id to the given region.
	matchedImages, err := a.matchImages(images...)
	if err != nil {
		return err
	}

	var (
		wg          sync.WaitGroup
		mu          sync.Mutex // protects multiErrors
		multiErrors error
	)

	for r, i := range matchedImages {
		wg.Add(1)
		go func(region string, images []string) {
			defer wg.Done()

			svc, err := a.svcFromRegion(region)
			if err != nil {
				mu.Lock()
				multiErrors = multierror.Append(multiErrors, err)
				mu.Unlock()
				return
			}

			if err := fn(svc, images); err != nil {
				mu.Lock()
				multiErrors = multierror.Append(multiErrors, err)
				mu.Unlock()
			}
		}(r, i)
	}

	wg.Wait()
	return multiErrors

}

// matchImages matches the given images to their respective regions and returns
// map of region to images.
func (a *AwsImages) matchImages(images ...string) (map[string][]string, error) {
	if err := a.Fetch(nil); err != nil {
		return nil, err
	}

	matchedImages := make(map[string][]string)
	for _, imageId := range images {
		region, err := a.imageRegion(imageId)
		if err != nil {
			return nil, err
		}

		ids := matchedImages[region]
		ids = append(ids, imageId)
		matchedImages[region] = ids
	}

	return matchedImages, nil
}

// singleSvc returns a single *ec2.EC2 service from the list of regions.
func (a *AwsImages) singleSvc() (*ec2.EC2, error) {
	if len(a.services.regions) > 1 {
		return nil, errors.New("multiple regions are available for singleSvc")
	}

	var svc *ec2.EC2
	for _, s := range a.services.regions {
		svc = s
	}

	return svc, nil
}

// svcFromRegion returns a *ec2.EC2 service with the given region
func (a *AwsImages) svcFromRegion(region string) (*ec2.EC2, error) {
	for r, s := range a.services.regions {
		if r == region {
			return s, nil
		}
	}

	return nil, fmt.Errorf("no svc found for region '%s'", region)
}

// imageRegion returns the given imageId's region
func (a *AwsImages) imageRegion(imageId string) (string, error) {
	if len(a.images) == 0 {
		return "", errors.New("images are not fetched")
	}

	for region, images := range a.images {
		for _, image := range images {
			if *image.ImageID == imageId {
				return region, nil
			}
		}
	}

	return "", fmt.Errorf("no region found for image id '%s'", imageId)
}

// byTime implements sort.Interface for []*ec2.Image based on the CreationDate field.
type byTime []*ec2.Image

func (a byTime) Len() int      { return len(a) }
func (a byTime) Swap(i, j int) { *a[i], *a[j] = *a[j], *a[i] }
func (a byTime) Less(i, j int) bool {
	it, err := time.Parse(time.RFC3339, *a[i].CreationDate)
	if err != nil {
		log.Println("aws: sorting err: ", err)
	}

	jt, err := time.Parse(time.RFC3339, *a[j].CreationDate)
	if err != nil {
		log.Println("aws: sorting err: ", err)
	}

	return it.Before(jt)
}

// stringSlice is an helper method to convert a slice of strings into a slice
// of pointer of strings. Needed for various aws/ec2 commands.
func stringSlice(vals ...string) []*string {
	a := make([]*string, len(vals))

	for i, v := range vals {
		a[i] = aws.String(v)
	}

	return a
}
<|endoftext|>


<commit_before>// Copyright 2018 The Terraformer Authors.
//
// 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 alicloud

import (
	"github.com/GoogleCloudPlatform/terraformer/terraform_utils"
	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
	"github.com/aliyun/alibaba-cloud-sdk-go/services/pvtz"
)

// PvtzGenerator Struct for generating AliCloud private zone
type PvtzGenerator struct {
	AliCloudService
}

func resourceFromZoneResponse(zone pvtz.Zone) terraform_utils.Resource {
	return terraform_utils.NewResource(
		zone.ZoneId,                    // id
		zone.ZoneId+"__"+zone.ZoneName, // name
		"alicloud_pvtz_zone",
		"alicloud",
		map[string]string{},
		[]string{},
		map[string]interface{}{},
	)
}

// InitResources Gets the list of all pvtz Zone ids and generates resources
func (g *PvtzGenerator) InitResources() error {
	client, err := LoadClientFromProfile()
	if err != nil {
		return err
	}
	remaining := 1
	pageNumber := 1
	pageSize := 10

	allZones := make([]pvtz.Zone, 1)

	for remaining > 0 {
		raw, err := client.WithPvtzClient(func(pvtzClient *pvtz.Client) (interface{}, error) {
			request := pvtz.CreateDescribeZonesRequest()
			request.RegionId = client.RegionId
			request.PageSize = requests.NewInteger(pageSize)
			request.PageNumber = requests.NewInteger(pageNumber)
			return pvtzClient.DescribeZones(request)
		})
		if err != nil {
			return err
		}

		response := raw.(*pvtz.DescribeZonesResponse)
		for _, Zone := range response.Zones.Zone {
			allZones = append(allZones, Zone)

		}
		remaining = response.TotalItems - pageNumber*pageSize
		pageNumber++
	}

	for _, Zone := range allZones {
		resource := resourceFromZoneResponse(Zone)
		g.Resources = append(g.Resources, resource)
	}

	return nil
}
<commit_msg>Added alicloud pvtz zone records<commit_after>// Copyright 2018 The Terraformer Authors.
//
// 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 alicloud

import (
	"strconv"

	"github.com/GoogleCloudPlatform/terraformer/terraform_utils"
	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
	"github.com/aliyun/alibaba-cloud-sdk-go/services/pvtz"
	"github.com/terraform-providers/terraform-provider-alicloud/alicloud/connectivity"
)

// PvtzGenerator Struct for generating AliCloud private zone
type PvtzGenerator struct {
	AliCloudService
}

func resourceFromZoneResponse(zone pvtz.Zone) terraform_utils.Resource {
	return terraform_utils.NewResource(
		zone.ZoneId,                    // id
		zone.ZoneId+"__"+zone.ZoneName, // name
		"alicloud_pvtz_zone",
		"alicloud",
		map[string]string{},
		[]string{},
		map[string]interface{}{},
	)
}

func resourceFromZoneRecordResponse(record pvtz.Record, ZoneID string) terraform_utils.Resource {
	return terraform_utils.NewResource(
		strconv.Itoa(record.RecordId)+":"+ZoneID,     // id
		strconv.Itoa(record.RecordId)+"__"+record.Rr, // name
		"alicloud_pvtz_zone_record",
		"alicloud",
		map[string]string{},
		[]string{},
		map[string]interface{}{},
	)
}

func initZones(client *connectivity.AliyunClient) ([]pvtz.Zone, error) {
	remaining := 1
	pageNumber := 1
	pageSize := 10

	allZones := make([]pvtz.Zone, 1)

	for remaining > 0 {
		raw, err := client.WithPvtzClient(func(pvtzClient *pvtz.Client) (interface{}, error) {
			request := pvtz.CreateDescribeZonesRequest()
			request.RegionId = client.RegionId
			request.PageSize = requests.NewInteger(pageSize)
			request.PageNumber = requests.NewInteger(pageNumber)
			return pvtzClient.DescribeZones(request)
		})
		if err != nil {
			return nil, err
		}

		response := raw.(*pvtz.DescribeZonesResponse)
		for _, Zone := range response.Zones.Zone {
			allZones = append(allZones, Zone)
		}
		remaining = response.TotalItems - pageNumber*pageSize
		pageNumber++
	}
	return allZones, nil
}

func initZoneRecords(client *connectivity.AliyunClient, allZones []pvtz.Zone) ([]pvtz.Record, []string, error) {
	allZoneRecords := make([]pvtz.Record, 1)
	zoneIds := make([]string, 1)

	for _, zone := range allZones {
		remaining := 1
		pageNumber := 1
		pageSize := 10
		if zone.ZoneId == "" {
			continue
		}
		for remaining > 0 {
			raw, err := client.WithPvtzClient(func(pvtzClient *pvtz.Client) (interface{}, error) {
				request := pvtz.CreateDescribeZoneRecordsRequest()
				request.RegionId = client.RegionId
				request.ZoneId = zone.ZoneId
				request.PageSize = requests.NewInteger(pageSize)
				request.PageNumber = requests.NewInteger(pageNumber)
				return pvtzClient.DescribeZoneRecords(request)
			})
			if err != nil {
				return nil, nil, err
			}

			response := raw.(*pvtz.DescribeZoneRecordsResponse)
			for _, zoneRecord := range response.Records.Record {
				allZoneRecords = append(allZoneRecords, zoneRecord)
				zoneIds = append(zoneIds, zone.ZoneId)
			}
			remaining = response.TotalItems - pageNumber*pageSize
			pageNumber++
		}
	}
	return allZoneRecords, zoneIds, nil
}

// InitResources Gets the list of all pvtz Zone ids and generates resources
func (g *PvtzGenerator) InitResources() error {
	client, err := LoadClientFromProfile()
	if err != nil {
		return err
	}

	allZones, err := initZones(client)
	if err != nil {
		return err
	}

	allRecords, zoneIds, err := initZoneRecords(client, allZones)
	if err != nil {
		return err
	}

	for _, Zone := range allZones {
		resource := resourceFromZoneResponse(Zone)
		g.Resources = append(g.Resources, resource)
	}

	for i, record := range allRecords {
		resource := resourceFromZoneRecordResponse(record, zoneIds[i])
		g.Resources = append(g.Resources, resource)
	}

	return nil
}
<|endoftext|>


<commit_before>package command

import (
	"fmt"
	"sort"
	"strings"

	"github.com/hashicorp/nomad/api"
	"github.com/ryanuber/columnize"
)

type ServerMembersCommand struct {
	Meta
}

func (c *ServerMembersCommand) Help() string {
	helpText := `
Usage: nomad server-members [options]

  Display a list of the known servers and their status.

General Options:

  ` + generalOptionsUsage() + `

Agent Members Options:

  -detailed
    Show detailed information about each member. This dumps
    a raw set of tags which shows more information than the
    default output format.
`
	return strings.TrimSpace(helpText)
}

func (c *ServerMembersCommand) Synopsis() string {
	return "Display a list of known servers and their status"
}

func (c *ServerMembersCommand) Run(args []string) int {
	var detailed bool

	flags := c.Meta.FlagSet("server-members", FlagSetClient)
	flags.Usage = func() { c.Ui.Output(c.Help()) }
	flags.BoolVar(&detailed, "detailed", false, "Show detailed output")

	if err := flags.Parse(args); err != nil {
		return 1
	}

	// Check for extra arguments
	args = flags.Args()
	if len(args) != 0 {
		c.Ui.Error(c.Help())
		return 1
	}

	// Get the HTTP client
	client, err := c.Meta.Client()
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
		return 1
	}

	// Query the members
	mem, err := client.Agent().Members()
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Error querying servers: %s", err))
		return 1
	}

	// Sort the members
	sort.Sort(api.AgentMembersNameSort(mem))

	// Determine the leaders per region.
	leaders, err := regionLeaders(client, mem)
	if err != nil && !strings.Contains(err.Error(), "No cluster leader") {
		c.Ui.Error(fmt.Sprintf("Error determining leaders: %s", err))
		return 1
	}

	// Format the list
	var out []string
	if detailed {
		out = detailedOutput(mem)
	} else {
		out = standardOutput(mem, leaders)
	}

	// Dump the list
	c.Ui.Output(columnize.SimpleFormat(out))
	return 0
}

func standardOutput(mem []*api.AgentMember, leaders map[string]string) []string {
	// Format the members list
	members := make([]string, len(mem)+1)
	members[0] = "Name|Address|Port|Status|Leader|Protocol|Build|Datacenter|Region"
	for i, member := range mem {
		reg := member.Tags["region"]
		regLeader, ok := leaders[reg]
		isLeader := false
		if ok {
			if regLeader == fmt.Sprintf("%s:%s", member.Addr, member.Tags["port"]) {

				isLeader = true
			}
		}

		members[i+1] = fmt.Sprintf("%s|%s|%d|%s|%t|%d|%s|%s|%s",
			member.Name,
			member.Addr,
			member.Port,
			member.Status,
			isLeader,
			member.ProtocolCur,
			member.Tags["build"],
			member.Tags["dc"],
			member.Tags["region"])
	}
	return members
}

func detailedOutput(mem []*api.AgentMember) []string {
	// Format the members list
	members := make([]string, len(mem)+1)
	members[0] = "Name|Address|Port|Tags"
	for i, member := range mem {
		// Format the tags
		tagPairs := make([]string, 0, len(member.Tags))
		for k, v := range member.Tags {
			tagPairs = append(tagPairs, fmt.Sprintf("%s=%s", k, v))
		}
		tags := strings.Join(tagPairs, ",")

		members[i+1] = fmt.Sprintf("%s|%s|%d|%s",
			member.Name,
			member.Addr,
			member.Port,
			tags)
	}
	return members
}

// regionLeaders returns a map of regions to the IP of the member that is the
// leader.
func regionLeaders(client *api.Client, mem []*api.AgentMember) (map[string]string, error) {
	// Determine the unique regions.
	leaders := make(map[string]string)
	regions := make(map[string]struct{})
	for _, m := range mem {
		regions[m.Tags["region"]] = struct{}{}
	}

	if len(regions) == 0 {
		return leaders, nil
	}

	status := client.Status()
	for reg := range regions {
		l, err := status.RegionLeader(reg)
		if err != nil {
			return leaders, err
		}
		leaders[reg] = l
	}

	return leaders, nil
}
<commit_msg>Better error handling<commit_after>package command

import (
	"fmt"
	"sort"
	"strings"

	"github.com/hashicorp/nomad/api"
	"github.com/ryanuber/columnize"
)

type ServerMembersCommand struct {
	Meta
}

func (c *ServerMembersCommand) Help() string {
	helpText := `
Usage: nomad server-members [options]

  Display a list of the known servers and their status.

General Options:

  ` + generalOptionsUsage() + `

Agent Members Options:

  -detailed
    Show detailed information about each member. This dumps
    a raw set of tags which shows more information than the
    default output format.
`
	return strings.TrimSpace(helpText)
}

func (c *ServerMembersCommand) Synopsis() string {
	return "Display a list of known servers and their status"
}

func (c *ServerMembersCommand) Run(args []string) int {
	var detailed bool

	flags := c.Meta.FlagSet("server-members", FlagSetClient)
	flags.Usage = func() { c.Ui.Output(c.Help()) }
	flags.BoolVar(&detailed, "detailed", false, "Show detailed output")

	if err := flags.Parse(args); err != nil {
		return 1
	}

	// Check for extra arguments
	args = flags.Args()
	if len(args) != 0 {
		c.Ui.Error(c.Help())
		return 1
	}

	// Get the HTTP client
	client, err := c.Meta.Client()
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err))
		return 1
	}

	// Query the members
	mem, err := client.Agent().Members()
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Error querying servers: %s", err))
		return 1
	}

	// Sort the members
	sort.Sort(api.AgentMembersNameSort(mem))

	// Determine the leaders per region.
	leaders, err := regionLeaders(client, mem)
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Error determining leaders: %s", err))
		return 1
	}

	// Format the list
	var out []string
	if detailed {
		out = detailedOutput(mem)
	} else {
		out = standardOutput(mem, leaders)
	}

	// Dump the list
	c.Ui.Output(columnize.SimpleFormat(out))
	return 0
}

func standardOutput(mem []*api.AgentMember, leaders map[string]string) []string {
	// Format the members list
	members := make([]string, len(mem)+1)
	members[0] = "Name|Address|Port|Status|Leader|Protocol|Build|Datacenter|Region"
	for i, member := range mem {
		reg := member.Tags["region"]
		regLeader, ok := leaders[reg]
		isLeader := false
		if ok {
			if regLeader == fmt.Sprintf("%s:%s", member.Addr, member.Tags["port"]) {

				isLeader = true
			}
		}

		members[i+1] = fmt.Sprintf("%s|%s|%d|%s|%t|%d|%s|%s|%s",
			member.Name,
			member.Addr,
			member.Port,
			member.Status,
			isLeader,
			member.ProtocolCur,
			member.Tags["build"],
			member.Tags["dc"],
			member.Tags["region"])
	}
	return members
}

func detailedOutput(mem []*api.AgentMember) []string {
	// Format the members list
	members := make([]string, len(mem)+1)
	members[0] = "Name|Address|Port|Tags"
	for i, member := range mem {
		// Format the tags
		tagPairs := make([]string, 0, len(member.Tags))
		for k, v := range member.Tags {
			tagPairs = append(tagPairs, fmt.Sprintf("%s=%s", k, v))
		}
		tags := strings.Join(tagPairs, ",")

		members[i+1] = fmt.Sprintf("%s|%s|%d|%s",
			member.Name,
			member.Addr,
			member.Port,
			tags)
	}
	return members
}

// regionLeaders returns a map of regions to the IP of the member that is the
// leader.
func regionLeaders(client *api.Client, mem []*api.AgentMember) (map[string]string, error) {
	// Determine the unique regions.
	leaders := make(map[string]string)
	regions := make(map[string]struct{})
	for _, m := range mem {
		regions[m.Tags["region"]] = struct{}{}
	}

	if len(regions) == 0 {
		return leaders, nil
	}

	status := client.Status()
	for reg := range regions {
		l, err := status.RegionLeader(reg)
		if err != nil {
			// This error means that region has no leader.
			if strings.Contains(err.Error(), "No cluster leader") {
				continue
			}
			return nil, err
		}

		leaders[reg] = l
	}

	return leaders, nil
}
<|endoftext|>


<commit_before>package commandHandlers

import (
	"fmt"
	"math/rand"
	"strings"

	"html"

	"github.com/hoisie/mustache"
	"github.com/khades/servbot/ircClient"
	"github.com/khades/servbot/models"
	"github.com/khades/servbot/repos"
)

// Custom handler checks if input command has template and then fills it in with mustache templating and sends to a specified/user
func Custom(online bool, chatMessage *models.ChatMessage, chatCommand models.ChatCommand, ircClient *ircClient.IrcClient) {
	channelInfo, error := repos.GetChannelInfo(&chatMessage.ChannelID)
	if error != nil {
		return
	}
	channelStatus := &models.ChannelInfoForTemplate{ChannelInfo: *channelInfo, IsMod: chatMessage.IsMod}
	channelStatus.IsMod = chatMessage.IsMod
	template, err := repos.GetChannelTemplate(&chatMessage.ChannelID, &chatCommand.Command)
	user := chatMessage.User
	if err != nil || template.Template == "" {
		return
	}

	if chatMessage.IsMod == false {
		if channelStatus.StreamStatus.Online == true && template.ShowOnline == false {
			return
		}
		if channelStatus.StreamStatus.Online == false && template.ShowOffline == false {
			return
		}
	}
	if template.IntegerRandomizer.Enabled == true && template.IntegerRandomizer.UpperLimit > template.IntegerRandomizer.LowerLimit {
		channelStatus.RandomInteger = template.IntegerRandomizer.LowerLimit + rand.Intn(template.IntegerRandomizer.UpperLimit-template.IntegerRandomizer.LowerLimit)
		if channelStatus.RandomInteger == template.IntegerRandomizer.LowerLimit {
			channelStatus.RandomIntegerIsMinimal = true
		}
		if channelStatus.RandomInteger == template.IntegerRandomizer.UpperLimit {
			channelStatus.RandomIntegerIsMaximal = true
		}
		if channelStatus.RandomInteger == 0 {
			channelStatus.RandomIntegerIsMinimal = true
		}
		if template.IntegerRandomizer.TimeoutAfter == true && channelStatus.RandomInteger > 0 {
			if chatMessage.IsMod == false {
				ircClient.SendPublic(&models.OutgoingMessage{
					Channel: chatMessage.Channel,
					Body:    fmt.Sprintf("/timeout %s %d ", user, channelStatus.RandomInteger)})
			} else {
				ircClient.SendPublic(&models.OutgoingMessage{
					Channel: chatMessage.Channel,
					User:    user,
					Body:    "Модератора нельзя затаймаутить SMOrc"})
				return
			}

		}
	}

	if template.StringRandomizer.Enabled == true {
		if len(template.StringRandomizer.Strings) == 0 {
			commandValues := strings.Split(chatCommand.Body, ",")
			if len(commandValues) != 0 {
				channelStatus.RandomString = strings.TrimSpace(commandValues[rand.Intn(len(commandValues)-1)])

			}
		} else {
			channelStatus.RandomString = strings.TrimSpace(template.StringRandomizer.Strings[rand.Intn(len(template.StringRandomizer.Strings)-1)])
		}
	}

	message := mustache.Render(template.Template, channelStatus)

	redirectTo := chatMessage.User
	if chatCommand.Body != "" && !(template.StringRandomizer.Enabled == true && len(template.StringRandomizer.Strings) == 0) && template.PreventRedirect == false {
		if strings.HasPrefix(chatCommand.Body, "@") {
			redirectTo = chatCommand.Body[1:]
		} else {
			redirectTo = chatCommand.Body

		}
	}
	if template.PreventDebounce == true {
		ircClient.SendPublic(&models.OutgoingMessage{
			Channel: chatMessage.Channel,
			User:    user,
			Body:    html.UnescapeString(message)})
	} else {
		ircClient.SendDebounced(models.OutgoingDebouncedMessage{
			Message: models.OutgoingMessage{
				Channel: chatMessage.Channel,
				User:    user,
				Body:    html.UnescapeString(message)},
			Command:    template.AliasTo,
			RedirectTo: redirectTo})
	}

}
<commit_msg>Debug: fixing non-working list<commit_after>package commandHandlers

import (
	"fmt"
	"log"
	"math/rand"
	"strings"

	"html"

	"github.com/hoisie/mustache"
	"github.com/khades/servbot/ircClient"
	"github.com/khades/servbot/models"
	"github.com/khades/servbot/repos"
)

// Custom handler checks if input command has template and then fills it in with mustache templating and sends to a specified/user
func Custom(online bool, chatMessage *models.ChatMessage, chatCommand models.ChatCommand, ircClient *ircClient.IrcClient) {
	channelInfo, error := repos.GetChannelInfo(&chatMessage.ChannelID)
	if error != nil {
		return
	}
	channelStatus := &models.ChannelInfoForTemplate{ChannelInfo: *channelInfo, IsMod: chatMessage.IsMod}
	channelStatus.IsMod = chatMessage.IsMod
	template, err := repos.GetChannelTemplate(&chatMessage.ChannelID, &chatCommand.Command)
	user := chatMessage.User
	if err != nil || template.Template == "" {
		return
	}

	if chatMessage.IsMod == false {
		if channelStatus.StreamStatus.Online == true && template.ShowOnline == false {
			return
		}
		if channelStatus.StreamStatus.Online == false && template.ShowOffline == false {
			return
		}
	}
	if template.IntegerRandomizer.Enabled == true && template.IntegerRandomizer.UpperLimit > template.IntegerRandomizer.LowerLimit {
		channelStatus.RandomInteger = template.IntegerRandomizer.LowerLimit + rand.Intn(template.IntegerRandomizer.UpperLimit-template.IntegerRandomizer.LowerLimit)
		if channelStatus.RandomInteger == template.IntegerRandomizer.LowerLimit {
			channelStatus.RandomIntegerIsMinimal = true
		}
		if channelStatus.RandomInteger == template.IntegerRandomizer.UpperLimit {
			channelStatus.RandomIntegerIsMaximal = true
		}
		if channelStatus.RandomInteger == 0 {
			channelStatus.RandomIntegerIsMinimal = true
		}
		if template.IntegerRandomizer.TimeoutAfter == true && channelStatus.RandomInteger > 0 {
			if chatMessage.IsMod == false {
				ircClient.SendPublic(&models.OutgoingMessage{
					Channel: chatMessage.Channel,
					Body:    fmt.Sprintf("/timeout %s %d ", user, channelStatus.RandomInteger)})
			} else {
				ircClient.SendPublic(&models.OutgoingMessage{
					Channel: chatMessage.Channel,
					User:    user,
					Body:    "Модератора нельзя затаймаутить SMOrc"})
				return
			}

		}
	}

	if template.StringRandomizer.Enabled == true {
		if len(template.StringRandomizer.Strings) == 0 {
			commandValues := strings.Split(chatCommand.Body, ",")
			if len(commandValues) != 0 {
				channelStatus.RandomString = strings.TrimSpace(commandValues[rand.Intn(len(commandValues)-1)])

			}
		} else {
			channelStatus.RandomString = strings.TrimSpace(template.StringRandomizer.Strings[rand.Intn(len(template.StringRandomizer.Strings)-1)])
		}
	}

	message := mustache.Render(template.Template, channelStatus)
	log.Println(template.CommandName)
	log.Println(message)
	redirectTo := chatMessage.User
	if chatCommand.Body != "" && !(template.StringRandomizer.Enabled == true && len(template.StringRandomizer.Strings) == 0) && template.PreventRedirect == false {
		if strings.HasPrefix(chatCommand.Body, "@") {
			redirectTo = chatCommand.Body[1:]
		} else {
			redirectTo = chatCommand.Body

		}
	}
	if template.PreventDebounce == true {
		ircClient.SendPublic(&models.OutgoingMessage{
			Channel: chatMessage.Channel,
			User:    user,
			Body:    html.UnescapeString(message)})
	} else {
		ircClient.SendDebounced(models.OutgoingDebouncedMessage{
			Message: models.OutgoingMessage{
				Channel: chatMessage.Channel,
				User:    user,
				Body:    html.UnescapeString(message)},
			Command:    template.AliasTo,
			RedirectTo: redirectTo})
	}

}
<|endoftext|>