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

// +build !appengine

package main

import (
	"flag"
	"fmt"
	"go/build"
	"io"
	"log"
	"net"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"time"

	"code.google.com/p/go.talks/pkg/socket"

	// Imports so that go build/install automatically installs them.
	_ "code.google.com/p/go-tour/pic"
	_ "code.google.com/p/go-tour/tree"
	_ "code.google.com/p/go-tour/wc"
)

const (
	basePkg    = "code.google.com/p/go-tour/"
	socketPath = "/socket"
)

var (
	httpListen  = flag.String("http", "127.0.0.1:3999", "host:port to listen on")
	htmlOutput  = flag.Bool("html", false, "render program output as HTML")
	openBrowser = flag.Bool("openbrowser", true, "open browser automatically")
)

var (
	// a source of numbers, for naming temporary files
	uniq = make(chan int)

	// GOPATH containing the tour packages
	gopath = os.Getenv("GOPATH")

	httpAddr string
)

func isRoot(path string) bool {
	_, err := os.Stat(filepath.Join(path, "tour.article"))
	return err == nil
}

func findRoot() (string, error) {
	ctx := build.Default
	p, err := ctx.Import(basePkg, "", build.FindOnly)
	if err == nil && isRoot(p.Dir) {
		return p.Dir, nil
	}
	tourRoot := filepath.Join(runtime.GOROOT(), "misc", "tour")
	ctx.GOPATH = tourRoot
	p, err = ctx.Import(basePkg, "", build.FindOnly)
	if err == nil && isRoot(tourRoot) {
		gopath = tourRoot
		return tourRoot, nil
	}
	return "", fmt.Errorf("could not find go-tour content; check $GOROOT and $GOPATH")
}

func main() {
	flag.Parse()

	// source of unique numbers
	go func() {
		for i := 0; ; i++ {
			uniq <- i
		}
	}()

	// find and serve the go tour files
	root, err := findRoot()
	if err != nil {
		log.Fatalf("Couldn't find tour files: %v", err)
	}

	log.Println("Serving content from", root)

	host, port, err := net.SplitHostPort(*httpListen)
	if err != nil {
		log.Fatal(err)
	}
	if host == "" {
		host = "localhost"
	}
	if host != "127.0.0.1" && host != "localhost" {
		log.Print(localhostWarning)
	}
	httpAddr = host + ":" + port

	if err := initTour(root); err != nil {
		log.Fatal(err)
	}

	fs := http.FileServer(http.Dir(root))
	http.Handle("/favicon.ico", fs)
	http.Handle("/static/", fs)
	http.Handle("/talks/", fs)

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path == "/" {
			if err := renderTour(w); err != nil {
				log.Println(err)
			}
			return
		}
		http.Error(w, "not found", 404)
	})

	http.Handle(socketPath, socket.Handler)

	err = serveScripts(filepath.Join(root, "js"), "socket.js")
	if err != nil {
		log.Fatal(err)
	}

	go func() {
		url := "http://" + httpAddr
		if waitServer(url) && *openBrowser && startBrowser(url) {
			log.Printf("A browser window should open. If not, please visit %s", url)
		} else {
			log.Printf("Please open your web browser and visit %s", url)
		}
	}()
	log.Fatal(http.ListenAndServe(httpAddr, nil))
}

const localhostWarning = `
WARNING!  WARNING!  WARNING!

I appear to be listening on an address that is not localhost.
Anyone with access to this address and port will have access
to this machine as the user running gotour.

If you don't understand this message, hit Control-C to terminate this process.

WARNING!  WARNING!  WARNING!
`

type response struct {
	Output string `json:"output"`
	Errors string `json:"compile_errors"`
}

// environ returns an execution environment containing only GO* variables
// and replacing GOPATH with the value of the global var gopath.
func environ() (env []string) {
	for _, v := range os.Environ() {
		if !strings.HasPrefix(v, "GO") {
			continue
		}
		if strings.HasPrefix(v, "GOPATH=") {
			v = "GOPATH=" + gopath
		}
		env = append(env, v)
	}
	return
}

// waitServer waits some time for the http Server to start
// serving url and returns whether it starts
func waitServer(url string) bool {
	tries := 20
	for tries > 0 {
		resp, err := http.Get(url)
		if err == nil {
			resp.Body.Close()
			return true
		}
		time.Sleep(100 * time.Millisecond)
		tries--
	}
	return false
}

// startBrowser tries to open the URL in a browser, and returns
// whether it succeed.
func startBrowser(url string) bool {
	// try to start the browser
	var args []string
	switch runtime.GOOS {
	case "darwin":
		args = []string{"open"}
	case "windows":
		args = []string{"cmd", "/c", "start"}
	default:
		args = []string{"xdg-open"}
	}
	cmd := exec.Command(args[0], append(args[1:], url)...)
	return cmd.Start() == nil
}

// prepContent for the local tour simply returns the content as-is.
func prepContent(r io.Reader) io.Reader { return r }

// socketAddr returns the WebSocket handler address.
func socketAddr() string { return "ws://" + httpAddr + socketPath }
<commit_msg>go-tour: supply alternate GOPATH when building locally<commit_after>// Copyright 2011 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !appengine

package main

import (
	"flag"
	"fmt"
	"go/build"
	"io"
	"log"
	"net"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"time"

	"code.google.com/p/go.talks/pkg/socket"

	// Imports so that go build/install automatically installs them.
	_ "code.google.com/p/go-tour/pic"
	_ "code.google.com/p/go-tour/tree"
	_ "code.google.com/p/go-tour/wc"
)

const (
	basePkg    = "code.google.com/p/go-tour/"
	socketPath = "/socket"
)

var (
	httpListen  = flag.String("http", "127.0.0.1:3999", "host:port to listen on")
	htmlOutput  = flag.Bool("html", false, "render program output as HTML")
	openBrowser = flag.Bool("openbrowser", true, "open browser automatically")
)

var (
	// a source of numbers, for naming temporary files
	uniq = make(chan int)

	// GOPATH containing the tour packages
	gopath = os.Getenv("GOPATH")

	httpAddr string
)

func isRoot(path string) bool {
	_, err := os.Stat(filepath.Join(path, "tour.article"))
	return err == nil
}

func findRoot() (string, error) {
	ctx := build.Default
	p, err := ctx.Import(basePkg, "", build.FindOnly)
	if err == nil && isRoot(p.Dir) {
		return p.Dir, nil
	}
	tourRoot := filepath.Join(runtime.GOROOT(), "misc", "tour")
	ctx.GOPATH = tourRoot
	p, err = ctx.Import(basePkg, "", build.FindOnly)
	if err == nil && isRoot(tourRoot) {
		gopath = tourRoot
		return tourRoot, nil
	}
	return "", fmt.Errorf("could not find go-tour content; check $GOROOT and $GOPATH")
}

func main() {
	flag.Parse()

	// source of unique numbers
	go func() {
		for i := 0; ; i++ {
			uniq <- i
		}
	}()

	// find and serve the go tour files
	root, err := findRoot()
	if err != nil {
		log.Fatalf("Couldn't find tour files: %v", err)
	}

	log.Println("Serving content from", root)

	host, port, err := net.SplitHostPort(*httpListen)
	if err != nil {
		log.Fatal(err)
	}
	if host == "" {
		host = "localhost"
	}
	if host != "127.0.0.1" && host != "localhost" {
		log.Print(localhostWarning)
	}
	httpAddr = host + ":" + port

	if err := initTour(root); err != nil {
		log.Fatal(err)
	}

	fs := http.FileServer(http.Dir(root))
	http.Handle("/favicon.ico", fs)
	http.Handle("/static/", fs)
	http.Handle("/talks/", fs)

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path == "/" {
			if err := renderTour(w); err != nil {
				log.Println(err)
			}
			return
		}
		http.Error(w, "not found", 404)
	})

	http.Handle(socketPath, socket.Handler)

	err = serveScripts(filepath.Join(root, "js"), "socket.js")
	if err != nil {
		log.Fatal(err)
	}

	go func() {
		url := "http://" + httpAddr
		if waitServer(url) && *openBrowser && startBrowser(url) {
			log.Printf("A browser window should open. If not, please visit %s", url)
		} else {
			log.Printf("Please open your web browser and visit %s", url)
		}
	}()
	log.Fatal(http.ListenAndServe(httpAddr, nil))
}

const localhostWarning = `
WARNING!  WARNING!  WARNING!

I appear to be listening on an address that is not localhost.
Anyone with access to this address and port will have access
to this machine as the user running gotour.

If you don't understand this message, hit Control-C to terminate this process.

WARNING!  WARNING!  WARNING!
`

type response struct {
	Output string `json:"output"`
	Errors string `json:"compile_errors"`
}

func init() {
	socket.Environ = environ
}

// environ returns an execution environment containing only GO* variables
// and replacing GOPATH with the value of the global var gopath.
func environ() (env []string) {
	for _, v := range os.Environ() {
		if !strings.HasPrefix(v, "GO") {
			continue
		}
		if strings.HasPrefix(v, "GOPATH=") {
			v = "GOPATH=" + gopath
		}
		env = append(env, v)
	}
	return
}

// waitServer waits some time for the http Server to start
// serving url and returns whether it starts
func waitServer(url string) bool {
	tries := 20
	for tries > 0 {
		resp, err := http.Get(url)
		if err == nil {
			resp.Body.Close()
			return true
		}
		time.Sleep(100 * time.Millisecond)
		tries--
	}
	return false
}

// startBrowser tries to open the URL in a browser, and returns
// whether it succeed.
func startBrowser(url string) bool {
	// try to start the browser
	var args []string
	switch runtime.GOOS {
	case "darwin":
		args = []string{"open"}
	case "windows":
		args = []string{"cmd", "/c", "start"}
	default:
		args = []string{"xdg-open"}
	}
	cmd := exec.Command(args[0], append(args[1:], url)...)
	return cmd.Start() == nil
}

// prepContent for the local tour simply returns the content as-is.
func prepContent(r io.Reader) io.Reader { return r }

// socketAddr returns the WebSocket handler address.
func socketAddr() string { return "ws://" + httpAddr + socketPath }
<|endoftext|>


<commit_before>package gpg

import (
	"bytes"
	"os"
	"testing"
)

func newGPGtest(t *testing.T, path string) {
	t.Log("Testing NewGPG for", path)
	file, _ := os.Open(path)
	defer file.Close()
	gpg, err := NewGPG(file, passphrase)
	if err != nil {
		t.Fatal("Failed to create GPG object for", path, ":", err)
	}

	if gpg.serverEntity == nil {
		t.Error("Failed to initialize serverEntity for path:", path)
	}
}

func TestNewGPG(t *testing.T) {
	for _, path := range [2]string{asciiKeyFilePrivate, binaryKeyFilePrivate} {
		newGPGtest(t, path)
	}
}

func setupGPG(t *testing.T) *GPG {
	file, _ := os.Open(asciiKeyFilePrivate)
	defer file.Close()
	gpg, err := NewGPG(file, passphrase)
	if err != nil {
		t.Fatal("Failed to create GPG object for", asciiKeyFilePrivate, ":", err)
	}
	return gpg
}

func TestGPGSignUserIDWithCorrectEmail(t *testing.T) {
	gpg := setupGPG(t)

	clientPublicKeyFile, _ := os.Open(asciiKeyFileClient)
	defer clientPublicKeyFile.Close()

	buffer := new(bytes.Buffer)
	err := gpg.SignUserID("test-gpg-validation@client.local", clientPublicKeyFile, buffer)
	if err != nil {
		t.Fatal("Failed to sign user id:", err)
	}

	signedClientEntity, _ := ReadEntity(buffer, true)
	verifySignatureTest(t, expectedClientIdentity, signedClientEntity)
}

func TestGPGSignUserIDWithIncorrectEmail(t *testing.T) {
	gpg := setupGPG(t)

	clientPublicKeyFile, _ := os.Open(asciiKeyFileClient)
	defer clientPublicKeyFile.Close()

	buffer := new(bytes.Buffer)
	err := gpg.SignUserID("impostor@faux.fake", clientPublicKeyFile, buffer)
	if err == nil {
		t.Fatal("Signed user id for fake email")
	}
}
<commit_msg>Added test for GPG.SignMessage<commit_after>package gpg

import (
	"bytes"
	"os"
	"testing"

	"golang.org/x/crypto/openpgp"
)

func newGPGtest(t *testing.T, path string) {
	t.Log("Testing NewGPG for", path)
	file, _ := os.Open(path)
	defer file.Close()
	gpg, err := NewGPG(file, passphrase)
	if err != nil {
		t.Fatal("Failed to create GPG object for", path, ":", err)
	}

	if gpg.serverEntity == nil {
		t.Error("Failed to initialize serverEntity for path:", path)
	}
}

func TestNewGPG(t *testing.T) {
	for _, path := range [2]string{asciiKeyFilePrivate, binaryKeyFilePrivate} {
		newGPGtest(t, path)
	}
}

func setupGPG(t *testing.T) *GPG {
	file, _ := os.Open(asciiKeyFilePrivate)
	defer file.Close()
	gpg, err := NewGPG(file, passphrase)
	if err != nil {
		t.Fatal("Failed to create GPG object for", asciiKeyFilePrivate, ":", err)
	}
	return gpg
}

func TestGPGSignUserIDWithCorrectEmail(t *testing.T) {
	gpg := setupGPG(t)

	clientPublicKeyFile, _ := os.Open(asciiKeyFileClient)
	defer clientPublicKeyFile.Close()

	buffer := new(bytes.Buffer)
	err := gpg.SignUserID("test-gpg-validation@client.local", clientPublicKeyFile, buffer)
	if err != nil {
		t.Fatal("Failed to sign user id:", err)
	}

	signedClientEntity, _ := ReadEntity(buffer, true)
	verifySignatureTest(t, expectedClientIdentity, signedClientEntity)
}

func TestGPGSignUserIDWithIncorrectEmail(t *testing.T) {
	gpg := setupGPG(t)

	clientPublicKeyFile, _ := os.Open(asciiKeyFileClient)
	defer clientPublicKeyFile.Close()

	buffer := new(bytes.Buffer)
	err := gpg.SignUserID("impostor@faux.fake", clientPublicKeyFile, buffer)
	if err == nil {
		t.Fatal("Signed user id for fake email")
	}
}

func TestGPGSignMessage(t *testing.T) {
	gpg := setupGPG(t)
	messageString := []byte("Hello World!")

	message := bytes.NewReader(messageString)
	signature := new(bytes.Buffer)
	err := gpg.SignMessage(message, signature)
	if err != nil {
		t.Fatal("Signing message failed:", err)
	}

	keyFile, _ := os.Open(binaryKeyFilePublic)
	defer keyFile.Close()
	keyRing, err := openpgp.ReadKeyRing(keyFile)
	if err != nil {
		t.Fatal("Failed to read key ring:", err)
	}

	signer, err := openpgp.CheckArmoredDetachedSignature(keyRing, bytes.NewReader(messageString), signature)
	if err != nil {
		t.Error("Failed to verify signature:", err)
	}

	_, ok := signer.Identities[expectedIdentity]
	if !ok {
		t.Error("Signature not signed by", expectedIdentity)
	}
}
<|endoftext|>


<commit_before>package livequery

func queryHash(query M) string {
	return ""
}

func matchesQuery(object, query M) bool {

	if className, ok := query["className"]; ok {
		if object["className"].(string) != className {
			return false
		}
		return matchesQuery(object, query["where"].(map[string]interface{}))
	}

	for field, constraints := range query {
		if matchesKeyConstraints(object, field, constraints) == false {
			return false
		}
	}

	return true
}

func matchesKeyConstraints(object M, key string, constraints interface{}) bool {
	if key == "$or" {
		if querys, ok := constraints.([]interface{}); ok {
			for _, query := range querys {
				if q, ok := query.(map[string]interface{}); ok {
					if matchesQuery(object, q) {
						return true
					}
				}
			}
			return false
		}
		return false
	}

	if key == "$relatedTo" {
		return false
	}

	return true
}
<commit_msg>添加 equalObject<commit_after>package livequery

func queryHash(query M) string {
	return ""
}

func matchesQuery(object, query M) bool {

	if className, ok := query["className"]; ok {
		if object["className"].(string) != className {
			return false
		}
		return matchesQuery(object, query["where"].(map[string]interface{}))
	}

	for field, constraints := range query {
		if matchesKeyConstraints(object, field, constraints) == false {
			return false
		}
	}

	return true
}

func matchesKeyConstraints(object M, key string, constraints interface{}) bool {
	if key == "$or" {
		if querys, ok := constraints.([]interface{}); ok {
			for _, query := range querys {
				if q, ok := query.(map[string]interface{}); ok {
					if matchesQuery(object, q) {
						return true
					}
				}
			}
			return false
		}
		return false
	}

	// 不支持 relatedTo
	if key == "$relatedTo" {
		return false
	}

	// 只支持 key == "$or" 时，constraints 为数组的情况
	if _, ok := constraints.([]interface{}); ok {
		return false
	}

	var constraint M
	if v, ok := constraints.(map[string]interface{}); ok {
		constraint = v
	} else {
		if objects, ok := object[key].([]interface{}); ok {
			for _, o := range objects {
				if equalObject(o, constraints) {
					return true
				}
			}
			return false
		}
		return equalObject(object[key], constraints)
	}

	return true
}

// equalObject 仅比较基础类型：string float64 bool
func equalObject(i1, i2 interface{}) bool {
	if v1, ok := i1.(string); ok {
		if v2, ok := i2.(string); ok {
			return v1 == v2
		}
	}

	if v1, ok := i1.(float64); ok {
		if v2, ok := i2.(float64); ok {
			return v1 == v2
		}
	}

	if v1, ok := i1.(bool); ok {
		if v2, ok := i2.(bool); ok {
			return v1 == v2
		}
	}

	return false
}
<|endoftext|>


<commit_before>package tests

import (
	"testing"
	"reflect"
	"github.com/v2pro/wombat/cpJson2/tests/model"
)

func Test_array_array_int(t *testing.T) {
	runFuzzTest(t, reflect.TypeOf([3][3]int{}))
}

func Test_array_map_string_int(t *testing.T) {
	runFuzzTest(t, reflect.TypeOf([3]map[string]int{}))
}

func Test_array_slice_int(t *testing.T) {
	runFuzzTest(t, reflect.TypeOf([3][]int{}))
}

func Test_array_struct(t *testing.T) {
	runFuzzTest(t, reflect.TypeOf([3]model.TypeA{}))
}<commit_msg>cpJson2 support slice+other<commit_after>package tests

import (
	"testing"
	"reflect"
	"github.com/v2pro/wombat/cpJson2/tests/model"
)

func Test_array_array_int(t *testing.T) {
	runFuzzTest(t, reflect.TypeOf([3][3]int{}))
}

func Test_array_map_string_int(t *testing.T) {
	runFuzzTest(t, reflect.TypeOf([3]map[string]int{}))
}

func Test_array_slice_int(t *testing.T) {
	runFuzzTest(t, reflect.TypeOf([3][]int{}))
}

func Test_array_struct(t *testing.T) {
	runFuzzTest(t, reflect.TypeOf([3]model.TypeA{}))
}

func Test_slice_array_int(t *testing.T) {
	runFuzzTest(t, reflect.TypeOf([][3]int{}))
}

func Test_slice_map_string_int(t *testing.T) {
	runFuzzTest(t, reflect.TypeOf([]map[string]int{}))
}

func Test_slice_slice_int(t *testing.T) {
	runFuzzTest(t, reflect.TypeOf([][]int{}))
}

func Test_slice_struct(t *testing.T) {
	runFuzzTest(t, reflect.TypeOf([]model.TypeA{}))
}<|endoftext|>


<commit_before>// The CQ Watcher monitors the Skia CQ for Gerrit CLs. It pumps the results of
// the monitoring into InfluxDB.
package main

import (
	"context"
	"flag"
	"fmt"
	"time"

	"go.skia.org/infra/go/auth"
	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/cq"
	"go.skia.org/infra/go/gerrit"
	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/metrics2"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/util"
)

var (
	testing  = flag.Bool("testing", false, "Set to true for local testing.")
	promPort = flag.String("prom_port", ":20000", "Metrics service address (e.g., ':20000')")
)

const (
	// How often the two pollers should poll Gerrit.
	IN_FLIGHT_POLL_TIME    = 30 * time.Second
	AFTER_COMMIT_POLL_TIME = 5 * time.Minute

	// How often to refresh the trybots received from cq.cfg.
	REFRESH_CQ_TRYBOTS_TIME = time.Hour

	MAX_CLS_PER_POLL = 100
	METRIC_NAME      = "cq_watcher"
)

// monitorStatsForInFlightCLs queries Gerrit for all CLs currently in dry run
// or waiting for commit. The following metrics are then reported for the
// matching CLs:
// * Number of CLs waiting for the CQ (both for dry runs and commits).
// * How long CQ trybots have been running for.
// * How many CQ trybots have been triggered.
func monitorStatsForInFlightCLs(ctx context.Context, cqClient *cq.Client, gerritClient *gerrit.Gerrit) {
	liveness := metrics2.NewLiveness(fmt.Sprintf("%s_%s", METRIC_NAME, cq.INFLIGHT_METRIC_NAME))
	cqMetric := metrics2.GetInt64Metric(fmt.Sprintf("%s_%s_%s", METRIC_NAME, cq.INFLIGHT_METRIC_NAME, cq.INFLIGHT_WAITING_IN_CQ))

	oldMetrics := map[metrics2.Int64Metric]struct{}{}
	util.RepeatCtx(time.Duration(IN_FLIGHT_POLL_TIME), ctx, func(ctx context.Context) {
		dryRunChanges, err := gerritClient.Search(ctx, MAX_CLS_PER_POLL, true, gerrit.SearchStatus("open"), gerrit.SearchProject("skia"), gerrit.SearchLabel(gerrit.COMMITQUEUE_LABEL, "1"))
		if err != nil {
			sklog.Errorf("Error searching for open changes with dry run in Gerrit: %s", err)
			return
		}
		cqChanges, err := gerritClient.Search(ctx, MAX_CLS_PER_POLL, true, gerrit.SearchStatus("open"), gerrit.SearchProject("skia"), gerrit.SearchLabel(gerrit.COMMITQUEUE_LABEL, "2"))
		if err != nil {
			sklog.Errorf("Error searching for open changes waiting for CQ in Gerrit: %s", err)
			return
		}

		// Combine dryrun and CQ changes into one slice.
		changes := dryRunChanges
		changes = append(changes, cqChanges...)
		cqMetric.Update(int64(len(changes)))

		newMetrics := map[metrics2.Int64Metric]struct{}{}
		for _, change := range changes {
			if err := cqClient.ReportCQStats(ctx, change.Issue, newMetrics); err != nil {
				sklog.Errorf("Could not get CQ stats for %d: %s", change.Issue, err)
				continue
			}
		}
		// If no CLs are currently in the CQ then report dummy data to prevent
		// "Failed to execute query for rule..." failures in the alertserver.
		if len(changes) == 0 {
			durationTags := map[string]string{
				"trybot": "DummyTrybot",
			}
			inflightTrybotDurationMetric := metrics2.GetInt64Metric(fmt.Sprintf("%s_%s_%s", METRIC_NAME, cq.INFLIGHT_METRIC_NAME, cq.INFLIGHT_TRYBOT_DURATION), durationTags)
			inflightTrybotDurationMetric.Update(0)
			trybotNumDurationMetric := metrics2.GetInt64Metric(fmt.Sprintf("%s_%s_%s", METRIC_NAME, cq.INFLIGHT_METRIC_NAME, cq.INFLIGHT_TRYBOT_NUM), map[string]string{})
			trybotNumDurationMetric.Update(0)
		}
		liveness.Reset()

		// Delete unused old metrics and use new metrics as old ones for next iteration.
		deleteUnusedOldMetrics(newMetrics, oldMetrics)
		oldMetrics = newMetrics
	})
}

// monitorStatsForLandedCLs queries Gerrit for all CLs that have been merged in
// the last AFTER_COMMIT_POLL_TIME seconds. The following metrics are then
// reported for the matching CLs:
// * The total time the CL spent waiting for CQ trybots to complete.
// * The time each CQ trybot took to complete.
func monitorStatsForLandedCLs(ctx context.Context, cqClient *cq.Client, gerritClient *gerrit.Gerrit) {
	liveness := metrics2.NewLiveness(fmt.Sprintf("%s_%s", METRIC_NAME, cq.LANDED_METRIC_NAME))
	previousPollChanges := []*gerrit.ChangeInfo{}
	oldMetrics := map[metrics2.Int64Metric]struct{}{}
	util.RepeatCtx(time.Duration(AFTER_COMMIT_POLL_TIME), ctx, func(ctx context.Context) {
		// Add a short (2 min) buffer to overlap with the last poll to make sure
		// we do not lose any edge cases.
		t_delta := time.Now().Add(-AFTER_COMMIT_POLL_TIME).Add(-2 * time.Minute)
		changes, err := gerritClient.Search(ctx, MAX_CLS_PER_POLL, true, gerrit.SearchModifiedAfter(t_delta), gerrit.SearchStatus("merged"), gerrit.SearchProject("skia"))
		if err != nil {
			sklog.Errorf("Error searching for merged changes in Gerrit: %s", err)
			return
		}
		newMetrics := map[metrics2.Int64Metric]struct{}{}
		for _, change := range changes {
			if gerrit.ContainsAny(change.Issue, previousPollChanges) {
				continue
			}
			if err := cqClient.ReportCQStats(ctx, change.Issue, newMetrics); err != nil {
				sklog.Errorf("Could not get CQ stats for %d: %s", change.Issue, err)
				continue
			}
		}
		previousPollChanges = changes
		liveness.Reset()

		// Delete unused old metrics and use new metrics as old ones for next iteration.
		deleteUnusedOldMetrics(newMetrics, oldMetrics)
		oldMetrics = newMetrics
	})
}

func deleteUnusedOldMetrics(newMetrics, oldMetrics map[metrics2.Int64Metric]struct{}) {
	for m := range oldMetrics {
		if _, ok := newMetrics[m]; !ok {
			if err := m.Delete(); err != nil {
				sklog.Errorf("Failed to delete metric: %s", err)
				// Add the metric to newMetrics so that we'll
				// have the chance to delete it again on the
				// next cycle.
				newMetrics[m] = struct{}{}
			}
		}
	}
}

func refreshCQTryBots(cqClient *cq.Client) {
	for range time.Tick(time.Duration(REFRESH_CQ_TRYBOTS_TIME)) {
		if err := cqClient.RefreshCQTryBots(); err != nil {
			sklog.Errorf("Error refreshing CQ trybots: %s", err)
		}
	}
}

func main() {
	common.InitWithMust(METRIC_NAME, common.PrometheusOpt(promPort))

	ctx := context.Background()
	ts, err := auth.NewDefaultTokenSource(*testing, auth.SCOPE_USERINFO_EMAIL, auth.SCOPE_GERRIT)
	if err != nil {
		sklog.Fatal(err)
	}
	httpClient := httputils.DefaultClientConfig().WithTokenSource(ts).With2xxOnly().Client()
	gerritClient, err := gerrit.NewGerrit(gerrit.GERRIT_SKIA_URL, httpClient)
	if err != nil {
		sklog.Fatalf("Failed to create Gerrit client: %s", err)
	}
	cqClient, err := cq.NewClient(gerritClient, cq.GetSkiaCQTryBots, METRIC_NAME)
	if err != nil {
		sklog.Fatalf("Failed to create CQ client: %s", err)
	}

	// Periodically refresh slice of trybots to make sure any changes to cq.cfg
	// are picked up without needing to restart the app.
	go refreshCQTryBots(cqClient)
	// Monitor in-flight CLs.
	go monitorStatsForInFlightCLs(ctx, cqClient, gerritClient)
	// Monitor landed CLs.
	monitorStatsForLandedCLs(ctx, cqClient, gerritClient)
}
<commit_msg>[cq_watcher] Make dummy alert labels match real alert labels<commit_after>// The CQ Watcher monitors the Skia CQ for Gerrit CLs. It pumps the results of
// the monitoring into InfluxDB.
package main

import (
	"context"
	"flag"
	"fmt"
	"time"

	"go.skia.org/infra/go/auth"
	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/cq"
	"go.skia.org/infra/go/gerrit"
	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/metrics2"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/util"
)

var (
	testing  = flag.Bool("testing", false, "Set to true for local testing.")
	promPort = flag.String("prom_port", ":20000", "Metrics service address (e.g., ':20000')")
)

const (
	// How often the two pollers should poll Gerrit.
	IN_FLIGHT_POLL_TIME    = 30 * time.Second
	AFTER_COMMIT_POLL_TIME = 5 * time.Minute

	// How often to refresh the trybots received from cq.cfg.
	REFRESH_CQ_TRYBOTS_TIME = time.Hour

	MAX_CLS_PER_POLL = 100
	METRIC_NAME      = "cq_watcher"
)

// monitorStatsForInFlightCLs queries Gerrit for all CLs currently in dry run
// or waiting for commit. The following metrics are then reported for the
// matching CLs:
// * Number of CLs waiting for the CQ (both for dry runs and commits).
// * How long CQ trybots have been running for.
// * How many CQ trybots have been triggered.
func monitorStatsForInFlightCLs(ctx context.Context, cqClient *cq.Client, gerritClient *gerrit.Gerrit) {
	liveness := metrics2.NewLiveness(fmt.Sprintf("%s_%s", METRIC_NAME, cq.INFLIGHT_METRIC_NAME))
	cqMetric := metrics2.GetInt64Metric(fmt.Sprintf("%s_%s_%s", METRIC_NAME, cq.INFLIGHT_METRIC_NAME, cq.INFLIGHT_WAITING_IN_CQ))

	oldMetrics := map[metrics2.Int64Metric]struct{}{}
	util.RepeatCtx(time.Duration(IN_FLIGHT_POLL_TIME), ctx, func(ctx context.Context) {
		dryRunChanges, err := gerritClient.Search(ctx, MAX_CLS_PER_POLL, true, gerrit.SearchStatus("open"), gerrit.SearchProject("skia"), gerrit.SearchLabel(gerrit.COMMITQUEUE_LABEL, "1"))
		if err != nil {
			sklog.Errorf("Error searching for open changes with dry run in Gerrit: %s", err)
			return
		}
		cqChanges, err := gerritClient.Search(ctx, MAX_CLS_PER_POLL, true, gerrit.SearchStatus("open"), gerrit.SearchProject("skia"), gerrit.SearchLabel(gerrit.COMMITQUEUE_LABEL, "2"))
		if err != nil {
			sklog.Errorf("Error searching for open changes waiting for CQ in Gerrit: %s", err)
			return
		}

		// Combine dryrun and CQ changes into one slice.
		changes := dryRunChanges
		changes = append(changes, cqChanges...)
		cqMetric.Update(int64(len(changes)))

		newMetrics := map[metrics2.Int64Metric]struct{}{}
		for _, change := range changes {
			if err := cqClient.ReportCQStats(ctx, change.Issue, newMetrics); err != nil {
				sklog.Errorf("Could not get CQ stats for %d: %s", change.Issue, err)
				continue
			}
		}
		// If no CLs are currently in the CQ then report dummy data to prevent
		// Absent alerts in the alert manager.
		if len(changes) == 0 {
			inflightTrybotDurationMetric := metrics2.GetInt64Metric(fmt.Sprintf("%s_%s_%s", METRIC_NAME, cq.INFLIGHT_METRIC_NAME, cq.INFLIGHT_TRYBOT_DURATION), map[string]string{"trybot": "DummyTrybot", "gerritURL": "DummyGerritURL"})
			inflightTrybotDurationMetric.Update(0)
			trybotNumDurationMetric := metrics2.GetInt64Metric(fmt.Sprintf("%s_%s_%s", METRIC_NAME, cq.INFLIGHT_METRIC_NAME, cq.INFLIGHT_TRYBOT_NUM), map[string]string{"gerritURL": "DummyGerritURL"})
			trybotNumDurationMetric.Update(0)
		}
		liveness.Reset()

		// Delete unused old metrics and use new metrics as old ones for next iteration.
		deleteUnusedOldMetrics(newMetrics, oldMetrics)
		oldMetrics = newMetrics
	})
}

// monitorStatsForLandedCLs queries Gerrit for all CLs that have been merged in
// the last AFTER_COMMIT_POLL_TIME seconds. The following metrics are then
// reported for the matching CLs:
// * The total time the CL spent waiting for CQ trybots to complete.
// * The time each CQ trybot took to complete.
func monitorStatsForLandedCLs(ctx context.Context, cqClient *cq.Client, gerritClient *gerrit.Gerrit) {
	liveness := metrics2.NewLiveness(fmt.Sprintf("%s_%s", METRIC_NAME, cq.LANDED_METRIC_NAME))
	previousPollChanges := []*gerrit.ChangeInfo{}
	oldMetrics := map[metrics2.Int64Metric]struct{}{}
	util.RepeatCtx(time.Duration(AFTER_COMMIT_POLL_TIME), ctx, func(ctx context.Context) {
		// Add a short (2 min) buffer to overlap with the last poll to make sure
		// we do not lose any edge cases.
		t_delta := time.Now().Add(-AFTER_COMMIT_POLL_TIME).Add(-2 * time.Minute)
		changes, err := gerritClient.Search(ctx, MAX_CLS_PER_POLL, true, gerrit.SearchModifiedAfter(t_delta), gerrit.SearchStatus("merged"), gerrit.SearchProject("skia"))
		if err != nil {
			sklog.Errorf("Error searching for merged changes in Gerrit: %s", err)
			return
		}
		newMetrics := map[metrics2.Int64Metric]struct{}{}
		for _, change := range changes {
			if gerrit.ContainsAny(change.Issue, previousPollChanges) {
				continue
			}
			if err := cqClient.ReportCQStats(ctx, change.Issue, newMetrics); err != nil {
				sklog.Errorf("Could not get CQ stats for %d: %s", change.Issue, err)
				continue
			}
		}
		previousPollChanges = changes
		liveness.Reset()

		// Delete unused old metrics and use new metrics as old ones for next iteration.
		deleteUnusedOldMetrics(newMetrics, oldMetrics)
		oldMetrics = newMetrics
	})
}

func deleteUnusedOldMetrics(newMetrics, oldMetrics map[metrics2.Int64Metric]struct{}) {
	for m := range oldMetrics {
		if _, ok := newMetrics[m]; !ok {
			if err := m.Delete(); err != nil {
				sklog.Errorf("Failed to delete metric: %s", err)
				// Add the metric to newMetrics so that we'll
				// have the chance to delete it again on the
				// next cycle.
				newMetrics[m] = struct{}{}
			}
		}
	}
}

func refreshCQTryBots(cqClient *cq.Client) {
	for range time.Tick(time.Duration(REFRESH_CQ_TRYBOTS_TIME)) {
		if err := cqClient.RefreshCQTryBots(); err != nil {
			sklog.Errorf("Error refreshing CQ trybots: %s", err)
		}
	}
}

func main() {
	common.InitWithMust(METRIC_NAME, common.PrometheusOpt(promPort))

	ctx := context.Background()
	ts, err := auth.NewDefaultTokenSource(*testing, auth.SCOPE_USERINFO_EMAIL, auth.SCOPE_GERRIT)
	if err != nil {
		sklog.Fatal(err)
	}
	httpClient := httputils.DefaultClientConfig().WithTokenSource(ts).With2xxOnly().Client()
	gerritClient, err := gerrit.NewGerrit(gerrit.GERRIT_SKIA_URL, httpClient)
	if err != nil {
		sklog.Fatalf("Failed to create Gerrit client: %s", err)
	}
	cqClient, err := cq.NewClient(gerritClient, cq.GetSkiaCQTryBots, METRIC_NAME)
	if err != nil {
		sklog.Fatalf("Failed to create CQ client: %s", err)
	}

	// Periodically refresh slice of trybots to make sure any changes to cq.cfg
	// are picked up without needing to restart the app.
	go refreshCQTryBots(cqClient)
	// Monitor in-flight CLs.
	go monitorStatsForInFlightCLs(ctx, cqClient, gerritClient)
	// Monitor landed CLs.
	monitorStatsForLandedCLs(ctx, cqClient, gerritClient)
}
<|endoftext|>


<commit_before>package ec2

import (
	"encoding/base64"
	"strconv"
)

// start ec2 instance accept array of instance-id

func (ec2 *EC2) Startnode(request interface{}) (resp interface{}, err error) {

	param := request.(map[string]string)
	ids := []string{}
	ids = append(ids, param["instance-id"])
	Region := param["Region"]

	params := makeParams("StartInstances")

	addParamsList(params, "InstanceID", ids)

	response := make(map[string]interface{})

	err = ec2.PrepareSignatureV2query(params, Region, response)
	resp = response
	return resp, err
}

// stop ec2 instance accept array of instance-id

func (ec2 *EC2) Stopnode(request interface{}) (resp interface{}, err error) {

	param := request.(map[string]string)
	ids := []string{}
	ids = append(ids, param["instance-id"])
	Region := param["Region"]

	params := makeParams("StopInstances")
	addParamsList(params, "InstanceID", ids)
	resp = &StopInstanceResp{}

	response := make(map[string]interface{})

	err = ec2.PrepareSignatureV2query(params, Region, response)

	if err != nil {
		return nil, err
	}

	resp = response
	return resp, nil
}

// reboot ec2 instance accept array of instance-id

func (ec2 *EC2) Rebootnode(request interface{}) (resp interface{}, err error) {

	param := request.(map[string]string)
	ids := []string{}
	ids = append(ids, param["instance-id"])
	Region := param["Region"]

	params := makeParams("RebootInstances")
	addParamsList(params, "InstanceID", ids)

	response := make(map[string]interface{})

	err = ec2.PrepareSignatureV2query(params, Region, response)
	if err != nil {
		return nil, err
	}
	resp = response
	return resp, err
}

// delete ec2 instance accept array of instance-id

func (ec2 *EC2) Deletenode(request interface{}) (resp interface{}, err error) {
	param := request.(map[string]string)
	instIds := []string{}
	instIds = append(instIds, param["instance-id"])
	Region := param["Region"]

	params := makeParams("TerminateInstances")
	addParamsList(params, "InstanceID", instIds)
	response := make(map[string]interface{})

	err = ec2.PrepareSignatureV2query(params, Region, response)
	if err != nil {
		return nil, err
	}
	resp = response
	return resp, err
}

//create Ec2 instances accept map[string]interface{} with attribute Define in EC2 documentation

func (ec2 *EC2) Createnode(request interface{}) (resp interface{}, err error) {

	var options RunInstances
	var Region string

	param := make(map[string]interface{})

	param = request.(map[string]interface{})

	for key, value := range param {
		switch key {

		case "Region":
			regionV, _ := value.(string)
			Region = regionV

		case "ImageId":
			ImageId, _ := value.(string)
			options.ImageId = ImageId

		case "MinCount":
			MinCount, _ := value.(int)
			options.MinCount = MinCount

		case "MaxCount":
			MaxCount, _ := value.(int)
			options.MaxCount = MaxCount

		case "KeyName":
			KeyName, _ := value.(string)
			options.KeyName = KeyName

		case "KernelId":
			KernelId, _ := value.(string)
			options.KernelId = KernelId

		case "InstanceType":
			InstanceType, _ := value.(string)
			options.InstanceType = InstanceType

		case "RamdiskId":
			RamdiskId, _ := value.(string)
			options.RamdiskId = RamdiskId

		case "AvailZone":
			AvailZone, _ := value.(string)
			options.AvailZone = AvailZone

		case "PlacementGroupName":
			PlacementGroupName, _ := value.(string)
			options.PlacementGroupName = PlacementGroupName

		case "Monitoring":
			Monitoring, _ := value.(bool)
			options.Monitoring = Monitoring

		case "SubnetId":
			SubnetId, _ := value.(string)
			options.SubnetId = SubnetId

		case "DisableAPITermination":
			DisableAPITermination, _ := value.(bool)
			options.DisableAPITermination = DisableAPITermination

		case "ShutdownBehavior":
			ShutdownBehavior, _ := value.(string)
			options.ShutdownBehavior = ShutdownBehavior

		case "PrivateIPAddress":
			PrivateIPAddress, _ := value.(string)
			options.PrivateIPAddress = PrivateIPAddress

		case "SecurityGroup":
			SecurityGroupparam, _ := value.([]map[string]string)
			for i := 0; i < len(SecurityGroupparam); i++ {
				var securityGroup SecurityGroup
				securityGroup.Id = SecurityGroupparam[i]["Id"]
				securityGroup.Name = SecurityGroupparam[i]["Name"]
				options.SecurityGroups = append(options.SecurityGroups, securityGroup)
			}

		case "BlockDevice":
			BlockDeviceparam, _ := value.([]map[string]interface{})
			for i := 0; i < len(BlockDeviceparam); i++ {
				var BlockDeviceMappingParam BlockDeviceMapping
				for BlockDeviceparamkey, BlockDeviceparamvalue := range BlockDeviceparam[i] {
					switch BlockDeviceparamkey {
					case "DeviceName":
						BlockDeviceMappingParam.DeviceName = BlockDeviceparamvalue.(string)

					case "VirtualName":
						BlockDeviceMappingParam.VirtualName = BlockDeviceparamvalue.(string)

					case "SnapshotId":
						BlockDeviceMappingParam.SnapshotId = BlockDeviceparamvalue.(string)

					case "VolumeType":
						BlockDeviceMappingParam.VolumeType = BlockDeviceparamvalue.(string)

					case "VolumeSize":
						BlockDeviceMappingParam.VolumeSize = BlockDeviceparamvalue.(int64)

					case "DeleteOnTermination":
						BlockDeviceMappingParam.DeleteOnTermination = BlockDeviceparamvalue.(bool)

					case "IOPS":
						BlockDeviceMappingParam.IOPS = BlockDeviceparamvalue.(int64)

					}
				}
				options.BlockDeviceMappings = append(options.BlockDeviceMappings, BlockDeviceMappingParam)

			}

		case "RunNetworkInterface":
			RunNetworkInterfaceparam, _ := value.([]map[string]interface{})
			var runNetworkInterface RunNetworkInterface
			for i := 0; i < len(RunNetworkInterfaceparam); i++ {
				for RunNetworkInterfaceparamkey, RunNetworkInterfaceparamvalue := range RunNetworkInterfaceparam[i] {
					switch RunNetworkInterfaceparamkey {
					case "Id":
						runNetworkInterface.Id = RunNetworkInterfaceparamvalue.(string)
					case "DeviceIndex":
						runNetworkInterface.DeviceIndex = RunNetworkInterfaceparamvalue.(int)
					case "SubnetId":
						runNetworkInterface.Id = RunNetworkInterfaceparamvalue.(string)
					case "Description":
						runNetworkInterface.Description = RunNetworkInterfaceparamvalue.(string)
					case "DeleteOnTermination":
						runNetworkInterface.DeleteOnTermination = RunNetworkInterfaceparamvalue.(bool)
					case "SecondaryPrivateIPCount":
						runNetworkInterface.SecondaryPrivateIPCount = RunNetworkInterfaceparamvalue.(int)
					case "SecurityGroupIds":
						securityGroupIds, _ := RunNetworkInterfaceparamvalue.([]string)
						runNetworkInterface.SecurityGroupIds = securityGroupIds

					case "PrivateIPs":
						privateIPsParam, _ := RunNetworkInterfaceparamvalue.([]map[string]interface{})
						for i := 0; i < len(privateIPsParam); i++ {
							var privateIP PrivateIP
							for privateIPsParamkey, privateIPsParamvalue := range privateIPsParam[i] {
								switch privateIPsParamkey {
								case "Address":
									privateIP.Address = privateIPsParamvalue.(string)
								case "DNSName":
									privateIP.DNSName = privateIPsParamvalue.(string)
								case "IsPrimary":
									privateIP.IsPrimary = privateIPsParamvalue.(bool)
								}

							}
							runNetworkInterface.PrivateIPs = append(runNetworkInterface.PrivateIPs, privateIP)
						}

					}

				}
				options.NetworkInterfaces = append(options.NetworkInterfaces, runNetworkInterface)
			}
		case "UserData":
			options.UserData = value.([]byte)
		}
	}

	params := makeParams("RunInstances")

	params["ImageId"] = options.ImageId

	params["InstanceType"] = options.InstanceType
	var min, max int
	if options.MinCount == 0 && options.MaxCount == 0 {
		min = 1
		max = 1
	} else if options.MaxCount == 0 {
		min = options.MinCount
		max = min
	} else {
		min = options.MinCount
		max = options.MaxCount
	}
	params["MinCount"] = strconv.Itoa(min)
	params["MaxCount"] = strconv.Itoa(max)
	i, j := 1, 1
	for _, g := range options.SecurityGroups {
		if g.Id != "" {
			params["SecurityGroupId."+strconv.Itoa(i)] = g.Id
			i++
		} else {
			params["SecurityGroup."+strconv.Itoa(j)] = g.Name
			j++
		}
	}
	prepareBlockDevices(params, options.BlockDeviceMappings)
	prepareNetworkInterfaces(params, options.NetworkInterfaces)
	token, err := clientToken()
	if err != nil {
		return nil, err
	}
	params["ClientToken"] = token

	if options.KeyName != "" {
		params["KeyName"] = options.KeyName
	}
	if options.KernelId != "" {
		params["KernelId"] = options.KernelId
	}
	if options.RamdiskId != "" {
		params["RamdiskId"] = options.RamdiskId
	}
	if options.UserData != nil {
		userData := make([]byte, base64.StdEncoding.EncodedLen(len(options.UserData)))
		base64.StdEncoding.Encode(userData, options.UserData)
		params["UserData"] = string(userData)
	}
	if options.AvailZone != "" {
		params["Placement.AvailabilityZone"] = options.AvailZone
	}
	if options.PlacementGroupName != "" {
		params["Placement.GroupName"] = options.PlacementGroupName
	}
	if options.Monitoring {
		params["Monitoring.Enabled"] = "true"
	}
	if options.SubnetId != "" {
		params["SubnetId"] = options.SubnetId
	}
	if options.DisableAPITermination {
		params["DisableApiTermination"] = "true"
	}
	if options.ShutdownBehavior != "" {
		params["InstanceInitiatedShutdownBehavior"] = options.ShutdownBehavior
	}
	if options.PrivateIPAddress != "" {
		params["PrivateIpAddress"] = options.PrivateIPAddress
	}

	response := make(map[string]interface{})
	err = ec2.PrepareSignatureV2query(params, Region, response)
	resp = response

	return resp, err
}
<commit_msg>Solved a problem by me: mistakenly correcting letter cases<commit_after>package ec2

import (
	"encoding/base64"
	"strconv"
)

// start ec2 instance accept array of instance-id

func (ec2 *EC2) Startnode(request interface{}) (resp interface{}, err error) {

	param := request.(map[string]string)
	ids := []string{}
	ids = append(ids, param["instance-id"])
	Region := param["Region"]

	params := makeParams("StartInstances")

	addParamsList(params, "InstanceId", ids)

	response := make(map[string]interface{})

	err = ec2.PrepareSignatureV2query(params, Region, response)
	resp = response
	return resp, err
}

// stop ec2 instance accept array of instance-id

func (ec2 *EC2) Stopnode(request interface{}) (resp interface{}, err error) {

	param := request.(map[string]string)
	ids := []string{}
	ids = append(ids, param["instance-id"])
	Region := param["Region"]

	params := makeParams("StopInstances")
	addParamsList(params, "InstanceId", ids)
	resp = &StopInstanceResp{}

	response := make(map[string]interface{})

	err = ec2.PrepareSignatureV2query(params, Region, response)

	if err != nil {
		return nil, err
	}

	resp = response
	return resp, nil
}

// reboot ec2 instance accept array of instance-id

func (ec2 *EC2) Rebootnode(request interface{}) (resp interface{}, err error) {

	param := request.(map[string]string)
	ids := []string{}
	ids = append(ids, param["instance-id"])
	Region := param["Region"]

	params := makeParams("RebootInstances")
	addParamsList(params, "InstanceId", ids)

	response := make(map[string]interface{})

	err = ec2.PrepareSignatureV2query(params, Region, response)
	if err != nil {
		return nil, err
	}
	resp = response
	return resp, err
}

// delete ec2 instance accept array of instance-id

func (ec2 *EC2) Deletenode(request interface{}) (resp interface{}, err error) {
	param := request.(map[string]string)
	instIds := []string{}
	instIds = append(instIds, param["instance-id"])
	Region := param["Region"]

	params := makeParams("TerminateInstances")
	addParamsList(params, "InstanceId", instIds)
	response := make(map[string]interface{})

	err = ec2.PrepareSignatureV2query(params, Region, response)
	if err != nil {
		return nil, err
	}
	resp = response
	return resp, err
}

//create Ec2 instances accept map[string]interface{} with attribute Define in EC2 documentation

func (ec2 *EC2) Createnode(request interface{}) (resp interface{}, err error) {

	var options RunInstances
	var Region string

	param := make(map[string]interface{})

	param = request.(map[string]interface{})

	for key, value := range param {
		switch key {

		case "Region":
			regionV, _ := value.(string)
			Region = regionV

		case "ImageId":
			ImageId, _ := value.(string)
			options.ImageId = ImageId

		case "MinCount":
			MinCount, _ := value.(int)
			options.MinCount = MinCount

		case "MaxCount":
			MaxCount, _ := value.(int)
			options.MaxCount = MaxCount

		case "KeyName":
			KeyName, _ := value.(string)
			options.KeyName = KeyName

		case "KernelId":
			KernelId, _ := value.(string)
			options.KernelId = KernelId

		case "InstanceType":
			InstanceType, _ := value.(string)
			options.InstanceType = InstanceType

		case "RamdiskId":
			RamdiskId, _ := value.(string)
			options.RamdiskId = RamdiskId

		case "AvailZone":
			AvailZone, _ := value.(string)
			options.AvailZone = AvailZone

		case "PlacementGroupName":
			PlacementGroupName, _ := value.(string)
			options.PlacementGroupName = PlacementGroupName

		case "Monitoring":
			Monitoring, _ := value.(bool)
			options.Monitoring = Monitoring

		case "SubnetId":
			SubnetId, _ := value.(string)
			options.SubnetId = SubnetId

		case "DisableAPITermination":
			DisableAPITermination, _ := value.(bool)
			options.DisableAPITermination = DisableAPITermination

		case "ShutdownBehavior":
			ShutdownBehavior, _ := value.(string)
			options.ShutdownBehavior = ShutdownBehavior

		case "PrivateIPAddress":
			PrivateIPAddress, _ := value.(string)
			options.PrivateIPAddress = PrivateIPAddress

		case "SecurityGroup":
			SecurityGroupparam, _ := value.([]map[string]string)
			for i := 0; i < len(SecurityGroupparam); i++ {
				var securityGroup SecurityGroup
				securityGroup.Id = SecurityGroupparam[i]["Id"]
				securityGroup.Name = SecurityGroupparam[i]["Name"]
				options.SecurityGroups = append(options.SecurityGroups, securityGroup)
			}

		case "BlockDevice":
			BlockDeviceparam, _ := value.([]map[string]interface{})
			for i := 0; i < len(BlockDeviceparam); i++ {
				var BlockDeviceMappingParam BlockDeviceMapping
				for BlockDeviceparamkey, BlockDeviceparamvalue := range BlockDeviceparam[i] {
					switch BlockDeviceparamkey {
					case "DeviceName":
						BlockDeviceMappingParam.DeviceName = BlockDeviceparamvalue.(string)

					case "VirtualName":
						BlockDeviceMappingParam.VirtualName = BlockDeviceparamvalue.(string)

					case "SnapshotId":
						BlockDeviceMappingParam.SnapshotId = BlockDeviceparamvalue.(string)

					case "VolumeType":
						BlockDeviceMappingParam.VolumeType = BlockDeviceparamvalue.(string)

					case "VolumeSize":
						BlockDeviceMappingParam.VolumeSize = BlockDeviceparamvalue.(int64)

					case "DeleteOnTermination":
						BlockDeviceMappingParam.DeleteOnTermination = BlockDeviceparamvalue.(bool)

					case "IOPS":
						BlockDeviceMappingParam.IOPS = BlockDeviceparamvalue.(int64)

					}
				}
				options.BlockDeviceMappings = append(options.BlockDeviceMappings, BlockDeviceMappingParam)

			}

		case "RunNetworkInterface":
			RunNetworkInterfaceparam, _ := value.([]map[string]interface{})
			var runNetworkInterface RunNetworkInterface
			for i := 0; i < len(RunNetworkInterfaceparam); i++ {
				for RunNetworkInterfaceparamkey, RunNetworkInterfaceparamvalue := range RunNetworkInterfaceparam[i] {
					switch RunNetworkInterfaceparamkey {
					case "Id":
						runNetworkInterface.Id = RunNetworkInterfaceparamvalue.(string)
					case "DeviceIndex":
						runNetworkInterface.DeviceIndex = RunNetworkInterfaceparamvalue.(int)
					case "SubnetId":
						runNetworkInterface.Id = RunNetworkInterfaceparamvalue.(string)
					case "Description":
						runNetworkInterface.Description = RunNetworkInterfaceparamvalue.(string)
					case "DeleteOnTermination":
						runNetworkInterface.DeleteOnTermination = RunNetworkInterfaceparamvalue.(bool)
					case "SecondaryPrivateIPCount":
						runNetworkInterface.SecondaryPrivateIPCount = RunNetworkInterfaceparamvalue.(int)
					case "SecurityGroupIds":
						securityGroupIds, _ := RunNetworkInterfaceparamvalue.([]string)
						runNetworkInterface.SecurityGroupIds = securityGroupIds

					case "PrivateIPs":
						privateIPsParam, _ := RunNetworkInterfaceparamvalue.([]map[string]interface{})
						for i := 0; i < len(privateIPsParam); i++ {
							var privateIP PrivateIP
							for privateIPsParamkey, privateIPsParamvalue := range privateIPsParam[i] {
								switch privateIPsParamkey {
								case "Address":
									privateIP.Address = privateIPsParamvalue.(string)
								case "DNSName":
									privateIP.DNSName = privateIPsParamvalue.(string)
								case "IsPrimary":
									privateIP.IsPrimary = privateIPsParamvalue.(bool)
								}

							}
							runNetworkInterface.PrivateIPs = append(runNetworkInterface.PrivateIPs, privateIP)
						}

					}

				}
				options.NetworkInterfaces = append(options.NetworkInterfaces, runNetworkInterface)
			}
		case "UserData":
			options.UserData = value.([]byte)
		}
	}

	params := makeParams("RunInstances")

	params["ImageId"] = options.ImageId

	params["InstanceType"] = options.InstanceType
	var min, max int
	if options.MinCount == 0 && options.MaxCount == 0 {
		min = 1
		max = 1
	} else if options.MaxCount == 0 {
		min = options.MinCount
		max = min
	} else {
		min = options.MinCount
		max = options.MaxCount
	}
	params["MinCount"] = strconv.Itoa(min)
	params["MaxCount"] = strconv.Itoa(max)
	i, j := 1, 1
	for _, g := range options.SecurityGroups {
		if g.Id != "" {
			params["SecurityGroupId."+strconv.Itoa(i)] = g.Id
			i++
		} else {
			params["SecurityGroup."+strconv.Itoa(j)] = g.Name
			j++
		}
	}
	prepareBlockDevices(params, options.BlockDeviceMappings)
	prepareNetworkInterfaces(params, options.NetworkInterfaces)
	token, err := clientToken()
	if err != nil {
		return nil, err
	}
	params["ClientToken"] = token

	if options.KeyName != "" {
		params["KeyName"] = options.KeyName
	}
	if options.KernelId != "" {
		params["KernelId"] = options.KernelId
	}
	if options.RamdiskId != "" {
		params["RamdiskId"] = options.RamdiskId
	}
	if options.UserData != nil {
		userData := make([]byte, base64.StdEncoding.EncodedLen(len(options.UserData)))
		base64.StdEncoding.Encode(userData, options.UserData)
		params["UserData"] = string(userData)
	}
	if options.AvailZone != "" {
		params["Placement.AvailabilityZone"] = options.AvailZone
	}
	if options.PlacementGroupName != "" {
		params["Placement.GroupName"] = options.PlacementGroupName
	}
	if options.Monitoring {
		params["Monitoring.Enabled"] = "true"
	}
	if options.SubnetId != "" {
		params["SubnetId"] = options.SubnetId
	}
	if options.DisableAPITermination {
		params["DisableApiTermination"] = "true"
	}
	if options.ShutdownBehavior != "" {
		params["InstanceInitiatedShutdownBehavior"] = options.ShutdownBehavior
	}
	if options.PrivateIPAddress != "" {
		params["PrivateIpAddress"] = options.PrivateIPAddress
	}

	response := make(map[string]interface{})
	err = ec2.PrepareSignatureV2query(params, Region, response)
	resp = response

	return resp, err
}
<|endoftext|>


<commit_before>package hcltest

import (
	"fmt"

	"github.com/hashicorp/hcl2/hcl"
	"github.com/zclconf/go-cty/cty"
)

// MockBody returns a hcl.Body implementation that works in terms of a
// caller-constructed hcl.BodyContent, thus avoiding the need to parse
// a "real" zcl config file to use as input to a test.
func MockBody(content *hcl.BodyContent) hcl.Body {
	return mockBody{content}
}

type mockBody struct {
	C *hcl.BodyContent
}

func (b mockBody) Content(schema *hcl.BodySchema) (*hcl.BodyContent, hcl.Diagnostics) {
	content, remainI, diags := b.PartialContent(schema)
	remain := remainI.(mockBody)
	for _, attr := range remain.C.Attributes {
		diags = append(diags, &hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Extraneous attribute in mock body",
			Detail:   fmt.Sprintf("Mock body has extraneous attribute %q.", attr.Name),
			Subject:  &attr.NameRange,
		})
	}
	for _, block := range remain.C.Blocks {
		diags = append(diags, &hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Extraneous block in mock body",
			Detail:   fmt.Sprintf("Mock body has extraneous block of type %q.", block.Type),
			Subject:  &block.DefRange,
		})
	}
	return content, diags
}

func (b mockBody) PartialContent(schema *hcl.BodySchema) (*hcl.BodyContent, hcl.Body, hcl.Diagnostics) {
	ret := &hcl.BodyContent{
		Attributes:       map[string]*hcl.Attribute{},
		Blocks:           []*hcl.Block{},
		MissingItemRange: b.C.MissingItemRange,
	}
	remain := &hcl.BodyContent{
		Attributes:       map[string]*hcl.Attribute{},
		Blocks:           []*hcl.Block{},
		MissingItemRange: b.C.MissingItemRange,
	}
	var diags hcl.Diagnostics

	if len(schema.Attributes) != 0 {
		for _, attrS := range schema.Attributes {
			name := attrS.Name
			attr, ok := b.C.Attributes[name]
			if !ok {
				if attrS.Required {
					diags = append(diags, &hcl.Diagnostic{
						Severity: hcl.DiagError,
						Summary:  "Missing required attribute",
						Detail:   fmt.Sprintf("Mock body doesn't have attribute %q", name),
						Subject:  b.C.MissingItemRange.Ptr(),
					})
				}
				continue
			}
			ret.Attributes[name] = attr
		}
	}

	for attrN, attr := range b.C.Attributes {
		if _, ok := ret.Attributes[attrN]; !ok {
			remain.Attributes[attrN] = attr
		}
	}

	wantedBlocks := map[string]hcl.BlockHeaderSchema{}
	for _, blockS := range schema.Blocks {
		wantedBlocks[blockS.Type] = blockS
	}

	for _, block := range b.C.Blocks {
		if blockS, ok := wantedBlocks[block.Type]; ok {
			if len(block.Labels) != len(blockS.LabelNames) {
				diags = append(diags, &hcl.Diagnostic{
					Severity: hcl.DiagError,
					Summary:  "Wrong number of block labels",
					Detail:   fmt.Sprintf("Block of type %q requires %d labels, but got %d", blockS.Type, len(blockS.LabelNames), len(block.Labels)),
					Subject:  b.C.MissingItemRange.Ptr(),
				})
			}

			ret.Blocks = append(ret.Blocks, block)
		} else {
			remain.Blocks = append(remain.Blocks, block)
		}
	}

	return ret, mockBody{remain}, diags
}

func (b mockBody) JustAttributes() (hcl.Attributes, hcl.Diagnostics) {
	var diags hcl.Diagnostics
	if len(b.C.Blocks) != 0 {
		diags = append(diags, &hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Mock body has blocks",
			Detail:   "Can't use JustAttributes on a mock body with blocks.",
			Subject:  b.C.MissingItemRange.Ptr(),
		})
	}

	return b.C.Attributes, diags
}

func (b mockBody) MissingItemRange() hcl.Range {
	return b.C.MissingItemRange
}

// MockExprLiteral returns a hcl.Expression that evaluates to the given literal
// value.
func MockExprLiteral(val cty.Value) hcl.Expression {
	return mockExprLiteral{val}
}

type mockExprLiteral struct {
	V cty.Value
}

func (e mockExprLiteral) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
	return e.V, nil
}

func (e mockExprLiteral) Variables() []hcl.Traversal {
	return nil
}

func (e mockExprLiteral) Range() hcl.Range {
	return hcl.Range{
		Filename: "MockExprLiteral",
	}
}

func (e mockExprLiteral) StartRange() hcl.Range {
	return e.Range()
}

// MockExprVariable returns a hcl.Expression that evaluates to the value of
// the variable with the given name.
func MockExprVariable(name string) hcl.Expression {
	return mockExprVariable(name)
}

type mockExprVariable string

func (e mockExprVariable) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
	name := string(e)
	for ctx != nil {
		if val, ok := ctx.Variables[name]; ok {
			return val, nil
		}
		ctx = ctx.Parent()
	}

	// If we fall out here then there is no variable with the given name
	return cty.DynamicVal, hcl.Diagnostics{
		{
			Severity: hcl.DiagError,
			Summary:  "Reference to undefined variable",
			Detail:   fmt.Sprintf("Variable %q is not defined.", name),
		},
	}
}

func (e mockExprVariable) Variables() []hcl.Traversal {
	return []hcl.Traversal{
		{
			hcl.TraverseRoot{
				Name:     string(e),
				SrcRange: e.Range(),
			},
		},
	}
}

func (e mockExprVariable) Range() hcl.Range {
	return hcl.Range{
		Filename: "MockExprVariable",
	}
}

func (e mockExprVariable) StartRange() hcl.Range {
	return e.Range()
}

// MockAttrs constructs and returns a hcl.Attributes map with attributes
// derived from the given expression map.
//
// Each entry in the map becomes an attribute whose name is the key and
// whose expression is the value.
func MockAttrs(exprs map[string]hcl.Expression) hcl.Attributes {
	ret := make(hcl.Attributes)
	for name, expr := range exprs {
		ret[name] = &hcl.Attribute{
			Name: name,
			Expr: expr,
			Range: hcl.Range{
				Filename: "MockAttrs",
			},
			NameRange: hcl.Range{
				Filename: "MockAttrs",
			},
		}
	}
	return ret
}
<commit_msg>hcltest: new implementations for ExprList and AbsTraversalForExpr<commit_after>package hcltest

import (
	"fmt"

	"github.com/hashicorp/hcl2/hcl/hclsyntax"

	"github.com/hashicorp/hcl2/hcl"
	"github.com/zclconf/go-cty/cty"
)

// MockBody returns a hcl.Body implementation that works in terms of a
// caller-constructed hcl.BodyContent, thus avoiding the need to parse
// a "real" zcl config file to use as input to a test.
func MockBody(content *hcl.BodyContent) hcl.Body {
	return mockBody{content}
}

type mockBody struct {
	C *hcl.BodyContent
}

func (b mockBody) Content(schema *hcl.BodySchema) (*hcl.BodyContent, hcl.Diagnostics) {
	content, remainI, diags := b.PartialContent(schema)
	remain := remainI.(mockBody)
	for _, attr := range remain.C.Attributes {
		diags = append(diags, &hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Extraneous attribute in mock body",
			Detail:   fmt.Sprintf("Mock body has extraneous attribute %q.", attr.Name),
			Subject:  &attr.NameRange,
		})
	}
	for _, block := range remain.C.Blocks {
		diags = append(diags, &hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Extraneous block in mock body",
			Detail:   fmt.Sprintf("Mock body has extraneous block of type %q.", block.Type),
			Subject:  &block.DefRange,
		})
	}
	return content, diags
}

func (b mockBody) PartialContent(schema *hcl.BodySchema) (*hcl.BodyContent, hcl.Body, hcl.Diagnostics) {
	ret := &hcl.BodyContent{
		Attributes:       map[string]*hcl.Attribute{},
		Blocks:           []*hcl.Block{},
		MissingItemRange: b.C.MissingItemRange,
	}
	remain := &hcl.BodyContent{
		Attributes:       map[string]*hcl.Attribute{},
		Blocks:           []*hcl.Block{},
		MissingItemRange: b.C.MissingItemRange,
	}
	var diags hcl.Diagnostics

	if len(schema.Attributes) != 0 {
		for _, attrS := range schema.Attributes {
			name := attrS.Name
			attr, ok := b.C.Attributes[name]
			if !ok {
				if attrS.Required {
					diags = append(diags, &hcl.Diagnostic{
						Severity: hcl.DiagError,
						Summary:  "Missing required attribute",
						Detail:   fmt.Sprintf("Mock body doesn't have attribute %q", name),
						Subject:  b.C.MissingItemRange.Ptr(),
					})
				}
				continue
			}
			ret.Attributes[name] = attr
		}
	}

	for attrN, attr := range b.C.Attributes {
		if _, ok := ret.Attributes[attrN]; !ok {
			remain.Attributes[attrN] = attr
		}
	}

	wantedBlocks := map[string]hcl.BlockHeaderSchema{}
	for _, blockS := range schema.Blocks {
		wantedBlocks[blockS.Type] = blockS
	}

	for _, block := range b.C.Blocks {
		if blockS, ok := wantedBlocks[block.Type]; ok {
			if len(block.Labels) != len(blockS.LabelNames) {
				diags = append(diags, &hcl.Diagnostic{
					Severity: hcl.DiagError,
					Summary:  "Wrong number of block labels",
					Detail:   fmt.Sprintf("Block of type %q requires %d labels, but got %d", blockS.Type, len(blockS.LabelNames), len(block.Labels)),
					Subject:  b.C.MissingItemRange.Ptr(),
				})
			}

			ret.Blocks = append(ret.Blocks, block)
		} else {
			remain.Blocks = append(remain.Blocks, block)
		}
	}

	return ret, mockBody{remain}, diags
}

func (b mockBody) JustAttributes() (hcl.Attributes, hcl.Diagnostics) {
	var diags hcl.Diagnostics
	if len(b.C.Blocks) != 0 {
		diags = append(diags, &hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Mock body has blocks",
			Detail:   "Can't use JustAttributes on a mock body with blocks.",
			Subject:  b.C.MissingItemRange.Ptr(),
		})
	}

	return b.C.Attributes, diags
}

func (b mockBody) MissingItemRange() hcl.Range {
	return b.C.MissingItemRange
}

// MockExprLiteral returns a hcl.Expression that evaluates to the given literal
// value.
func MockExprLiteral(val cty.Value) hcl.Expression {
	return mockExprLiteral{val}
}

type mockExprLiteral struct {
	V cty.Value
}

func (e mockExprLiteral) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
	return e.V, nil
}

func (e mockExprLiteral) Variables() []hcl.Traversal {
	return nil
}

func (e mockExprLiteral) Range() hcl.Range {
	return hcl.Range{
		Filename: "MockExprLiteral",
	}
}

func (e mockExprLiteral) StartRange() hcl.Range {
	return e.Range()
}

// Implementation for hcl.ExprList
func (e mockExprLiteral) ExprList() []hcl.Expression {
	v := e.V
	ty := v.Type()
	if v.IsKnown() && !v.IsNull() && (ty.IsListType() || ty.IsTupleType()) {
		ret := make([]hcl.Expression, 0, v.LengthInt())
		for it := v.ElementIterator(); it.Next(); {
			_, v := it.Element()
			ret = append(ret, MockExprLiteral(v))
		}
		return ret
	}
	return nil
}

// MockExprVariable returns a hcl.Expression that evaluates to the value of
// the variable with the given name.
func MockExprVariable(name string) hcl.Expression {
	return mockExprVariable(name)
}

type mockExprVariable string

func (e mockExprVariable) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
	name := string(e)
	for ctx != nil {
		if val, ok := ctx.Variables[name]; ok {
			return val, nil
		}
		ctx = ctx.Parent()
	}

	// If we fall out here then there is no variable with the given name
	return cty.DynamicVal, hcl.Diagnostics{
		{
			Severity: hcl.DiagError,
			Summary:  "Reference to undefined variable",
			Detail:   fmt.Sprintf("Variable %q is not defined.", name),
		},
	}
}

func (e mockExprVariable) Variables() []hcl.Traversal {
	return []hcl.Traversal{
		{
			hcl.TraverseRoot{
				Name:     string(e),
				SrcRange: e.Range(),
			},
		},
	}
}

func (e mockExprVariable) Range() hcl.Range {
	return hcl.Range{
		Filename: "MockExprVariable",
	}
}

func (e mockExprVariable) StartRange() hcl.Range {
	return e.Range()
}

// Implementation for hcl.AbsTraversalForExpr and hcl.RelTraversalForExpr.
func (e mockExprVariable) AsTraversal() hcl.Traversal {
	return hcl.Traversal{
		hcl.TraverseRoot{
			Name:     string(e),
			SrcRange: e.Range(),
		},
	}
}

// MockExprTraversal returns a hcl.Expression that evaluates the given
// absolute traversal.
func MockExprTraversal(traversal hcl.Traversal) hcl.Expression {
	return mockExprTraversal{
		Traversal: traversal,
	}
}

// MockExprTraversalSrc is like MockExprTraversal except it takes a
// traversal string as defined by the native syntax and parses it first.
//
// This method is primarily for testing with hard-coded traversal strings, so
// it will panic if the given string is not syntactically correct.
func MockExprTraversalSrc(src string) hcl.Expression {
	traversal, diags := hclsyntax.ParseTraversalAbs([]byte(src), "MockExprTraversal", hcl.Pos{})
	if diags.HasErrors() {
		panic("invalid traversal string")
	}
	return MockExprTraversal(traversal)
}

type mockExprTraversal struct {
	Traversal hcl.Traversal
}

func (e mockExprTraversal) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
	return e.Traversal.TraverseAbs(ctx)
}

func (e mockExprTraversal) Variables() []hcl.Traversal {
	return []hcl.Traversal{e.Traversal}
}

func (e mockExprTraversal) Range() hcl.Range {
	return e.Traversal.SourceRange()
}

func (e mockExprTraversal) StartRange() hcl.Range {
	return e.Range()
}

// Implementation for hcl.AbsTraversalForExpr and hcl.RelTraversalForExpr.
func (e mockExprTraversal) AsTraversal() hcl.Traversal {
	return e.Traversal
}

func MockExprList(exprs []hcl.Expression) hcl.Expression {
	return mockExprList{
		Exprs: exprs,
	}
}

type mockExprList struct {
	Exprs []hcl.Expression
}

func (e mockExprList) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
	if len(e.Exprs) == 0 {
		return cty.ListValEmpty(cty.DynamicPseudoType), nil
	}
	vals := make([]cty.Value, 0, len(e.Exprs))
	var diags hcl.Diagnostics

	for _, expr := range e.Exprs {
		val, valDiags := expr.Value(ctx)
		diags = append(diags, valDiags...)
		vals = append(vals, val)
	}

	return cty.ListVal(vals), diags
}

func (e mockExprList) Variables() []hcl.Traversal {
	var traversals []hcl.Traversal
	for _, expr := range e.Exprs {
		traversals = append(traversals, expr.Variables()...)
	}
	return traversals
}

func (e mockExprList) Range() hcl.Range {
	return hcl.Range{
		Filename: "MockExprList",
	}
}

func (e mockExprList) StartRange() hcl.Range {
	return e.Range()
}

// Implementation for hcl.ExprList
func (e mockExprList) ExprList() []hcl.Expression {
	return e.Exprs
}

// MockAttrs constructs and returns a hcl.Attributes map with attributes
// derived from the given expression map.
//
// Each entry in the map becomes an attribute whose name is the key and
// whose expression is the value.
func MockAttrs(exprs map[string]hcl.Expression) hcl.Attributes {
	ret := make(hcl.Attributes)
	for name, expr := range exprs {
		ret[name] = &hcl.Attribute{
			Name: name,
			Expr: expr,
			Range: hcl.Range{
				Filename: "MockAttrs",
			},
			NameRange: hcl.Range{
				Filename: "MockAttrs",
			},
		}
	}
	return ret
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"math/rand"
	"net/http"
	_ "net/http/pprof"

	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/bitly/go-nsq"
	"github.com/bitly/nsq/internal/app"
	"github.com/raintank/raintank-metric/metricdef"
	"github.com/raintank/raintank-metric/setting"
)

var (
	showVersion = flag.Bool("version", false, "print version string")

	topic         = flag.String("topic", "", "NSQ topic")
	channel       = flag.String("channel", "", "NSQ channel")
	maxInFlight   = flag.Int("max-in-flight", 200, "max number of messages to allow in flight")
	totalMessages = flag.Int("n", 0, "total messages to process (will wait if starved)")

	consumerOpts     = app.StringArray{}
	nsqdTCPAddrs     = app.StringArray{}
	lookupdHTTPAddrs = app.StringArray{}
)

func init() {
	flag.Var(&consumerOpts, "consumer-opt", "option to passthrough to nsq.Consumer (may be given multiple times, http://godoc.org/github.com/bitly/go-nsq#Config)")
	flag.Var(&nsqdTCPAddrs, "nsqd-tcp-address", "nsqd TCP address (may be given multiple times)")
	flag.Var(&lookupdHTTPAddrs, "lookupd-http-address", "lookupd HTTP address (may be given multiple times)")
}

type ESHandler struct {
	totalMessages int
	messagesDone  int
}

func NewESHandler(totalMessages int) (*ESHandler, error) {

	err := metricdef.InitElasticsearch()
	if err != nil {
		return nil, err
	}
	err = metricdef.InitRedis()
	if err != nil {
		return nil, err
	}

	return &ESHandler{
		totalMessages: totalMessages,
	}, nil
}

func (k *ESHandler) HandleMessage(m *nsq.Message) error {
	k.messagesDone++
	format := "unknown"
	if m.Body[0] == '\x00' {
		format = "msgFormatMetricDefinitionArrayJson"
	}

	metrics := make([]*metricdef.IndvMetric, 0)
	if err := json.Unmarshal(m.Body[9:], &metrics); err != nil {
		log.Printf("ERROR: failure to unmarshal message body via format %s: %s. skipping message", format, err)
		return nil
	}

	for _, m := range metrics {
		if err := m.EnsureIndex(); err != nil {
			fmt.Printf("ERROR: couldn't process %s: %s\n", m.Id, err)
			return err
		}
	}

	if k.totalMessages > 0 && k.messagesDone >= k.totalMessages {
		os.Exit(0)
	}
	return nil
}

func main() {
	flag.Parse()

	if *showVersion {
		fmt.Println("nsq_to_elasticsearch")
		return
	}

	if *channel == "" {
		rand.Seed(time.Now().UnixNano())
		*channel = fmt.Sprintf("tail%06d#ephemeral", rand.Int()%999999)
	}

	if *topic == "" {
		log.Fatal("--topic is required")
	}

	if len(nsqdTCPAddrs) == 0 && len(lookupdHTTPAddrs) == 0 {
		log.Fatal("--nsqd-tcp-address or --lookupd-http-address required")
	}
	if len(nsqdTCPAddrs) > 0 && len(lookupdHTTPAddrs) > 0 {
		log.Fatal("use --nsqd-tcp-address or --lookupd-http-address not both")
	}

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

	// Don't ask for more messages than we want
	if *totalMessages > 0 && *totalMessages < *maxInFlight {
		*maxInFlight = *totalMessages
	}

	setting.Config = new(setting.Conf)
	setting.Config.ElasticsearchDomain = "elasticsearch"
	setting.Config.ElasticsearchPort = 9200
	setting.Config.RedisAddr = "redis:6379"

	cfg := nsq.NewConfig()
	cfg.UserAgent = "nsq_to_elasticsearch"
	err := app.ParseOpts(cfg, consumerOpts)
	if err != nil {
		log.Fatal(err)
	}
	cfg.MaxInFlight = *maxInFlight

	consumer, err := nsq.NewConsumer(*topic, *channel, cfg)
	if err != nil {
		log.Fatal(err)
	}

	handler, err := NewESHandler(*totalMessages)
	if err != nil {
		log.Fatal(err)
	}

	consumer.AddHandler(handler)

	err = consumer.ConnectToNSQDs(nsqdTCPAddrs)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("connected to nsqd")

	err = consumer.ConnectToNSQLookupds(lookupdHTTPAddrs)
	if err != nil {
		log.Fatal(err)
	}
	go func() {
		log.Println("INFO starting listener for http/debug on :6060")
		log.Println(http.ListenAndServe(":6060", nil))
	}()

	for {
		select {
		case <-consumer.StopChan:
			return
		case <-sigChan:
			consumer.Stop()
		}
	}
}
<commit_msg>process each metric batch in a goroutine<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"math/rand"
	"net/http"
	_ "net/http/pprof"

	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/bitly/go-nsq"
	"github.com/bitly/nsq/internal/app"
	"github.com/raintank/raintank-metric/metricdef"
	"github.com/raintank/raintank-metric/setting"
)

var (
	showVersion = flag.Bool("version", false, "print version string")

	topic         = flag.String("topic", "", "NSQ topic")
	channel       = flag.String("channel", "", "NSQ channel")
	maxInFlight   = flag.Int("max-in-flight", 200, "max number of messages to allow in flight")
	totalMessages = flag.Int("n", 0, "total messages to process (will wait if starved)")

	consumerOpts     = app.StringArray{}
	nsqdTCPAddrs     = app.StringArray{}
	lookupdHTTPAddrs = app.StringArray{}
)

func init() {
	flag.Var(&consumerOpts, "consumer-opt", "option to passthrough to nsq.Consumer (may be given multiple times, http://godoc.org/github.com/bitly/go-nsq#Config)")
	flag.Var(&nsqdTCPAddrs, "nsqd-tcp-address", "nsqd TCP address (may be given multiple times)")
	flag.Var(&lookupdHTTPAddrs, "lookupd-http-address", "lookupd HTTP address (may be given multiple times)")
}

type ESHandler struct {
	totalMessages int
	messagesDone  int
}

func NewESHandler(totalMessages int) (*ESHandler, error) {

	err := metricdef.InitElasticsearch()
	if err != nil {
		return nil, err
	}
	err = metricdef.InitRedis()
	if err != nil {
		return nil, err
	}

	return &ESHandler{
		totalMessages: totalMessages,
	}, nil
}

func (k *ESHandler) HandleMessage(m *nsq.Message) error {
	k.messagesDone++
	format := "unknown"
	if m.Body[0] == '\x00' {
		format = "msgFormatMetricDefinitionArrayJson"
	}

	metrics := make([]*metricdef.IndvMetric, 0)
	if err := json.Unmarshal(m.Body[9:], &metrics); err != nil {
		log.Printf("ERROR: failure to unmarshal message body via format %s: %s. skipping message", format, err)
		return nil
	}
	done := make(chan error, 1)
	go func() {
		for _, m := range metrics {
			if err := m.EnsureIndex(); err != nil {
				fmt.Printf("ERROR: couldn't process %s: %s\n", m.Id, err)
				done <- err
				return
			}
		}
		done <- nil
	}()

	if err := <-done; err != nil {
		return err
	}

	if k.totalMessages > 0 && k.messagesDone >= k.totalMessages {
		os.Exit(0)
	}
	return nil
}

func main() {
	flag.Parse()

	if *showVersion {
		fmt.Println("nsq_to_elasticsearch")
		return
	}

	if *channel == "" {
		rand.Seed(time.Now().UnixNano())
		*channel = fmt.Sprintf("tail%06d#ephemeral", rand.Int()%999999)
	}

	if *topic == "" {
		log.Fatal("--topic is required")
	}

	if len(nsqdTCPAddrs) == 0 && len(lookupdHTTPAddrs) == 0 {
		log.Fatal("--nsqd-tcp-address or --lookupd-http-address required")
	}
	if len(nsqdTCPAddrs) > 0 && len(lookupdHTTPAddrs) > 0 {
		log.Fatal("use --nsqd-tcp-address or --lookupd-http-address not both")
	}

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

	// Don't ask for more messages than we want
	if *totalMessages > 0 && *totalMessages < *maxInFlight {
		*maxInFlight = *totalMessages
	}

	setting.Config = new(setting.Conf)
	setting.Config.ElasticsearchDomain = "elasticsearch"
	setting.Config.ElasticsearchPort = 9200
	setting.Config.RedisAddr = "redis:6379"

	cfg := nsq.NewConfig()
	cfg.UserAgent = "nsq_to_elasticsearch"
	err := app.ParseOpts(cfg, consumerOpts)
	if err != nil {
		log.Fatal(err)
	}
	cfg.MaxInFlight = *maxInFlight

	consumer, err := nsq.NewConsumer(*topic, *channel, cfg)
	if err != nil {
		log.Fatal(err)
	}

	handler, err := NewESHandler(*totalMessages)
	if err != nil {
		log.Fatal(err)
	}

	consumer.AddHandler(handler)

	err = consumer.ConnectToNSQDs(nsqdTCPAddrs)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("connected to nsqd")

	err = consumer.ConnectToNSQLookupds(lookupdHTTPAddrs)
	if err != nil {
		log.Fatal(err)
	}
	go func() {
		log.Println("INFO starting listener for http/debug on :6060")
		log.Println(http.ListenAndServe(":6060", nil))
	}()

	for {
		select {
		case <-consumer.StopChan:
			return
		case <-sigChan:
			consumer.Stop()
		}
	}
}
<|endoftext|>


<commit_before>package logging

import (
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"strings"

	"github.com/hashicorp/go-syslog"
	"github.com/hashicorp/logutils"
)

// Levels are the log levels we respond to=o.
var Levels = []logutils.LogLevel{"DEBUG", "INFO", "WARN", "ERR"}

// Config is the configuration for this log setup.
type Config struct {
	// Name is the progname as it will appear in syslog output (if enabled).
	Name string

	// Level is the log level to use.
	Level string

	// Syslog and SyslogFacility are the syslog configuration options.
	Syslog         bool
	SyslogFacility string

	// Writer is the output where logs should go. If syslog is enabled, data will
	// be written to writer in addition to syslog.
	Writer io.Writer
}

func Setup(config *Config) error {
	var logOutput io.Writer

	// Setup the default logging
	logFilter := NewLogFilter()
	logFilter.MinLevel = logutils.LogLevel(strings.ToUpper(config.Level))
	logFilter.Writer = config.Writer
	if !ValidateLevelFilter(logFilter.MinLevel, logFilter) {
		levels := make([]string, 0, len(logFilter.Levels))
		for _, level := range logFilter.Levels {
			levels = append(levels, string(level))
		}
		return fmt.Errorf("invalid log level %q, valid log levels are %s",
			config.Level, strings.Join(levels, ", "))
	}

	// Check if syslog is enabled
	if config.Syslog {
		l, err := gsyslog.NewLogger(gsyslog.LOG_NOTICE, config.SyslogFacility, config.Name)
		if err != nil {
			return fmt.Errorf("error setting up syslog logger: %s", err)
		}
		syslog := &SyslogWrapper{l, logFilter}
		logOutput = io.MultiWriter(logFilter, syslog)
	} else {
		logOutput = io.MultiWriter(logFilter)
	}

	log.SetOutput(logOutput)

	return nil
}

// NewLogFilter returns a LevelFilter that is configured with the log levels that
// we use.
func NewLogFilter() *logutils.LevelFilter {
	return &logutils.LevelFilter{
		Levels:   Levels,
		MinLevel: "WARN",
		Writer:   ioutil.Discard,
	}
}

// ValidateLevelFilter verifies that the log levels within the filter are valid.
func ValidateLevelFilter(min logutils.LogLevel, filter *logutils.LevelFilter) bool {
	for _, level := range filter.Levels {
		if level == min {
			return true
		}
	}
	return false
}
<commit_msg>Add logging when setting up logging<commit_after>package logging

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"strings"

	"github.com/hashicorp/go-syslog"
	"github.com/hashicorp/logutils"
)

// Levels are the log levels we respond to=o.
var Levels = []logutils.LogLevel{"DEBUG", "INFO", "WARN", "ERR"}

// Config is the configuration for this log setup.
type Config struct {
	// Name is the progname as it will appear in syslog output (if enabled).
	Name string `json:"name"`

	// Level is the log level to use.
	Level string `json:"level"`

	// Syslog and SyslogFacility are the syslog configuration options.
	Syslog         bool   `json:"syslog"`
	SyslogFacility string `json:"syslog_facility"`

	// Writer is the output where logs should go. If syslog is enabled, data will
	// be written to writer in addition to syslog.
	Writer io.Writer `json:"-"`
}

func Setup(config *Config) error {
	log.Print("[DEBUG] (logging) setting up logging")
	result, err := json.MarshalIndent(config, "", "  ")
	if err != nil {
		return err
	}
	log.Printf("[DEBUG] (logging) config:\n\n%s\n\n", result)

	var logOutput io.Writer

	// Setup the default logging
	logFilter := NewLogFilter()
	logFilter.MinLevel = logutils.LogLevel(strings.ToUpper(config.Level))
	logFilter.Writer = config.Writer
	if !ValidateLevelFilter(logFilter.MinLevel, logFilter) {
		levels := make([]string, 0, len(logFilter.Levels))
		for _, level := range logFilter.Levels {
			levels = append(levels, string(level))
		}
		return fmt.Errorf("invalid log level %q, valid log levels are %s",
			config.Level, strings.Join(levels, ", "))
	}

	// Check if syslog is enabled
	if config.Syslog {
		log.Printf("[DEBUG] (logging) enabling syslog on %s", config.SyslogFacility)

		l, err := gsyslog.NewLogger(gsyslog.LOG_NOTICE, config.SyslogFacility, config.Name)
		if err != nil {
			return fmt.Errorf("error setting up syslog logger: %s", err)
		}
		syslog := &SyslogWrapper{l, logFilter}
		logOutput = io.MultiWriter(logFilter, syslog)
	} else {
		logOutput = io.MultiWriter(logFilter)
	}

	log.SetOutput(logOutput)

	return nil
}

// NewLogFilter returns a LevelFilter that is configured with the log levels that
// we use.
func NewLogFilter() *logutils.LevelFilter {
	return &logutils.LevelFilter{
		Levels:   Levels,
		MinLevel: "WARN",
		Writer:   ioutil.Discard,
	}
}

// ValidateLevelFilter verifies that the log levels within the filter are valid.
func ValidateLevelFilter(min logutils.LogLevel, filter *logutils.LevelFilter) bool {
	for _, level := range filter.Levels {
		if level == min {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>package aws

import (
	"bytes"
	"crypto/rand"
	"fmt"
	"log"
	"math/big"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/iam"
	"github.com/hashicorp/terraform/helper/encryption"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/validation"
)

func resourceAwsIamUserLoginProfile() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsIamUserLoginProfileCreate,
		Read:   schema.Noop,
		Update: schema.Noop,
		Delete: schema.RemoveFromState,

		Schema: map[string]*schema.Schema{
			"user": {
				Type:     schema.TypeString,
				Required: true,
			},
			"pgp_key": {
				Type:     schema.TypeString,
				Required: true,
			},
			"password_reset_required": {
				Type:     schema.TypeBool,
				Optional: true,
				Default:  true,
			},
			"password_length": {
				Type:         schema.TypeInt,
				Optional:     true,
				Default:      20,
				ValidateFunc: validation.IntBetween(5, 128),
			},

			"key_fingerprint": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"encrypted_password": {
				Type:     schema.TypeString,
				Computed: true,
			},
		},
	}
}

const (
	charLower   = "abcdefghijklmnopqrstuvwxyz"
	charUpper   = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	charNumbers = "0123456789"
	charSymbols = "!@#$%^&*()_+-=[]{}|'"
)

// generateIAMPassword generates a random password of a given length, matching the
// most restrictive iam password policy.
func generateIAMPassword(length int) string {
	const charset = charLower + charUpper + charNumbers + charSymbols

	result := make([]byte, length)
	charsetSize := big.NewInt(int64(len(charset)))

	// rather than trying to artificially add specific characters from each
	// class to the password to match the policy, we generate passwords
	// randomly and reject those that don't match.
	//
	// Even in the worst case, this tends to take less than 10 tries to find a
	// matching password. Any sufficiently long password is likely to succeed
	// on the first try
	for n := 0; n < 100000; n++ {
		for i := range result {
			r, err := rand.Int(rand.Reader, charsetSize)
			if err != nil {
				panic(err)
			}
			if !r.IsInt64() {
				panic("rand.Int() not representable as an Int64")
			}

			result[i] = charset[r.Int64()]
		}

		if !checkIAMPwdPolicy(result) {
			continue
		}

		return string(result)
	}

	panic("failed to generate acceptable password")
}

// Check the generated password contains all character classes listed in the
// IAM password policy.
func checkIAMPwdPolicy(pass []byte) bool {
	return (bytes.ContainsAny(pass, charLower) &&
		bytes.ContainsAny(pass, charNumbers) &&
		bytes.ContainsAny(pass, charSymbols) &&
		bytes.ContainsAny(pass, charUpper))
}

func resourceAwsIamUserLoginProfileCreate(d *schema.ResourceData, meta interface{}) error {
	iamconn := meta.(*AWSClient).iamconn

	encryptionKey, err := encryption.RetrieveGPGKey(strings.TrimSpace(d.Get("pgp_key").(string)))
	if err != nil {
		return err
	}

	username := d.Get("user").(string)
	passwordResetRequired := d.Get("password_reset_required").(bool)
	passwordLength := d.Get("password_length").(int)

	_, err = iamconn.GetLoginProfile(&iam.GetLoginProfileInput{
		UserName: aws.String(username),
	})
	if err != nil {
		// Catch AccessDenid errors (e.g. because we have no iam:GetLoginProfile permissions)
		if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "AccessDenied" {
			return err
		}
		if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() != "NoSuchEntity" {
			// If there is already a login profile, bring it under management (to prevent
			// resource creation diffs) - we will never modify it, but obviously cannot
			// set the password.
			d.SetId(username)
			d.Set("key_fingerprint", "")
			d.Set("encrypted_password", "")
			return nil
		}
	}

	initialPassword := generateIAMPassword(passwordLength)

	fingerprint, encrypted, err := encryption.EncryptValue(encryptionKey, initialPassword, "Password")
	if err != nil {
		return err
	}

	request := &iam.CreateLoginProfileInput{
		UserName:              aws.String(username),
		Password:              aws.String(initialPassword),
		PasswordResetRequired: aws.Bool(passwordResetRequired),
	}

	log.Println("[DEBUG] Create IAM User Login Profile request:", request)
	createResp, err := iamconn.CreateLoginProfile(request)
	if err != nil {
		if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "EntityAlreadyExists" {
			// If there is already a login profile, bring it under management (to prevent
			// resource creation diffs) - we will never modify it, but obviously cannot
			// set the password.
			d.SetId(username)
			d.Set("key_fingerprint", "")
			d.Set("encrypted_password", "")
			return nil
		}
		return fmt.Errorf("Error creating IAM User Login Profile for %q: %s", username, err)
	}

	d.SetId(*createResp.LoginProfile.UserName)
	d.Set("key_fingerprint", fingerprint)
	d.Set("encrypted_password", encrypted)
	return nil
}
<commit_msg>Implement bflads more beautiful code.<commit_after>package aws

import (
	"bytes"
	"crypto/rand"
	"fmt"
	"log"
	"math/big"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/iam"
	"github.com/hashicorp/terraform/helper/encryption"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/validation"
)

func resourceAwsIamUserLoginProfile() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsIamUserLoginProfileCreate,
		Read:   schema.Noop,
		Update: schema.Noop,
		Delete: schema.RemoveFromState,

		Schema: map[string]*schema.Schema{
			"user": {
				Type:     schema.TypeString,
				Required: true,
			},
			"pgp_key": {
				Type:     schema.TypeString,
				Required: true,
			},
			"password_reset_required": {
				Type:     schema.TypeBool,
				Optional: true,
				Default:  true,
			},
			"password_length": {
				Type:         schema.TypeInt,
				Optional:     true,
				Default:      20,
				ValidateFunc: validation.IntBetween(5, 128),
			},

			"key_fingerprint": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"encrypted_password": {
				Type:     schema.TypeString,
				Computed: true,
			},
		},
	}
}

const (
	charLower   = "abcdefghijklmnopqrstuvwxyz"
	charUpper   = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	charNumbers = "0123456789"
	charSymbols = "!@#$%^&*()_+-=[]{}|'"
)

// generateIAMPassword generates a random password of a given length, matching the
// most restrictive iam password policy.
func generateIAMPassword(length int) string {
	const charset = charLower + charUpper + charNumbers + charSymbols

	result := make([]byte, length)
	charsetSize := big.NewInt(int64(len(charset)))

	// rather than trying to artificially add specific characters from each
	// class to the password to match the policy, we generate passwords
	// randomly and reject those that don't match.
	//
	// Even in the worst case, this tends to take less than 10 tries to find a
	// matching password. Any sufficiently long password is likely to succeed
	// on the first try
	for n := 0; n < 100000; n++ {
		for i := range result {
			r, err := rand.Int(rand.Reader, charsetSize)
			if err != nil {
				panic(err)
			}
			if !r.IsInt64() {
				panic("rand.Int() not representable as an Int64")
			}

			result[i] = charset[r.Int64()]
		}

		if !checkIAMPwdPolicy(result) {
			continue
		}

		return string(result)
	}

	panic("failed to generate acceptable password")
}

// Check the generated password contains all character classes listed in the
// IAM password policy.
func checkIAMPwdPolicy(pass []byte) bool {
	return (bytes.ContainsAny(pass, charLower) &&
		bytes.ContainsAny(pass, charNumbers) &&
		bytes.ContainsAny(pass, charSymbols) &&
		bytes.ContainsAny(pass, charUpper))
}

func resourceAwsIamUserLoginProfileCreate(d *schema.ResourceData, meta interface{}) error {
	iamconn := meta.(*AWSClient).iamconn

	encryptionKey, err := encryption.RetrieveGPGKey(strings.TrimSpace(d.Get("pgp_key").(string)))
	if err != nil {
		return err
	}

	username := d.Get("user").(string)
	passwordResetRequired := d.Get("password_reset_required").(bool)
	passwordLength := d.Get("password_length").(int)

	// DEPRECATED: Automatic import will be removed in a future major version update
	// https://github.com/terraform-providers/terraform-provider-aws/issues/7536
	_, err = iamconn.GetLoginProfile(&iam.GetLoginProfileInput{
		UserName: aws.String(username),
	})

	// If there is already a login profile, bring it under management (to prevent
	// resource creation diffs) - we will never modify it, but obviously cannot
	// set the password.
	if err == nil {
		d.SetId(username)
		d.Set("key_fingerprint", "")
		d.Set("encrypted_password", "")
		return nil
	}

	if !isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") {
		return fmt.Errorf("Error checking for existing IAM User Login Profile: %s", err)
	}

	initialPassword := generateIAMPassword(passwordLength)

	fingerprint, encrypted, err := encryption.EncryptValue(encryptionKey, initialPassword, "Password")
	if err != nil {
		return err
	}

	request := &iam.CreateLoginProfileInput{
		UserName:              aws.String(username),
		Password:              aws.String(initialPassword),
		PasswordResetRequired: aws.Bool(passwordResetRequired),
	}

	log.Println("[DEBUG] Create IAM User Login Profile request:", request)
	createResp, err := iamconn.CreateLoginProfile(request)
	if err != nil {
		if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "EntityAlreadyExists" {
			// If there is already a login profile, bring it under management (to prevent
			// resource creation diffs) - we will never modify it, but obviously cannot
			// set the password.
			d.SetId(username)
			d.Set("key_fingerprint", "")
			d.Set("encrypted_password", "")
			return nil
		}
		return fmt.Errorf("Error creating IAM User Login Profile for %q: %s", username, err)
	}

	d.SetId(*createResp.LoginProfile.UserName)
	d.Set("key_fingerprint", fingerprint)
	d.Set("encrypted_password", encrypted)
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"errors"
	wyc "wysteria/wysteria_common"
)

const (
	err_cannot_orphan = "Unable to delete obj while undeleted children exist"
	err_id_required   = "Unable to delete: Obj id not supplied"
)

func (s *WysteriaServer) handleDelCollection(data []byte) ([]byte, error) {
	i := wyc.Collection{}
	err := json.Unmarshal(data, &i)
	if err != nil {
		return nil, err
	}
	if i.Id == "" {
		return nil, errors.New(err_id_required)
	}

	res, err := s.searchbase.QueryItem("", true, 0, wyc.QueryDesc{Parent: i.Id})
	if err != nil {
		return nil, err
	}
	if len(res) > 0 {
		return nil, errors.New(err_cannot_orphan)
	}

	err = s.database.DeleteCollection(i.Id)
	if err != nil {
		return nil, err
	}

	return wyc.WYSTERIA_SERVER_ACK, nil
}

func (s *WysteriaServer) handleDelItem(data []byte) ([]byte, error) {
	i := wyc.Item{}
	err := json.Unmarshal(data, &i)
	if err != nil {
		return nil, err
	}
	if i.Id == "" {
		return nil, errors.New(err_id_required)
	}

	res, err := s.searchbase.QueryVersion("", true, 0, wyc.QueryDesc{Parent: i.Id})
	if len(res) > 0 {
		return nil, errors.New(err_cannot_orphan)
	}

	if i.Links != nil && len(i.Links) > 0 {
		err = s.database.DeleteLink(i.Links...)
		if err != nil {
			return nil, err
		}
		s.searchbase.DeleteLink(i.Links...)
	}

	err = s.database.DeleteItem(i.Id)
	if err != nil {
		return nil, err
	}
	s.searchbase.DeleteItem(i.Id)

	return wyc.WYSTERIA_SERVER_ACK, nil
}

func (s *WysteriaServer) handleDelVersion(data []byte) ([]byte, error) {
	i := wyc.Version{}
	err := json.Unmarshal(data, &i)
	if err != nil {
		return nil, err
	}
	if i.Id == "" {
		return nil, errors.New(err_id_required)
	}

	res, err := s.searchbase.QueryFileResource("", true, 0, wyc.QueryDesc{Parent: i.Id})
	if err != nil {
		return nil, err
	}
	if len(res) > 0 {
		return nil, errors.New(err_cannot_orphan)
	}

	if i.Links != nil && len(i.Links) > 0 {
		err = s.database.DeleteLink(i.Links...)
		if err != nil {
			return nil, err
		}
		s.searchbase.DeleteLink(i.Links...)
	}

	err = s.database.DeleteVersion(i.Id)
	if err != nil {
		return nil, err
	}
	err = s.searchbase.DeleteVersion(i.Id)
	if err != nil {
		return nil, err
	}

	return wyc.WYSTERIA_SERVER_ACK, nil
}

func (s *WysteriaServer) handleDelFileResource(data []byte) ([]byte, error) {
	i := wyc.FileResource{}
	err := json.Unmarshal(data, &i)
	if err != nil {
		return nil, err
	}
	if i.Id == "" {
		return nil, errors.New(err_id_required)
	}

	err = s.database.DeleteCollection(i.Id)
	if err != nil {
		return nil, err
	}
	s.searchbase.DeleteFileResource(i.Id)

	return wyc.WYSTERIA_SERVER_ACK, nil
}
<commit_msg>Add err checking for searchbase.delete calls<commit_after>package main

import (
	"encoding/json"
	"errors"
	wyc "wysteria/wysteria_common"
)

const (
	err_cannot_orphan = "Unable to delete obj while undeleted children exist"
	err_id_required   = "Unable to delete: Obj id not supplied"
)

func (s *WysteriaServer) handleDelCollection(data []byte) ([]byte, error) {
	i := wyc.Collection{}
	err := json.Unmarshal(data, &i)
	if err != nil {
		return nil, err
	}
	if i.Id == "" {
		return nil, errors.New(err_id_required)
	}

	res, err := s.searchbase.QueryItem("", true, 0, wyc.QueryDesc{Parent: i.Id})
	if err != nil {
		return nil, err
	}
	if len(res) > 0 {
		return nil, errors.New(err_cannot_orphan)
	}

	err = s.database.DeleteCollection(i.Id)
	if err != nil {
		return nil, err
	}

	return wyc.WYSTERIA_SERVER_ACK, nil
}

func (s *WysteriaServer) handleDelItem(data []byte) ([]byte, error) {
	i := wyc.Item{}
	err := json.Unmarshal(data, &i)
	if err != nil {
		return nil, err
	}
	if i.Id == "" {
		return nil, errors.New(err_id_required)
	}

	res, err := s.searchbase.QueryVersion("", true, 0, wyc.QueryDesc{Parent: i.Id})
	if len(res) > 0 {
		return nil, errors.New(err_cannot_orphan)
	}

	if i.Links != nil && len(i.Links) > 0 {
		err = s.database.DeleteLink(i.Links...)
		if err != nil {
			return nil, err
		}
		s.searchbase.DeleteLink(i.Links...)
	}

	err = s.database.DeleteItem(i.Id)
	if err != nil {
		return nil, err
	}
	err = s.searchbase.DeleteItem(i.Id)
	if err != nil {
		return nil, err
	}
	return wyc.WYSTERIA_SERVER_ACK, nil
}

func (s *WysteriaServer) handleDelVersion(data []byte) ([]byte, error) {
	i := wyc.Version{}
	err := json.Unmarshal(data, &i)
	if err != nil {
		return nil, err
	}
	if i.Id == "" {
		return nil, errors.New(err_id_required)
	}

	res, err := s.searchbase.QueryFileResource("", true, 0, wyc.QueryDesc{Parent: i.Id})
	if err != nil {
		return nil, err
	}
	if len(res) > 0 {
		return nil, errors.New(err_cannot_orphan)
	}

	if i.Links != nil && len(i.Links) > 0 {
		err = s.database.DeleteLink(i.Links...)
		if err != nil {
			return nil, err
		}
		s.searchbase.DeleteLink(i.Links...)
	}

	err = s.database.DeleteVersion(i.Id)
	if err != nil {
		return nil, err
	}
	err = s.searchbase.DeleteVersion(i.Id)
	if err != nil {
		return nil, err
	}

	return wyc.WYSTERIA_SERVER_ACK, nil
}

func (s *WysteriaServer) handleDelFileResource(data []byte) ([]byte, error) {
	i := wyc.FileResource{}
	err := json.Unmarshal(data, &i)
	if err != nil {
		return nil, err
	}
	if i.Id == "" {
		return nil, errors.New(err_id_required)
	}

	err = s.database.DeleteFileResource(i.Id)
	if err != nil {
		return nil, err
	}
	err = s.searchbase.DeleteFileResource(i.Id)
	if err != nil {
		return nil, err
	}

	return wyc.WYSTERIA_SERVER_ACK, nil
}
<|endoftext|>


<commit_before>package bufferbench

import (
	"bytes"
	"sync"
	"testing"
)

var chars []byte
func init() {
	s := "acdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	chars = make([]byte, len(s))
	for i, c := range s {
		chars[i] = byte(c)
	}
}

func BenchmarkWriteToBuffer(b *testing.B) {
	for i := 0; i < b.N; i++ {
		b := bytes.Buffer{}
		for j := 0; j < 100; j++ {
			b.Write(chars)
		}
	}
}

var pool = sync.Pool{}
func BenchmarkWriteToBufferWithPool(b *testing.B) {
	pool.New = func() interface{} {
		return &bytes.Buffer{}
	}
	for i := 0; i < b.N; i++ {
		b := pool.Get().(*bytes.Buffer)
		for j := 0; j < 100; j++ {
			b.Write(chars)
		}
		pool.Put(b)
	}
}
<commit_msg>make sure to reset the buffer<commit_after>package bufferbench

import (
	"bytes"
	"sync"
	"testing"
)

var chars []byte
func init() {
	s := "acdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	chars = make([]byte, len(s))
	for i, c := range s {
		chars[i] = byte(c)
	}
}

func BenchmarkWriteToBuffer(b *testing.B) {
	for i := 0; i < b.N; i++ {
		b := bytes.Buffer{}
		for j := 0; j < 100; j++ {
			b.Write(chars)
		}
	}
}

var pool = sync.Pool{}
func BenchmarkWriteToBufferWithPool(b *testing.B) {
	pool.New = func() interface{} {
		return &bytes.Buffer{}
	}
	for i := 0; i < b.N; i++ {
		b := pool.Get().(*bytes.Buffer)
		b.Reset()
		for j := 0; j < 100; j++ {
			b.Write(chars)
		}
		pool.Put(b)
	}
}
<|endoftext|>