<commit_before>package integration_test

import (
	"fmt"
	"os"
	"os/exec"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gexec"
	"github.com/pivotalservices/cf-mgmt/cloudcontroller"
	"github.com/pivotalservices/cf-mgmt/uaa"
)

const (
	systemDomain = "local.pcfdev.io"
	userId       = "admin"
	password     = "admin"
	clientSecret = "admin-client-secret"
	configDir    = "./fixture"
)

var _ = Describe("cf-mgmt cli", func() {
	Describe("running tests against pcfdev", func() {

		var (
			outPath   string
			err       error
			ccManager cloudcontroller.Manager
			cfToken   string
		)
		BeforeEach(func() {
			uaaManager := uaa.NewDefaultUAAManager(systemDomain, userId)
			cfToken, err = uaaManager.GetCFToken(password)
			Expect(err).ShouldNot(HaveOccurred())

			ccManager = cloudcontroller.NewManager(fmt.Sprintf("https://api.%s", systemDomain), cfToken)
			outPath, err = Build("github.com/pivotalservices/cf-mgmt")

			Ω(err).ShouldNot(HaveOccurred())
		})
		AfterEach(func() {
			os.RemoveAll("./config")
			ccManager.DeleteOrg("test1")
			ccManager.DeleteOrg("test2")
			CleanupBuildArtifacts()
		})
		It("should complete successfully", func() {
			var orgs []*cloudcontroller.Org
			var spaces []*cloudcontroller.Space
			orgs, err = ccManager.ListOrgs()
			Expect(err).ShouldNot(HaveOccurred())
			Expect(getOrg(orgs, "test1")).Should(BeNil())
			Expect(getOrg(orgs, "test2")).Should(BeNil())

			createOrgsCommand := exec.Command(outPath, "create-orgs", "--config-dir", configDir,
				"--system-domain", systemDomain, "--user-id", userId, "--password",
				password, "--client-secret", clientSecret)
			session, err := Start(createOrgsCommand, GinkgoWriter, GinkgoWriter)
			Expect(err).ShouldNot(HaveOccurred())
			Eventually(session).Should(Exit(0))

			orgs, err = ccManager.ListOrgs()
			Expect(err).ShouldNot(HaveOccurred())
			Expect(getOrg(orgs, "test1")).ShouldNot(BeNil())
			Expect(getOrg(orgs, "test2")).ShouldNot(BeNil())

			ccManager.CreateOrg("rogue-org1")
			ccManager.CreateOrg("rogue-org2")
			deleteOrgsCommand := exec.Command(outPath, "delete-orgs", "--config-dir", configDir,
				"--system-domain", systemDomain, "--user-id", userId, "--password",
				password, "--client-secret", clientSecret)
			session, err = Start(deleteOrgsCommand, GinkgoWriter, GinkgoWriter)
			Expect(err).ShouldNot(HaveOccurred())
			Eventually(session).Should(Exit(0))

			orgs, err = ccManager.ListOrgs()
			Expect(err).ShouldNot(HaveOccurred())
			Expect(getOrg(orgs, "system")).ShouldNot(BeNil())
			Expect(getOrg(orgs, "pcfdev-org")).ShouldNot(BeNil())
			Expect(getOrg(orgs, "rogue-org1")).Should(BeNil())
			Expect(getOrg(orgs, "rogue-org2")).Should(BeNil())

			createSpacesCommand := exec.Command(outPath, "create-spaces", "--config-dir", configDir,
				"--system-domain", systemDomain, "--user-id", userId, "--password",
				password, "--client-secret", clientSecret)
			session, err = Start(createSpacesCommand, GinkgoWriter, GinkgoWriter)
			Expect(err).ShouldNot(HaveOccurred())
			Eventually(session).Should(Exit(0))

			spaces, err = ccManager.ListSpaces(getOrg(orgs, "test1").MetaData.GUID)
			Expect(err).ShouldNot(HaveOccurred())
			Expect(getSpace(spaces, "dev")).ShouldNot(BeNil())
			Expect(getSpace(spaces, "prod")).ShouldNot(BeNil())

			spaces, err = ccManager.ListSpaces(getOrg(orgs, "test2").MetaData.GUID)
			Expect(err).ShouldNot(HaveOccurred())
			Expect(len(spaces)).Should(BeEquivalentTo(0))
		})

		It("should export config with > 50 spaces", func() {

			ccManager := cloudcontroller.NewManager(fmt.Sprintf("https://api.%s", systemDomain), cfToken)

			ccManager.CreateOrg("test1")
			orgs, _ := ccManager.ListOrgs()
			for _, org := range orgs {
				if org.Entity.Name == "test1" {
					i := 1
					for i < 101 {
						ccManager.CreateSpace(fmt.Sprintf("space-%d", i), org.MetaData.GUID)
						i++
					}
				}
			}

			exportConfigCommand := exec.Command(outPath, "export-config", "--config-dir", "./config",
				"--system-domain", systemDomain, "--user-id", userId, "--password",
				password, "--client-secret", clientSecret)
			session, err := Start(exportConfigCommand, GinkgoWriter, GinkgoWriter)
			session.Wait(20)
			Expect(err).ShouldNot(HaveOccurred())
			Eventually(session).Should(Exit(0))

		})

		It("should export config with > 50 quotas", func() {

			ccManager := cloudcontroller.NewManager(fmt.Sprintf("https://api.%s", systemDomain), cfToken)
			i := 1
			for i < 101 {
				ccManager.CreateQuota(fmt.Sprintf("quota-%d", i), 1, 1, 1, 1, true)
				i++
			}

			exportConfigCommand := exec.Command(outPath, "export-config", "--config-dir", "./config",
				"--system-domain", systemDomain, "--user-id", userId, "--password",
				password, "--client-secret", clientSecret)
			session, err := Start(exportConfigCommand, GinkgoWriter, GinkgoWriter)
			session.Wait(20)
			Expect(err).ShouldNot(HaveOccurred())
			Eventually(session).Should(Exit(0))

		})

	})
})

func getSpace(spaces []*cloudcontroller.Space, spaceName string) *cloudcontroller.Space {
	for _, space := range spaces {
		if space.Entity.Name == spaceName {
			return space
		}
	}
	return nil
}

func getOrg(orgs []*cloudcontroller.Org, orgName string) *cloudcontroller.Org {
	for _, org := range orgs {
		if org.Entity.Name == orgName {
			return org
		}
	}
	return nil
}
<commit_msg>adding intigration testing<commit_after>package integration_test

import (
	"fmt"
	"os"
	"os/exec"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gexec"
	"github.com/pivotalservices/cf-mgmt/cloudcontroller"
	"github.com/pivotalservices/cf-mgmt/uaa"
)

const (
	systemDomain = "local.pcfdev.io"
	userId       = "admin"
	password     = "admin"
	clientSecret = "admin-client-secret"
	configDir    = "./fixture"
)

var _ = Describe("cf-mgmt cli", func() {
	Describe("running tests against pcfdev", func() {

		var (
			outPath   string
			err       error
			ccManager cloudcontroller.Manager
			cfToken   string
		)
		BeforeEach(func() {
			uaaManager := uaa.NewDefaultUAAManager(systemDomain, userId)
			cfToken, err = uaaManager.GetCFToken(password)
			Expect(err).ShouldNot(HaveOccurred())

			ccManager = cloudcontroller.NewManager(fmt.Sprintf("https://api.%s", systemDomain), cfToken)
			outPath, err = Build("github.com/pivotalservices/cf-mgmt")

			ccManager.CreateOrg("rogue-org1")
			ccManager.CreateOrg("rogue-org2")

			Ω(err).ShouldNot(HaveOccurred())
		})
		AfterEach(func() {
			os.RemoveAll("./config")
			ccManager.DeleteOrg("test1")
			ccManager.DeleteOrg("test2")
			ccManager.DeleteOrg("rogue-org1")
			ccManager.DeleteOrg("rogue-org2")
			CleanupBuildArtifacts()
		})
		It("should complete successfully", func() {
			var orgs []*cloudcontroller.Org
			var spaces []*cloudcontroller.Space
			orgs, err = ccManager.ListOrgs()
			Expect(err).ShouldNot(HaveOccurred())
			Expect(getOrg(orgs, "test1")).Should(BeNil())
			Expect(getOrg(orgs, "test2")).Should(BeNil())

			createOrgsCommand := exec.Command(outPath, "create-orgs", "--config-dir", configDir,
				"--system-domain", systemDomain, "--user-id", userId, "--password",
				password, "--client-secret", clientSecret)
			session, err := Start(createOrgsCommand, GinkgoWriter, GinkgoWriter)
			Expect(err).ShouldNot(HaveOccurred())
			Eventually(session).Should(Exit(0))

			orgs, err = ccManager.ListOrgs()
			Expect(err).ShouldNot(HaveOccurred())
			Expect(getOrg(orgs, "test1")).ShouldNot(BeNil())
			Expect(getOrg(orgs, "test2")).ShouldNot(BeNil())

			deleteOrgsCommand := exec.Command(outPath, "delete-orgs", "--config-dir", configDir,
				"--system-domain", systemDomain, "--user-id", userId, "--password",
				password, "--client-secret", clientSecret)
			session, err = Start(deleteOrgsCommand, GinkgoWriter, GinkgoWriter)
			Expect(err).ShouldNot(HaveOccurred())
			Eventually(session).Should(Exit(0))

			orgs, err = ccManager.ListOrgs()
			Expect(err).ShouldNot(HaveOccurred())
			Expect(getOrg(orgs, "system")).ShouldNot(BeNil())
			Expect(getOrg(orgs, "pcfdev-org")).ShouldNot(BeNil())
			Expect(getOrg(orgs, "rogue-org1")).Should(BeNil())
			Expect(getOrg(orgs, "rogue-org2")).Should(BeNil())

			ccManager.CreateOrg("rogue-org1")
			ccManager.CreateOrg("rogue-org2")
			peekDeleteOrgsCommand := exec.Command(outPath, "delete-orgs", "--peek", "--config-dir", configDir,
				"--system-domain", systemDomain, "--user-id", userId, "--password",
				password, "--client-secret", clientSecret)
			session, err = Start(peekDeleteOrgsCommand, GinkgoWriter, GinkgoWriter)
			Expect(err).ShouldNot(HaveOccurred())
			Eventually(session).Should(Exit(0))

			orgs, err = ccManager.ListOrgs()
			Expect(err).ShouldNot(HaveOccurred())
			Expect(getOrg(orgs, "system")).ShouldNot(BeNil())
			Expect(getOrg(orgs, "pcfdev-org")).ShouldNot(BeNil())
			Expect(getOrg(orgs, "rogue-org1")).ShouldNot(BeNil())
			Expect(getOrg(orgs, "rogue-org2")).ShouldNot(BeNil())

			createSpacesCommand := exec.Command(outPath, "create-spaces", "--config-dir", configDir,
				"--system-domain", systemDomain, "--user-id", userId, "--password",
				password, "--client-secret", clientSecret)
			session, err = Start(createSpacesCommand, GinkgoWriter, GinkgoWriter)
			Expect(err).ShouldNot(HaveOccurred())
			Eventually(session).Should(Exit(0))

			spaces, err = ccManager.ListSpaces(getOrg(orgs, "test1").MetaData.GUID)
			Expect(err).ShouldNot(HaveOccurred())
			Expect(getSpace(spaces, "dev")).ShouldNot(BeNil())
			Expect(getSpace(spaces, "prod")).ShouldNot(BeNil())

			spaces, err = ccManager.ListSpaces(getOrg(orgs, "test2").MetaData.GUID)
			Expect(err).ShouldNot(HaveOccurred())
			Expect(len(spaces)).Should(BeEquivalentTo(0))
		})

		It("should export config with > 50 spaces", func() {

			ccManager := cloudcontroller.NewManager(fmt.Sprintf("https://api.%s", systemDomain), cfToken)

			ccManager.CreateOrg("test1")
			orgs, _ := ccManager.ListOrgs()
			for _, org := range orgs {
				if org.Entity.Name == "test1" {
					i := 1
					for i < 101 {
						ccManager.CreateSpace(fmt.Sprintf("space-%d", i), org.MetaData.GUID)
						i++
					}
				}
			}

			exportConfigCommand := exec.Command(outPath, "export-config", "--config-dir", "./config",
				"--system-domain", systemDomain, "--user-id", userId, "--password",
				password, "--client-secret", clientSecret)
			session, err := Start(exportConfigCommand, GinkgoWriter, GinkgoWriter)
			session.Wait(20)
			Expect(err).ShouldNot(HaveOccurred())
			Eventually(session).Should(Exit(0))

		})

		It("should export config with > 50 quotas", func() {

			ccManager := cloudcontroller.NewManager(fmt.Sprintf("https://api.%s", systemDomain), cfToken)
			i := 1
			for i < 101 {
				ccManager.CreateQuota(fmt.Sprintf("quota-%d", i), 1, 1, 1, 1, true)
				i++
			}

			exportConfigCommand := exec.Command(outPath, "export-config", "--config-dir", "./config",
				"--system-domain", systemDomain, "--user-id", userId, "--password",
				password, "--client-secret", clientSecret)
			session, err := Start(exportConfigCommand, GinkgoWriter, GinkgoWriter)
			session.Wait(20)
			Expect(err).ShouldNot(HaveOccurred())
			Eventually(session).Should(Exit(0))

		})

	})
})

func getSpace(spaces []*cloudcontroller.Space, spaceName string) *cloudcontroller.Space {
	for _, space := range spaces {
		if space.Entity.Name == spaceName {
			return space
		}
	}
	return nil
}

func getOrg(orgs []*cloudcontroller.Org, orgName string) *cloudcontroller.Org {
	for _, org := range orgs {
		if org.Entity.Name == orgName {
			return org
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"code.google.com/p/log4go"
	"fmt"
	"github.com/quarnster/parser"
	"io/ioutil"
	"lime/3rdparty/libs/termbox-go"
	"lime/backend"
	"lime/backend/loaders"
	"lime/backend/primitives"
	"lime/backend/textmate"
	"sort"
	"strings"
)

var (
	lut = map[termbox.Key]backend.KeyPress{
		termbox.KeyCtrlA: backend.KeyPress{Ctrl: true, Key: 'a'},
		termbox.KeyCtrlB: backend.KeyPress{Ctrl: true, Key: 'b'},
		termbox.KeyCtrlC: backend.KeyPress{Ctrl: true, Key: 'c'},
		termbox.KeyCtrlD: backend.KeyPress{Ctrl: true, Key: 'd'},
		termbox.KeyCtrlE: backend.KeyPress{Ctrl: true, Key: 'e'},
		termbox.KeyCtrlF: backend.KeyPress{Ctrl: true, Key: 'f'},
		termbox.KeyCtrlG: backend.KeyPress{Ctrl: true, Key: 'g'},
		termbox.KeyCtrlH: backend.KeyPress{Ctrl: true, Key: 'h'},
		termbox.KeyCtrlI: backend.KeyPress{Ctrl: true, Key: 'i'},
		termbox.KeyCtrlJ: backend.KeyPress{Ctrl: true, Key: 'j'},
		termbox.KeyCtrlK: backend.KeyPress{Ctrl: true, Key: 'k'},
		termbox.KeyCtrlL: backend.KeyPress{Ctrl: true, Key: 'l'},
		termbox.KeyCtrlM: backend.KeyPress{Ctrl: true, Key: 'm'},
		termbox.KeyCtrlN: backend.KeyPress{Ctrl: true, Key: 'n'},
		termbox.KeyCtrlO: backend.KeyPress{Ctrl: true, Key: 'o'},
		termbox.KeyCtrlP: backend.KeyPress{Ctrl: true, Key: 'p'},
		termbox.KeyCtrlQ: backend.KeyPress{Ctrl: true, Key: 'q'},
		termbox.KeyCtrlR: backend.KeyPress{Ctrl: true, Key: 'r'},
		termbox.KeyCtrlS: backend.KeyPress{Ctrl: true, Key: 's'},
		termbox.KeyCtrlT: backend.KeyPress{Ctrl: true, Key: 't'},
		termbox.KeyCtrlU: backend.KeyPress{Ctrl: true, Key: 'u'},
		termbox.KeyCtrlV: backend.KeyPress{Ctrl: true, Key: 'v'},
		termbox.KeyCtrlW: backend.KeyPress{Ctrl: true, Key: 'w'},
		termbox.KeyCtrlX: backend.KeyPress{Ctrl: true, Key: 'x'},
		termbox.KeyCtrlY: backend.KeyPress{Ctrl: true, Key: 'y'},
		termbox.KeyCtrlZ: backend.KeyPress{Ctrl: true, Key: 'z'},
		termbox.KeyCtrl2: backend.KeyPress{Ctrl: true, Key: '2'},
		termbox.KeyCtrl3: backend.KeyPress{Ctrl: true, Key: '3'},
		termbox.KeyCtrl4: backend.KeyPress{Ctrl: true, Key: '4'},
		termbox.KeyCtrl5: backend.KeyPress{Ctrl: true, Key: '5'},
		termbox.KeyCtrl6: backend.KeyPress{Ctrl: true, Key: '6'},
		termbox.KeyCtrl7: backend.KeyPress{Ctrl: true, Key: '7'},
		termbox.KeyCtrl8: backend.KeyPress{Ctrl: true, Key: '8'},
	}
	schemelut = make(map[string][2]termbox.Attribute)
	defaultBg = termbox.ColorBlack
	defaultFg = termbox.ColorWhite
)

func findScope(search parser.Range, node *parser.Node, in string) string {
	idx := sort.Search(len(node.Children), func(i int) bool {
		return node.Children[i].Range.Start >= search.End || node.Children[i].Range.Contains(search)
	})
	if idx != len(node.Children) {
		in += " " + node.Name
		return findScope(search, node.Children[idx], in)
	} else if node.Range.Contains(search) {
		return in + " " + node.Name
	} else {
		return in
	}
}

func renderView(sx, sy, w, h int, v *backend.View, root *parser.Node) {
	substr := v.Substr(primitives.Region{0, v.Size()})
	lines := strings.Split(substr, "\n")
	s, e := 0, len(lines)
	if e > 1 {
		e = e - 1
		if e > h {
			s = e - h
		}
	}
	off := len(strings.Join(lines[:s], "\n"))
	lines = lines[s:e]
	runes := []rune(strings.Join(lines, "\n"))
	x, y := sx, sy
	ex, ey := sx+w, sy+h

	sub2 := ""
	var (
		lastScope string
		lfg, lbg  termbox.Attribute
	)

	for i := range runes {
		sub2 += string(runes[i])
		if runes[i] == '\n' {
			x = sx
			y++
			if y > ey {
				break
			}
			continue
		}

		if x < ex {
			fg, bg := defaultFg, defaultBg
			o := off + len(sub2)
			scope := findScope(parser.Range{o, o + 1}, root, "")
			if scope != lastScope {
				lastScope = scope
				na := scope
				for len(na) > 0 {
					sn := na
					i := strings.LastIndex(sn, " ")
					if i != -1 {
						sn = sn[i+1:]
					}
					if c, ok := schemelut[sn]; ok {
						fg, bg = c[0], c[1]
						break
					}
					if i2 := strings.LastIndex(na, "."); i2 == -1 {
						break
					} else if i > i2 {
						na = na[:i]
					} else {
						na = strings.TrimSpace(na[:i2])
					}
				}
				lfg, lbg = fg, bg
			} else {
				fg, bg = lfg, lbg
			}
			termbox.SetCell(x, y, runes[i], fg, bg)
		}
		x++
	}
}

func main() {
	if err := termbox.Init(); err != nil {
		log4go.Exit(err)
	}

	ed := backend.GetEditor()
	ed.LogInput(true)
	ed.LogCommands(true)
	c := ed.Console()
	var (
		scheme textmate.Theme
		syntax textmate.Language
		lp     = textmate.LanguageParser{Language: &syntax}
	)
	if d, err := ioutil.ReadFile("../../3rdparty/bundles/monokai.tmbundle/Themes/Monokai.tmTheme"); err != nil {
		log4go.Error("Unable to load colorscheme definition: %s", err)
	} else if err := loaders.LoadPlist(d, &scheme); err != nil {
		log4go.Error("Unable to load colorscheme definition: %s", err)
	}

	if d, err := ioutil.ReadFile("../../3rdparty/bundles/go.tmbundle/Syntaxes/Go.tmLanguage"); err != nil {
		log4go.Error("Unable to load syntax definition: %s", err)
	} else if err := loaders.LoadPlist(d, &syntax); err != nil {
		log4go.Error("Unable to load syntax definition: %s", err)
	}

	if err := termbox.SetColorMode(termbox.ColorMode256); err != nil {
		log4go.Error("Unable to use 256 color mode: %s", err)
	} else {
		log4go.Debug("Using 256 color mode")
		pal := make([]termbox.RGB, 0, 256)

		palLut := func(col textmate.Color) termbox.Attribute {
			tc := termbox.RGB{col.R, col.G, col.B}
			for i, c := range pal {
				if c == tc {
					return termbox.Attribute(i)
				}
			}
			l := len(pal)
			pal = append(pal, tc)
			return termbox.Attribute(l)
		}
		for i, s := range scheme.Settings {
			var (
				fi = defaultFg
				bi = defaultBg
			)
			if fg, ok := s.Settings["foreground"]; ok {
				fi = palLut(fg)
				if i == 0 {
					defaultFg = fi
				}
			}
			if bg, ok := s.Settings["background"]; ok {
				bi = palLut(bg)
				if i == 0 {
					defaultBg = bi
				}
			}
			schemelut[s.Scope] = [2]termbox.Attribute{fi, bi}
		}
		termbox.SetColorPalette(pal)
	}
	defer func() {
		termbox.Close()
		fmt.Println(c.Substr(primitives.Region{0, c.Size()}))
	}()

	w := ed.NewWindow()
	v := w.OpenFile("main.go", 0)
	lp.Parse(v.Buffer().Data())

	for {
		termbox.Clear(defaultFg, defaultBg)
		w, h := termbox.Size()

		renderView(0, 0, w, h-3, v, lp.RootNode())
		renderView(0, h-3, w, 3, c, &parser.Node{Name: "", Range: parser.Range{0, c.Buffer().Size()}})

		termbox.Flush()
		ev := termbox.PollEvent()
		switch ev.Type {
		case termbox.EventKey:
			var kp backend.KeyPress
			if ev.Ch != 0 {
				kp.Key = backend.Key(ev.Ch)
			} else if v, ok := lut[ev.Key]; ok {
				kp = v
			}
			if ev.Key == termbox.KeyEsc {
				return
			}
			ed.HandleInput(kp)
		}
	}
}
<commit_msg>Use GlitterBomb color scheme and GoSublime syntax + scope fix. Starting to look almost exactly like my ST3 setup<commit_after>package main

import (
	"code.google.com/p/log4go"
	"fmt"
	"github.com/quarnster/parser"
	"io/ioutil"
	"lime/3rdparty/libs/termbox-go"
	"lime/backend"
	"lime/backend/loaders"
	"lime/backend/primitives"
	"lime/backend/textmate"
	"sort"
	"strings"
)

var (
	lut = map[termbox.Key]backend.KeyPress{
		termbox.KeyCtrlA: backend.KeyPress{Ctrl: true, Key: 'a'},
		termbox.KeyCtrlB: backend.KeyPress{Ctrl: true, Key: 'b'},
		termbox.KeyCtrlC: backend.KeyPress{Ctrl: true, Key: 'c'},
		termbox.KeyCtrlD: backend.KeyPress{Ctrl: true, Key: 'd'},
		termbox.KeyCtrlE: backend.KeyPress{Ctrl: true, Key: 'e'},
		termbox.KeyCtrlF: backend.KeyPress{Ctrl: true, Key: 'f'},
		termbox.KeyCtrlG: backend.KeyPress{Ctrl: true, Key: 'g'},
		termbox.KeyCtrlH: backend.KeyPress{Ctrl: true, Key: 'h'},
		termbox.KeyCtrlI: backend.KeyPress{Ctrl: true, Key: 'i'},
		termbox.KeyCtrlJ: backend.KeyPress{Ctrl: true, Key: 'j'},
		termbox.KeyCtrlK: backend.KeyPress{Ctrl: true, Key: 'k'},
		termbox.KeyCtrlL: backend.KeyPress{Ctrl: true, Key: 'l'},
		termbox.KeyCtrlM: backend.KeyPress{Ctrl: true, Key: 'm'},
		termbox.KeyCtrlN: backend.KeyPress{Ctrl: true, Key: 'n'},
		termbox.KeyCtrlO: backend.KeyPress{Ctrl: true, Key: 'o'},
		termbox.KeyCtrlP: backend.KeyPress{Ctrl: true, Key: 'p'},
		termbox.KeyCtrlQ: backend.KeyPress{Ctrl: true, Key: 'q'},
		termbox.KeyCtrlR: backend.KeyPress{Ctrl: true, Key: 'r'},
		termbox.KeyCtrlS: backend.KeyPress{Ctrl: true, Key: 's'},
		termbox.KeyCtrlT: backend.KeyPress{Ctrl: true, Key: 't'},
		termbox.KeyCtrlU: backend.KeyPress{Ctrl: true, Key: 'u'},
		termbox.KeyCtrlV: backend.KeyPress{Ctrl: true, Key: 'v'},
		termbox.KeyCtrlW: backend.KeyPress{Ctrl: true, Key: 'w'},
		termbox.KeyCtrlX: backend.KeyPress{Ctrl: true, Key: 'x'},
		termbox.KeyCtrlY: backend.KeyPress{Ctrl: true, Key: 'y'},
		termbox.KeyCtrlZ: backend.KeyPress{Ctrl: true, Key: 'z'},
		termbox.KeyCtrl2: backend.KeyPress{Ctrl: true, Key: '2'},
		termbox.KeyCtrl3: backend.KeyPress{Ctrl: true, Key: '3'},
		termbox.KeyCtrl4: backend.KeyPress{Ctrl: true, Key: '4'},
		termbox.KeyCtrl5: backend.KeyPress{Ctrl: true, Key: '5'},
		termbox.KeyCtrl6: backend.KeyPress{Ctrl: true, Key: '6'},
		termbox.KeyCtrl7: backend.KeyPress{Ctrl: true, Key: '7'},
		termbox.KeyCtrl8: backend.KeyPress{Ctrl: true, Key: '8'},
	}
	schemelut = make(map[string][2]termbox.Attribute)
	defaultBg = termbox.ColorBlack
	defaultFg = termbox.ColorWhite
)

func findScope(search parser.Range, node *parser.Node, in string) string {
	idx := sort.Search(len(node.Children), func(i int) bool {
		return node.Children[i].Range.Start >= search.Start || node.Children[i].Range.Contains(search)
	})
	for idx < len(node.Children) {
		c := node.Children[idx]
		if c.Range.Start > search.End {
			break
		}
		if c.Range.Contains(search) {
			in += " " + node.Name
			return findScope(search, node.Children[idx], in)
		}
		idx++
	}
	if node.Range.Contains(search) {
		return in + " " + node.Name
	}
	return in
}

func renderView(sx, sy, w, h int, v *backend.View, root *parser.Node) {
	substr := v.Substr(primitives.Region{0, v.Size()})
	lines := strings.Split(substr, "\n")
	s, e := 0, len(lines)
	if e > 1 {
		e = e - 1
		if e > h {
			s = e - h
		}
	}
	off := len(strings.Join(lines[:s], "\n"))
	lines = lines[s:e]
	runes := []rune(strings.Join(lines, "\n"))
	x, y := sx, sy
	ex, ey := sx+w, sy+h

	sub2 := ""
	var (
		lastScope string
		lfg, lbg  termbox.Attribute
	)

	for i := range runes {
		sub2 += string(runes[i])
		if runes[i] == '\n' {
			x = sx
			y++
			if y > ey {
				break
			}
			continue
		}

		if x < ex {
			fg, bg := defaultFg, defaultBg
			o := off + len(sub2)
			scope := findScope(parser.Range{o, o + 1}, root, "")
			if scope != lastScope {
				lastScope = scope
				na := scope
				for len(na) > 0 {
					sn := na
					i := strings.LastIndex(sn, " ")
					if i != -1 {
						sn = sn[i+1:]
					}
					if c, ok := schemelut[sn]; ok {
						fg, bg = c[0], c[1]
						break
					}
					if i2 := strings.LastIndex(na, "."); i2 == -1 {
						break
					} else if i > i2 {
						na = na[:i]
					} else {
						na = strings.TrimSpace(na[:i2])
					}
				}
				lfg, lbg = fg, bg
			} else {
				fg, bg = lfg, lbg
			}
			termbox.SetCell(x, y, runes[i], fg, bg)
		}
		x++
	}
}

func main() {
	if err := termbox.Init(); err != nil {
		log4go.Exit(err)
	}

	ed := backend.GetEditor()
	ed.LogInput(true)
	ed.LogCommands(true)
	c := ed.Console()
	var (
		scheme textmate.Theme
		syntax textmate.Language
		lp     = textmate.LanguageParser{Language: &syntax}
	)
	if d, err := ioutil.ReadFile("../../3rdparty/bundles/TextMate-Themes/GlitterBomb.tmTheme"); err != nil {
		log4go.Error("Unable to load colorscheme definition: %s", err)
	} else if err := loaders.LoadPlist(d, &scheme); err != nil {
		log4go.Error("Unable to load colorscheme definition: %s", err)
	}

	if d, err := ioutil.ReadFile("../../3rdparty/bundles/GoSublime/GoSublime.tmLanguage"); err != nil {
		log4go.Error("Unable to load syntax definition: %s", err)
	} else if err := loaders.LoadPlist(d, &syntax); err != nil {
		log4go.Error("Unable to load syntax definition: %s", err)
	}

	if err := termbox.SetColorMode(termbox.ColorMode256); err != nil {
		log4go.Error("Unable to use 256 color mode: %s", err)
	} else {
		log4go.Debug("Using 256 color mode")
		pal := make([]termbox.RGB, 0, 256)

		palLut := func(col textmate.Color) termbox.Attribute {
			tc := termbox.RGB{col.R, col.G, col.B}
			for i, c := range pal {
				if c == tc {
					return termbox.Attribute(i)
				}
			}
			l := len(pal)
			pal = append(pal, tc)
			return termbox.Attribute(l)
		}
		for i, s := range scheme.Settings {
			var (
				fi = defaultFg
				bi = defaultBg
			)
			if fg, ok := s.Settings["foreground"]; ok {
				fi = palLut(fg)
				if i == 0 {
					defaultFg = fi
				}
			}
			if bg, ok := s.Settings["background"]; ok {
				bi = palLut(bg)
				if i == 0 {
					defaultBg = bi
				}
			}
			schemelut[s.Scope] = [2]termbox.Attribute{fi, bi}
		}
		termbox.SetColorPalette(pal)
	}
	defer func() {
		termbox.Close()
		fmt.Println(c.Substr(primitives.Region{0, c.Size()}))
	}()

	w := ed.NewWindow()
	v := w.OpenFile("main.go", 0)
	lp.Parse(v.Buffer().Data())

	for {
		termbox.Clear(defaultFg, defaultBg)
		w, h := termbox.Size()

		renderView(0, 0, w, h-3, v, lp.RootNode())
		renderView(0, h-3, w, 3, c, &parser.Node{Name: "", Range: parser.Range{0, c.Buffer().Size()}})

		termbox.Flush()
		ev := termbox.PollEvent()
		switch ev.Type {
		case termbox.EventKey:
			var kp backend.KeyPress
			if ev.Ch != 0 {
				kp.Key = backend.Key(ev.Ch)
			} else if v, ok := lut[ev.Key]; ok {
				kp = v
			}
			if ev.Key == termbox.KeyEsc {
				return
			}
			ed.HandleInput(kp)
		}
	}
}
<|endoftext|>


<commit_before>package pool_test

import (
	"sync"
	"testing"

	"github.com/npat-efault/tst/pool"
)

type S struct {
	id  int
	buf [64]byte
}

func TestPoolNil(t *testing.T) {
	p := pool.New(10, nil)
	for i := 0; i < 12; i++ {
		p.Put(&S{id: i})
	}
	for i := 0; i < 10; i++ {
		if s := p.Get(); s == nil {
			t.Fatalf("Elem %d is nil", i)
		} else {
			ss := s.(*S)
			if ss.id != i {
				t.Fatalf("Elem id %d != %d", ss.id, i)
			}
		}
	}
	if s := p.Get(); s != nil {
		t.Fatal("Too many items in pool")
	}
}

func TestPoolAlloc(t *testing.T) {
	p := pool.New(10, func() interface{} { return &S{} })
	for i := 0; i < 12; i++ {
		p.Put(&S{id: i})
	}
	for i := 0; i < 10; i++ {
		if s := p.Get(); s == nil {
			t.Fatalf("Elem %d is nil", i)
		} else {
			ss := s.(*S)
			if ss.id != i {
				t.Fatalf("Elem id %d != %d", ss.id, i)
			}
		}
	}
	if s := p.Get(); s == nil {
		t.Fatal("No new allocation")
	} else if ss := s.(*S); ss.id != 0 {
		t.Fatal("Unitialized new allocation")
	}
}

func TestPoolEmpty(t *testing.T) {
	p := pool.New(10, nil)
	for i := 0; i < 12; i++ {
		p.Put(&S{id: i})
	}
	p.Empty()
	if s := p.Get(); s != nil {
		t.Fatal("Pool not empty")
	}
}

func TestBSPoolNil(t *testing.T) {
	p := pool.NewByteSlice(10, nil)
	for i := 0; i < 12; i++ {
		b := make([]byte, 64)
		b[63] = byte(i)
		p.Put(b)
	}
	for i := 0; i < 10; i++ {
		if b := p.Get(); b == nil {
			t.Fatalf("Elem %d is nil", i)
		} else if b[63] != byte(i) {
			t.Fatalf("Elem %d[0] != %d", b[63], i)
		}
	}
	if b := p.Get(); b != nil {
		t.Fatal("Too many items in pool")
	}
}

func TestBSPoolAlloc(t *testing.T) {
	p := pool.NewByteSlice(10, func() []byte { return make([]byte, 64) })
	for i := 0; i < 12; i++ {
		b := make([]byte, 64)
		b[63] = byte(i)
		p.Put(b)
	}
	for i := 0; i < 10; i++ {
		if b := p.Get(); b == nil {
			t.Fatalf("Elem %d is nil", i)
		} else if b[63] != byte(i) {
			t.Fatalf("Elem %d[0] != %d", b[63], i)
		}
	}
	if b := p.Get(); b == nil {
		t.Fatal("No new allocation")
	} else if b[63] != 0 {
		t.Fatal("Unitialized new allocation")
	}
}

func TestBSPoolEmpty(t *testing.T) {
	p := pool.NewByteSlice(10, nil)
	for i := 0; i < 12; i++ {
		b := make([]byte, 64)
		b[63] = byte(i)
		p.Put(b)
	}
	p.Empty()
	if b := p.Get(); b != nil {
		t.Fatal("Pool not empty")
	}
}

// See allocations due to conversions from []byte to
// interface{}. Avoided by specialized ByteSlice pool.
//
// run with:
//      go test -v -memprofile=mem-bsp.out -bench='ByteSlicePool$'
//   or go test -v -memprofile=mem-p.out -bench='Pool$'
//   or go test -v -memprofile=mem-sp.out -bench='SyncPool$'
//
// see results with
//
//      go tool pprof --alloc_objects ./pool.test mem-xxx.out -text
//      ... etc ...

func BenchmarkAllocByteSlicePool(b *testing.B) {
	s := make([]byte, 10)
	p := pool.NewByteSlice(1, nil)
	for i := 0; i < b.N; i++ {
		p.Put(s)
		s = p.Get()
	}
}

func BenchmarkAllocPool(b *testing.B) {
	s := make([]byte, 10)
	p := pool.New(1, nil)
	for i := 0; i < b.N; i++ {
		p.Put(s)
		s = p.Get().([]byte)
	}
}

func BenchmarkAllocSyncPool(b *testing.B) {
	var p sync.Pool
	s := make([]byte, 10)
	for i := 0; i < b.N; i++ {
		p.Put(s)
		s = p.Get().([]byte)
	}
}
<commit_msg>Strings (message) fix<commit_after>package pool_test

import (
	"sync"
	"testing"

	"github.com/npat-efault/tst/pool"
)

type S struct {
	id  int
	buf [64]byte
}

func TestPoolNil(t *testing.T) {
	p := pool.New(10, nil)
	for i := 0; i < 12; i++ {
		p.Put(&S{id: i})
	}
	for i := 0; i < 10; i++ {
		if s := p.Get(); s == nil {
			t.Fatalf("Item %d is nil", i)
		} else {
			ss := s.(*S)
			if ss.id != i {
				t.Fatalf("Item id %d != %d", ss.id, i)
			}
		}
	}
	if s := p.Get(); s != nil {
		t.Fatal("Too many items in pool")
	}
}

func TestPoolAlloc(t *testing.T) {
	p := pool.New(10, func() interface{} { return &S{} })
	for i := 0; i < 12; i++ {
		p.Put(&S{id: i})
	}
	for i := 0; i < 10; i++ {
		if s := p.Get(); s == nil {
			t.Fatalf("Item %d is nil", i)
		} else {
			ss := s.(*S)
			if ss.id != i {
				t.Fatalf("Item id %d != %d", ss.id, i)
			}
		}
	}
	if s := p.Get(); s == nil {
		t.Fatal("No new allocation")
	} else if ss := s.(*S); ss.id != 0 {
		t.Fatal("Unitialized new allocation")
	}
}

func TestPoolEmpty(t *testing.T) {
	p := pool.New(10, nil)
	for i := 0; i < 12; i++ {
		p.Put(&S{id: i})
	}
	p.Empty()
	if s := p.Get(); s != nil {
		t.Fatal("Pool not empty")
	}
}

func TestBSPoolNil(t *testing.T) {
	p := pool.NewByteSlice(10, nil)
	for i := 0; i < 12; i++ {
		b := make([]byte, 64)
		b[63] = byte(i)
		p.Put(b)
	}
	for i := 0; i < 10; i++ {
		if b := p.Get(); b == nil {
			t.Fatalf("Item %d is nil", i)
		} else if b[63] != byte(i) {
			t.Fatalf("Item %d[0] != %d", b[63], i)
		}
	}
	if b := p.Get(); b != nil {
		t.Fatal("Too many items in pool")
	}
}

func TestBSPoolAlloc(t *testing.T) {
	p := pool.NewByteSlice(10, func() []byte { return make([]byte, 64) })
	for i := 0; i < 12; i++ {
		b := make([]byte, 64)
		b[63] = byte(i)
		p.Put(b)
	}
	for i := 0; i < 10; i++ {
		if b := p.Get(); b == nil {
			t.Fatalf("Item %d is nil", i)
		} else if b[63] != byte(i) {
			t.Fatalf("Item %d[0] != %d", b[63], i)
		}
	}
	if b := p.Get(); b == nil {
		t.Fatal("No new allocation")
	} else if b[63] != 0 {
		t.Fatal("Unitialized new allocation")
	}
}

func TestBSPoolEmpty(t *testing.T) {
	p := pool.NewByteSlice(10, nil)
	for i := 0; i < 12; i++ {
		b := make([]byte, 64)
		b[63] = byte(i)
		p.Put(b)
	}
	p.Empty()
	if b := p.Get(); b != nil {
		t.Fatal("Pool not empty")
	}
}

// See allocations due to conversions from []byte to
// interface{}. Avoided by specialized ByteSlice pool.
//
// run with:
//      go test -v -memprofile=mem-bsp.out -bench='ByteSlicePool$'
//   or go test -v -memprofile=mem-p.out -bench='Pool$'
//   or go test -v -memprofile=mem-sp.out -bench='SyncPool$'
//
// see results with
//
//      go tool pprof --alloc_objects ./pool.test mem-xxx.out -text
//      ... etc ...

func BenchmarkAllocByteSlicePool(b *testing.B) {
	s := make([]byte, 10)
	p := pool.NewByteSlice(1, nil)
	for i := 0; i < b.N; i++ {
		p.Put(s)
		s = p.Get()
	}
}

func BenchmarkAllocPool(b *testing.B) {
	s := make([]byte, 10)
	p := pool.New(1, nil)
	for i := 0; i < b.N; i++ {
		p.Put(s)
		s = p.Get().([]byte)
	}
}

func BenchmarkAllocSyncPool(b *testing.B) {
	var p sync.Pool
	s := make([]byte, 10)
	for i := 0; i < b.N; i++ {
		p.Put(s)
		s = p.Get().([]byte)
	}
}
<|endoftext|>


<commit_before>/*
 * Datadog API for Go
 *
 * Please see the included LICENSE file for licensing information.
 *
 * Copyright 2018 by authors and contributors.
 */

package datadog

/*
	PagerDuty Integration
*/

type servicePD struct {
	ServiceName *string `json:"service_name"`
	ServiceKey  *string `json:"service_key"`
}

type integrationPD struct {
	Services  []servicePD `json:"services"`
	Subdomain *string     `json:"subdomain"`
	Schedules []string    `json:"schedules"`
	APIToken  *string     `json:"api_token"`
}

// ServicePDRequest defines the Services struct that is part of the IntegrationPDRequest.
type ServicePDRequest struct {
	ServiceName *string `json:"service_name"`
	ServiceKey  *string `json:"service_key"`
}

// IntegrationPDRequest defines the request payload for
// creating & updating Datadog-PagerDuty integration.
type IntegrationPDRequest struct {
	Services  []ServicePDRequest `json:"services,omitempty"`
	Subdomain *string            `json:"subdomain,omitempty"`
	Schedules []string           `json:"schedules,omitempty"`
	APIToken  *string            `json:"api_token,omitempty"`
	RunCheck  *bool              `json:"run_check,omitempty"`
}

// CreateIntegrationPD creates new PagerDuty Integrations.
// Use this if you want to setup the integration for the first time
// or to add more services/schedules.
func (client *Client) CreateIntegrationPD(pdIntegration *IntegrationPDRequest) error {
	return client.doJsonRequest("POST", "/v1/integration/pagerduty", pdIntegration, nil)
}

// UpdateIntegrationPD updates the PagerDuty Integration.
// This will replace the existing values with the new values.
func (client *Client) UpdateIntegrationPD(pdIntegration *IntegrationPDRequest) error {
	return client.doJsonRequest("PUT", "/v1/integration/pagerduty", pdIntegration, nil)
}

// GetIntegrationPD gets all the PagerDuty Integrations from the system.
func (client *Client) GetIntegrationPD() (*integrationPD, error) {
	var out integrationPD
	if err := client.doJsonRequest("GET", "/v1/integration/pagerduty", nil, &out); err != nil {
		return nil, err
	}

	return &out, nil
}

// DeleteIntegrationPD removes the PagerDuty Integration from the system.
func (client *Client) DeleteIntegrationPD() error {
	return client.doJsonRequest("DELETE", "/v1/integration/pagerduty", nil, nil)
}

// CreateIntegrationPDService creates a single service object in the PagerDuty integration
// Note that creating a service object requires the integration to be activated
func (client *Client) CreateIntegrationPDService(serviceObject *ServicePDRequest) error {
	return client.doJsonRequest("POST", "/v1/integration/pagerduty/configuration/services", serviceObject, nil)
}

// UpdateIntegrationPDService updates a single service object in the PagerDuty integration
func (client *Client) UpdateIntegrationPDService(serviceObject *ServicePDRequest) error {
	// we can only post the ServiceKey, not ServiceName
	toPost := struct {
		ServiceKey *string `json:"service_key,omitempty"`
	}{
		serviceObject.ServiceKey,
	}
	uri := "/v1/integration/pagerduty/configuration/services/" + *serviceObject.ServiceName
	return client.doJsonRequest("PUT", uri, toPost, nil)
}

// GetIntegrationPDService gets a single service object in the PagerDuty integration
// NOTE: the service key is never returned by the API, so it won't be set
func (client *Client) GetIntegrationPDService(serviceName string) (*ServicePDRequest, error) {
	uri := "/v1/integration/pagerduty/configuration/services/" + serviceName
	var out ServicePDRequest
	if err := client.doJsonRequest("GET", uri, nil, &out); err != nil {
		return nil, err
	}
	return &out, nil
}

// DeleteIntegrationPDService deletes a single service object in the PagerDuty integration
func (client *Client) DeleteIntegrationPDService(serviceName string) error {
	uri := "/v1/integration/pagerduty/configuration/services/" + serviceName
	return client.doJsonRequest("DELETE", uri, nil, nil)
}

/*
	Slack Integration
*/

// ServiceHookSlackRequest defines the ServiceHooks struct that is part of the IntegrationSlackRequest.
type ServiceHookSlackRequest struct {
	Account *string `json:"account"`
	Url     *string `json:"url"`
}

// ChannelSlackRequest defines the Channels struct that is part of the IntegrationSlackRequest.
type ChannelSlackRequest struct {
	ChannelName             *string `json:"channel_name"`
	TransferAllUserComments *bool   `json:"transfer_all_user_comments,omitempty,string"`
	Account                 *string `json:"account"`
}

// IntegrationSlackRequest defines the request payload for
// creating & updating Datadog-Slack integration.
type IntegrationSlackRequest struct {
	ServiceHooks []ServiceHookSlackRequest `json:"service_hooks,omitempty"`
	Channels     []ChannelSlackRequest     `json:"channels,omitempty"`
	RunCheck     *bool                     `json:"run_check,omitempty,string"`
}

// CreateIntegrationSlack creates new Slack Integrations.
// Use this if you want to setup the integration for the first time
// or to add more channels.
func (client *Client) CreateIntegrationSlack(slackIntegration *IntegrationSlackRequest) error {
	return client.doJsonRequest("POST", "/v1/integration/slack", slackIntegration, nil)
}

// UpdateIntegrationSlack updates the Slack Integration.
// This will replace the existing values with the new values.
func (client *Client) UpdateIntegrationSlack(slackIntegration *IntegrationSlackRequest) error {
	return client.doJsonRequest("PUT", "/v1/integration/slack", slackIntegration, nil)
}

// GetIntegrationSlack gets all the Slack Integrations from the system.
func (client *Client) GetIntegrationSlack() (*IntegrationSlackRequest, error) {
	var out IntegrationSlackRequest
	if err := client.doJsonRequest("GET", "/v1/integration/slack", nil, &out); err != nil {
		return nil, err
	}

	return &out, nil
}

// DeleteIntegrationSlack removes the Slack Integration from the system.
func (client *Client) DeleteIntegrationSlack() error {
	return client.doJsonRequest("DELETE", "/v1/integration/slack", nil, nil)
}

/*
	AWS Integration
*/

// IntegrationAWSAccount defines the request payload for
// creating & updating Datadog-AWS integration.
type IntegrationAWSAccount struct {
	AccountID                     *string         `json:"account_id"`
	RoleName                      *string         `json:"role_name"`
	FilterTags                    []string        `json:"filter_tags"`
	HostTags                      []string        `json:"host_tags"`
	AccountSpecificNamespaceRules map[string]bool `json:"account_specific_namespace_rules"`
}

// IntegrationAWSAccountCreateResponse defines the response payload for
// creating & updating Datadog-AWS integration.
type IntegrationAWSAccountCreateResponse struct {
	ExternalID string `json:"external_id"`
}

type IntegrationAWSAccountGetResponse struct {
	Accounts []IntegrationAWSAccount `json:"accounts"`
}

type IntegrationAWSAccountDeleteRequest struct {
	AccountID *string `json:"account_id"`
	RoleName  *string `json:"role_name"`
}

// CreateIntegrationAWS adds a new AWS Account in the AWS Integrations.
// Use this if you want to setup the integration for the first time
// or to add more accounts.
func (client *Client) CreateIntegrationAWS(awsAccount *IntegrationAWSAccount) (*IntegrationAWSAccountCreateResponse, error) {
	var out IntegrationAWSAccountCreateResponse
	if err := client.doJsonRequest("POST", "/v1/integration/aws", awsAccount, &out); err != nil {
		return nil, err
	}

	return &out, nil
}

// GetIntegrationAWS gets all the AWS Accounts in the AWS Integrations from Datadog.
func (client *Client) GetIntegrationAWS() (*[]IntegrationAWSAccount, error) {
	var response IntegrationAWSAccountGetResponse
	if err := client.doJsonRequest("GET", "/v1/integration/aws", nil, &response); err != nil {
		return nil, err
	}

	return &response.Accounts, nil
}

// DeleteIntegrationAWS removes a specific AWS Account from the AWS Integration.
func (client *Client) DeleteIntegrationAWS(awsAccount *IntegrationAWSAccountDeleteRequest) error {
	return client.doJsonRequest("DELETE", "/v1/integration/aws", awsAccount, nil)
}

/*
	Google Cloud Platform Integration
*/

// IntegrationGCP defines the response for listing Datadog-Google CloudPlatform integration.
type IntegrationGCP struct {
	ProjectID   *string `json:"project_id"`
	ClientEmail *string `json:"client_email"`
	HostFilters *string `json:"host_filters"`
}

// IntegrationGCPCreateRequest defines the request payload for creating Datadog-Google CloudPlatform integration.
type IntegrationGCPCreateRequest struct {
	Type                    *string `json:"type"` // Should be service_account
	ProjectID               *string `json:"project_id"`
	PrivateKeyID            *string `json:"private_key_id"`
	PrivateKey              *string `json:"private_key"`
	ClientEmail             *string `json:"client_email"`
	ClientID                *string `json:"client_id"`
	AuthURI                 *string `json:"auth_uri"`                    // Should be https://accounts.google.com/o/oauth2/auth
	TokenURI                *string `json:"token_uri"`                   // Should be https://accounts.google.com/o/oauth2/token
	AuthProviderX509CertURL *string `json:"auth_provider_x509_cert_url"` // Should be https://www.googleapis.com/oauth2/v1/certs
	ClientX509CertURL       *string `json:"client_x509_cert_url"`        // https://www.googleapis.com/robot/v1/metadata/x509/<CLIENT_EMAIL>
	HostFilters             *string `json:"host_filters,omitempty"`
}

// IntegrationGCPUpdateRequest defines the request payload for updating Datadog-Google CloudPlatform integration.
type IntegrationGCPUpdateRequest struct {
	ProjectID   *string `json:"project_id"`
	ClientEmail *string `json:"client_email"`
	HostFilters *string `json:"host_filters,omitempty"`
}

// IntegrationGCPDeleteRequest defines the request payload for deleting Datadog-Google CloudPlatform integration.
type IntegrationGCPDeleteRequest struct {
	ProjectID   *string `json:"project_id"`
	ClientEmail *string `json:"client_email"`
}

// ListIntegrationGCP gets all Google Cloud Platform Integrations.
func (client *Client) ListIntegrationGCP() ([]*IntegrationGCP, error) {
	var list []*IntegrationGCP
	if err := client.doJsonRequest("GET", "/v1/integration/gcp", nil, &list); err != nil {
		return nil, err
	}
	return list, nil
}

// CreateIntegrationGCP creates a new Google Cloud Platform Integration.
func (client *Client) CreateIntegrationGCP(cir *IntegrationGCPCreateRequest) error {
	return client.doJsonRequest("POST", "/v1/integration/gcp", cir, nil)
}

// UpdateIntegrationGCP updates a Google Cloud Platform Integration.
func (client *Client) UpdateIntegrationGCP(cir *IntegrationGCPUpdateRequest) error {
	return client.doJsonRequest("POST", "/v1/integration/gcp/host_filters", cir, nil)
}

// DeleteIntegrationGCP deletes a Google Cloud Platform Integration.
func (client *Client) DeleteIntegrationGCP(cir *IntegrationGCPDeleteRequest) error {
	return client.doJsonRequest("DELETE", "/v1/integration/gcp", cir, nil)
}
<commit_msg>As documentation states, PUT has to be used to create the PD integration<commit_after>/*
 * Datadog API for Go
 *
 * Please see the included LICENSE file for licensing information.
 *
 * Copyright 2018 by authors and contributors.
 */

package datadog

/*
	PagerDuty Integration
*/

type servicePD struct {
	ServiceName *string `json:"service_name"`
	ServiceKey  *string `json:"service_key"`
}

type integrationPD struct {
	Services  []servicePD `json:"services"`
	Subdomain *string     `json:"subdomain"`
	Schedules []string    `json:"schedules"`
	APIToken  *string     `json:"api_token"`
}

// ServicePDRequest defines the Services struct that is part of the IntegrationPDRequest.
type ServicePDRequest struct {
	ServiceName *string `json:"service_name"`
	ServiceKey  *string `json:"service_key"`
}

// IntegrationPDRequest defines the request payload for
// creating & updating Datadog-PagerDuty integration.
type IntegrationPDRequest struct {
	Services  []ServicePDRequest `json:"services,omitempty"`
	Subdomain *string            `json:"subdomain,omitempty"`
	Schedules []string           `json:"schedules,omitempty"`
	APIToken  *string            `json:"api_token,omitempty"`
	RunCheck  *bool              `json:"run_check,omitempty"`
}

// CreateIntegrationPD creates new PagerDuty Integrations.
// Use this if you want to setup the integration for the first time
// or to add more services/schedules.
func (client *Client) CreateIntegrationPD(pdIntegration *IntegrationPDRequest) error {
	return client.doJsonRequest("PUT", "/v1/integration/pagerduty", pdIntegration, nil)
}

// UpdateIntegrationPD updates the PagerDuty Integration.
// This will replace the existing values with the new values.
func (client *Client) UpdateIntegrationPD(pdIntegration *IntegrationPDRequest) error {
	return client.doJsonRequest("PUT", "/v1/integration/pagerduty", pdIntegration, nil)
}

// GetIntegrationPD gets all the PagerDuty Integrations from the system.
func (client *Client) GetIntegrationPD() (*integrationPD, error) {
	var out integrationPD
	if err := client.doJsonRequest("GET", "/v1/integration/pagerduty", nil, &out); err != nil {
		return nil, err
	}

	return &out, nil
}

// DeleteIntegrationPD removes the PagerDuty Integration from the system.
func (client *Client) DeleteIntegrationPD() error {
	return client.doJsonRequest("DELETE", "/v1/integration/pagerduty", nil, nil)
}

// CreateIntegrationPDService creates a single service object in the PagerDuty integration
// Note that creating a service object requires the integration to be activated
func (client *Client) CreateIntegrationPDService(serviceObject *ServicePDRequest) error {
	return client.doJsonRequest("POST", "/v1/integration/pagerduty/configuration/services", serviceObject, nil)
}

// UpdateIntegrationPDService updates a single service object in the PagerDuty integration
func (client *Client) UpdateIntegrationPDService(serviceObject *ServicePDRequest) error {
	// we can only post the ServiceKey, not ServiceName
	toPost := struct {
		ServiceKey *string `json:"service_key,omitempty"`
	}{
		serviceObject.ServiceKey,
	}
	uri := "/v1/integration/pagerduty/configuration/services/" + *serviceObject.ServiceName
	return client.doJsonRequest("PUT", uri, toPost, nil)
}

// GetIntegrationPDService gets a single service object in the PagerDuty integration
// NOTE: the service key is never returned by the API, so it won't be set
func (client *Client) GetIntegrationPDService(serviceName string) (*ServicePDRequest, error) {
	uri := "/v1/integration/pagerduty/configuration/services/" + serviceName
	var out ServicePDRequest
	if err := client.doJsonRequest("GET", uri, nil, &out); err != nil {
		return nil, err
	}
	return &out, nil
}

// DeleteIntegrationPDService deletes a single service object in the PagerDuty integration
func (client *Client) DeleteIntegrationPDService(serviceName string) error {
	uri := "/v1/integration/pagerduty/configuration/services/" + serviceName
	return client.doJsonRequest("DELETE", uri, nil, nil)
}

/*
	Slack Integration
*/

// ServiceHookSlackRequest defines the ServiceHooks struct that is part of the IntegrationSlackRequest.
type ServiceHookSlackRequest struct {
	Account *string `json:"account"`
	Url     *string `json:"url"`
}

// ChannelSlackRequest defines the Channels struct that is part of the IntegrationSlackRequest.
type ChannelSlackRequest struct {
	ChannelName             *string `json:"channel_name"`
	TransferAllUserComments *bool   `json:"transfer_all_user_comments,omitempty,string"`
	Account                 *string `json:"account"`
}

// IntegrationSlackRequest defines the request payload for
// creating & updating Datadog-Slack integration.
type IntegrationSlackRequest struct {
	ServiceHooks []ServiceHookSlackRequest `json:"service_hooks,omitempty"`
	Channels     []ChannelSlackRequest     `json:"channels,omitempty"`
	RunCheck     *bool                     `json:"run_check,omitempty,string"`
}

// CreateIntegrationSlack creates new Slack Integrations.
// Use this if you want to setup the integration for the first time
// or to add more channels.
func (client *Client) CreateIntegrationSlack(slackIntegration *IntegrationSlackRequest) error {
	return client.doJsonRequest("POST", "/v1/integration/slack", slackIntegration, nil)
}

// UpdateIntegrationSlack updates the Slack Integration.
// This will replace the existing values with the new values.
func (client *Client) UpdateIntegrationSlack(slackIntegration *IntegrationSlackRequest) error {
	return client.doJsonRequest("PUT", "/v1/integration/slack", slackIntegration, nil)
}

// GetIntegrationSlack gets all the Slack Integrations from the system.
func (client *Client) GetIntegrationSlack() (*IntegrationSlackRequest, error) {
	var out IntegrationSlackRequest
	if err := client.doJsonRequest("GET", "/v1/integration/slack", nil, &out); err != nil {
		return nil, err
	}

	return &out, nil
}

// DeleteIntegrationSlack removes the Slack Integration from the system.
func (client *Client) DeleteIntegrationSlack() error {
	return client.doJsonRequest("DELETE", "/v1/integration/slack", nil, nil)
}

/*
	AWS Integration
*/

// IntegrationAWSAccount defines the request payload for
// creating & updating Datadog-AWS integration.
type IntegrationAWSAccount struct {
	AccountID                     *string         `json:"account_id"`
	RoleName                      *string         `json:"role_name"`
	FilterTags                    []string        `json:"filter_tags"`
	HostTags                      []string        `json:"host_tags"`
	AccountSpecificNamespaceRules map[string]bool `json:"account_specific_namespace_rules"`
}

// IntegrationAWSAccountCreateResponse defines the response payload for
// creating & updating Datadog-AWS integration.
type IntegrationAWSAccountCreateResponse struct {
	ExternalID string `json:"external_id"`
}

type IntegrationAWSAccountGetResponse struct {
	Accounts []IntegrationAWSAccount `json:"accounts"`
}

type IntegrationAWSAccountDeleteRequest struct {
	AccountID *string `json:"account_id"`
	RoleName  *string `json:"role_name"`
}

// CreateIntegrationAWS adds a new AWS Account in the AWS Integrations.
// Use this if you want to setup the integration for the first time
// or to add more accounts.
func (client *Client) CreateIntegrationAWS(awsAccount *IntegrationAWSAccount) (*IntegrationAWSAccountCreateResponse, error) {
	var out IntegrationAWSAccountCreateResponse
	if err := client.doJsonRequest("POST", "/v1/integration/aws", awsAccount, &out); err != nil {
		return nil, err
	}

	return &out, nil
}

// GetIntegrationAWS gets all the AWS Accounts in the AWS Integrations from Datadog.
func (client *Client) GetIntegrationAWS() (*[]IntegrationAWSAccount, error) {
	var response IntegrationAWSAccountGetResponse
	if err := client.doJsonRequest("GET", "/v1/integration/aws", nil, &response); err != nil {
		return nil, err
	}

	return &response.Accounts, nil
}

// DeleteIntegrationAWS removes a specific AWS Account from the AWS Integration.
func (client *Client) DeleteIntegrationAWS(awsAccount *IntegrationAWSAccountDeleteRequest) error {
	return client.doJsonRequest("DELETE", "/v1/integration/aws", awsAccount, nil)
}

/*
	Google Cloud Platform Integration
*/

// IntegrationGCP defines the response for listing Datadog-Google CloudPlatform integration.
type IntegrationGCP struct {
	ProjectID   *string `json:"project_id"`
	ClientEmail *string `json:"client_email"`
	HostFilters *string `json:"host_filters"`
}

// IntegrationGCPCreateRequest defines the request payload for creating Datadog-Google CloudPlatform integration.
type IntegrationGCPCreateRequest struct {
	Type                    *string `json:"type"` // Should be service_account
	ProjectID               *string `json:"project_id"`
	PrivateKeyID            *string `json:"private_key_id"`
	PrivateKey              *string `json:"private_key"`
	ClientEmail             *string `json:"client_email"`
	ClientID                *string `json:"client_id"`
	AuthURI                 *string `json:"auth_uri"`                    // Should be https://accounts.google.com/o/oauth2/auth
	TokenURI                *string `json:"token_uri"`                   // Should be https://accounts.google.com/o/oauth2/token
	AuthProviderX509CertURL *string `json:"auth_provider_x509_cert_url"` // Should be https://www.googleapis.com/oauth2/v1/certs
	ClientX509CertURL       *string `json:"client_x509_cert_url"`        // https://www.googleapis.com/robot/v1/metadata/x509/<CLIENT_EMAIL>
	HostFilters             *string `json:"host_filters,omitempty"`
}

// IntegrationGCPUpdateRequest defines the request payload for updating Datadog-Google CloudPlatform integration.
type IntegrationGCPUpdateRequest struct {
	ProjectID   *string `json:"project_id"`
	ClientEmail *string `json:"client_email"`
	HostFilters *string `json:"host_filters,omitempty"`
}

// IntegrationGCPDeleteRequest defines the request payload for deleting Datadog-Google CloudPlatform integration.
type IntegrationGCPDeleteRequest struct {
	ProjectID   *string `json:"project_id"`
	ClientEmail *string `json:"client_email"`
}

// ListIntegrationGCP gets all Google Cloud Platform Integrations.
func (client *Client) ListIntegrationGCP() ([]*IntegrationGCP, error) {
	var list []*IntegrationGCP
	if err := client.doJsonRequest("GET", "/v1/integration/gcp", nil, &list); err != nil {
		return nil, err
	}
	return list, nil
}

// CreateIntegrationGCP creates a new Google Cloud Platform Integration.
func (client *Client) CreateIntegrationGCP(cir *IntegrationGCPCreateRequest) error {
	return client.doJsonRequest("POST", "/v1/integration/gcp", cir, nil)
}

// UpdateIntegrationGCP updates a Google Cloud Platform Integration.
func (client *Client) UpdateIntegrationGCP(cir *IntegrationGCPUpdateRequest) error {
	return client.doJsonRequest("POST", "/v1/integration/gcp/host_filters", cir, nil)
}

// DeleteIntegrationGCP deletes a Google Cloud Platform Integration.
func (client *Client) DeleteIntegrationGCP(cir *IntegrationGCPDeleteRequest) error {
	return client.doJsonRequest("DELETE", "/v1/integration/gcp", cir, nil)
}
<|endoftext|>


<commit_before>package flags

import (
	"strconv"
)

type multiTag struct {
	value string
	cache map[string][]string
}

func newMultiTag(v string) multiTag {
	return multiTag{
		value: v,
	}
}

func (x *multiTag) scan() (map[string][]string, error) {
	v := x.value

	ret := make(map[string][]string)

	// This is mostly copied from reflect.StructTag.Get
	for v != "" {
		i := 0

		// Skip whitespace
		for i < len(v) && v[i] == ' ' {
			i++
		}

		v = v[i:]

		if v == "" {
			break
		}

		// Scan to colon to find key
		i = 0

		for i < len(v) && v[i] != ' ' && v[i] != ':' && v[i] != '"' {
			i++
		}

		if v[i] != ':' {
			return nil, newErrorf(ErrTag, "Expected `:' after key name, but got %v (in %v column %v)", v[i], v, i)
		}

		if i+1 >= len(v) {
			return nil, newErrorf(ErrTag, "Expected `\"' to start tag value at end of tag (in %v)", v)
		}

		if v[i+1] != '"' {
			return nil, newErrorf(ErrTag, "Expected `\"' to start tag value, but got %v (in %v column %v)", v[i+1], v, i+1)
		}

		name := v[:i]
		v = v[i+1:]

		// Scan quoted string to find value
		i = 1

		for i < len(v) && v[i] != '"' {
			if v[i] == '\\' {
				i++
			}
			i++
		}

		if i >= len(v) {
			return nil, newErrorf(ErrTag, "Expected end of tag value `\"' at end of tag (in %v)", v)
		}

		val, _ := strconv.Unquote(v[:i+1])
		v = v[i+1:]

		ret[name] = append(ret[name], val)
	}

	return ret, nil
}

func (x *multiTag) Parse() error {
	vals, err := x.scan()
	x.cache = vals

	return err
}

func (x *multiTag) cached() map[string][]string {
	if x.cache == nil {
		cache, _ := x.scan()

		if cache == nil {
			cache = make(map[string][]string)
		}

		x.cache = cache
	}

	return x.cache
}

func (x *multiTag) Get(key string) string {
	c := x.cached()

	if v, ok := c[key]; ok {
		return v[len(v)-1]
	}

	return ""
}

func (x *multiTag) GetMany(key string) []string {
	c := x.cached()
	return c[key]
}

func (x *multiTag) Set(key string, value string) {
	c := x.cached()
	c[key] = []string{value}
}

func (x *multiTag) SetMany(key string, value []string) {
	c := x.cached()
	c[key] = value
}
<commit_msg>Check for end of tag before expecting :<commit_after>package flags

import (
	"strconv"
)

type multiTag struct {
	value string
	cache map[string][]string
}

func newMultiTag(v string) multiTag {
	return multiTag{
		value: v,
	}
}

func (x *multiTag) scan() (map[string][]string, error) {
	v := x.value

	ret := make(map[string][]string)

	// This is mostly copied from reflect.StructTag.Get
	for v != "" {
		i := 0

		// Skip whitespace
		for i < len(v) && v[i] == ' ' {
			i++
		}

		v = v[i:]

		if v == "" {
			break
		}

		// Scan to colon to find key
		i = 0

		for i < len(v) && v[i] != ' ' && v[i] != ':' && v[i] != '"' {
			i++
		}

		if i >= len(v) {
			return nil, newErrorf(ErrTag, "Expected `:' after key name, but got end of tag (in `%v`)", v)
		}

		if v[i] != ':' {
			return nil, newErrorf(ErrTag, "Expected `:' after key name, but got %v (in %v column %v)", v[i], v, i)
		}

		if i+1 >= len(v) {
			return nil, newErrorf(ErrTag, "Expected `\"' to start tag value at end of tag (in %v)", v)
		}

		if v[i+1] != '"' {
			return nil, newErrorf(ErrTag, "Expected `\"' to start tag value, but got %v (in %v column %v)", v[i+1], v, i+1)
		}

		name := v[:i]
		v = v[i+1:]

		// Scan quoted string to find value
		i = 1

		for i < len(v) && v[i] != '"' {
			if v[i] == '\\' {
				i++
			}
			i++
		}

		if i >= len(v) {
			return nil, newErrorf(ErrTag, "Expected end of tag value `\"' at end of tag (in %v)", v)
		}

		val, _ := strconv.Unquote(v[:i+1])
		v = v[i+1:]

		ret[name] = append(ret[name], val)
	}

	return ret, nil
}

func (x *multiTag) Parse() error {
	vals, err := x.scan()
	x.cache = vals

	return err
}

func (x *multiTag) cached() map[string][]string {
	if x.cache == nil {
		cache, _ := x.scan()

		if cache == nil {
			cache = make(map[string][]string)
		}

		x.cache = cache
	}

	return x.cache
}

func (x *multiTag) Get(key string) string {
	c := x.cached()

	if v, ok := c[key]; ok {
		return v[len(v)-1]
	}

	return ""
}

func (x *multiTag) GetMany(key string) []string {
	c := x.cached()
	return c[key]
}

func (x *multiTag) Set(key string, value string) {
	c := x.cached()
	c[key] = []string{value}
}

func (x *multiTag) SetMany(key string, value []string) {
	c := x.cached()
	c[key] = value
}
<|endoftext|>


<commit_before>// +build !without_openssl

// Package stupidgcm is a thin wrapper for OpenSSL's GCM encryption and
// decryption functions. It only support 32-byte keys and 16-bit IVs.
package stupidgcm

// #include <openssl/evp.h>
// #cgo pkg-config: libcrypto
import "C"

import (
	"crypto/cipher"
	"log"
	"unsafe"
)

const (
	// BuiltWithoutOpenssl indicates if openssl been disabled at compile-time
	BuiltWithoutOpenssl = false

	keyLen = 32
	ivLen  = 16
	tagLen = 16
)

// stupidGCM implements the cipher.AEAD interface
type stupidGCM struct {
	key         []byte
	forceDecode bool
}

// Verify that we satisfy the cipher.AEAD interface
var _ cipher.AEAD = &stupidGCM{}

// New returns a new cipher.AEAD implementation..
func New(key []byte, forceDecode bool) cipher.AEAD {
	if len(key) != keyLen {
		log.Panicf("Only %d-byte keys are supported", keyLen)
	}
	return &stupidGCM{key: key, forceDecode: forceDecode}
}

func (g *stupidGCM) NonceSize() int {
	return ivLen
}

func (g *stupidGCM) Overhead() int {
	return tagLen
}

// Seal encrypts "in" using "iv" and "authData" and append the result to "dst"
func (g *stupidGCM) Seal(dst, iv, in, authData []byte) []byte {
	if len(iv) != ivLen {
		log.Panicf("Only %d-byte IVs are supported", ivLen)
	}
	if len(in) == 0 {
		log.Panic("Zero-length input data is not supported")
	}

	// If the "dst" slice is large enough we can use it as our output buffer
	outLen := len(in) + tagLen
	var buf []byte
	inplace := false
	if cap(dst)-len(dst) >= outLen {
		inplace = true
		buf = dst[len(dst) : len(dst)+outLen]
	} else {
		buf = make([]byte, outLen)
	}

	// https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption#Authenticated_Encryption_using_GCM_mode

	// Create scratch space "context"
	ctx := C.EVP_CIPHER_CTX_new()
	if ctx == nil {
		log.Panic("EVP_CIPHER_CTX_new failed")
	}

	// Set cipher to AES-256
	if C.EVP_EncryptInit_ex(ctx, C.EVP_aes_256_gcm(), nil, nil, nil) != 1 {
		log.Panic("EVP_EncryptInit_ex I failed")
	}

	// Use 16-byte IV
	if C.EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_GCM_SET_IVLEN, ivLen, nil) != 1 {
		log.Panic("EVP_CIPHER_CTX_ctrl EVP_CTRL_GCM_SET_IVLEN failed")
	}

	// Set key and IV
	if C.EVP_EncryptInit_ex(ctx, nil, nil, (*C.uchar)(&g.key[0]), (*C.uchar)(&iv[0])) != 1 {
		log.Panic("EVP_EncryptInit_ex II failed")
	}

	// Provide authentication data
	var resultLen C.int
	if C.EVP_EncryptUpdate(ctx, nil, &resultLen, (*C.uchar)(&authData[0]), C.int(len(authData))) != 1 {
		log.Panic("EVP_EncryptUpdate authData failed")
	}
	if int(resultLen) != len(authData) {
		log.Panicf("Unexpected length %d", resultLen)
	}

	// Encrypt "in" into "buf"
	if C.EVP_EncryptUpdate(ctx, (*C.uchar)(&buf[0]), &resultLen, (*C.uchar)(&in[0]), C.int(len(in))) != 1 {
		log.Panic("EVP_EncryptUpdate failed")
	}
	if int(resultLen) != len(in) {
		log.Panicf("Unexpected length %d", resultLen)
	}

	// Finalise encryption
	// Because GCM is a stream encryption, this will not write out any data.
	dummy := make([]byte, 16)
	if C.EVP_EncryptFinal_ex(ctx, (*C.uchar)(&dummy[0]), &resultLen) != 1 {
		log.Panic("EVP_EncryptFinal_ex failed")
	}
	if resultLen != 0 {
		log.Panicf("Unexpected length %d", resultLen)
	}

	// Get GMAC tag and append it to the ciphertext in "buf"
	if C.EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_GCM_GET_TAG, tagLen, (unsafe.Pointer)(&buf[len(in)])) != 1 {
		log.Panic("EVP_CIPHER_CTX_ctrl EVP_CTRL_GCM_GET_TAG failed")
	}

	// Free scratch space
	C.EVP_CIPHER_CTX_free(ctx)

	if inplace {
		return dst[:len(dst)+outLen]
	}
	return append(dst, buf...)
}

// Open decrypts "in" using "iv" and "authData" and append the result to "dst"
func (g *stupidGCM) Open(dst, iv, in, authData []byte) ([]byte, error) {
	if len(iv) != ivLen {
		log.Panicf("Only %d-byte IVs are supported", ivLen)
	}
	if len(in) <= tagLen {
		log.Panic("Input data too short")
	}

	// If the "dst" slice is large enough we can use it as our output buffer
	outLen := len(in) - tagLen
	var buf []byte
	inplace := false
	if cap(dst)-len(dst) >= outLen {
		inplace = true
		buf = dst[len(dst) : len(dst)+outLen]
	} else {
		buf = make([]byte, len(in)-tagLen)
	}

	ciphertext := in[:len(in)-tagLen]
	tag := in[len(in)-tagLen:]

	// https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption#Authenticated_Encryption_using_GCM_mode

	// Create scratch space "context"
	ctx := C.EVP_CIPHER_CTX_new()
	if ctx == nil {
		log.Panic("EVP_CIPHER_CTX_new failed")
	}

	// Set cipher to AES-256
	if C.EVP_DecryptInit_ex(ctx, C.EVP_aes_256_gcm(), nil, nil, nil) != 1 {
		log.Panic("EVP_DecryptInit_ex I failed")
	}

	// Use 16-byte IV
	if C.EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_GCM_SET_IVLEN, ivLen, nil) != 1 {
		log.Panic("EVP_CIPHER_CTX_ctrl EVP_CTRL_GCM_SET_IVLEN failed")
	}

	// Set key and IV
	if C.EVP_DecryptInit_ex(ctx, nil, nil, (*C.uchar)(&g.key[0]), (*C.uchar)(&iv[0])) != 1 {
		log.Panic("EVP_DecryptInit_ex II failed")
	}

	// Set expected GMAC tag
	if C.EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_GCM_SET_TAG, tagLen, (unsafe.Pointer)(&tag[0])) != 1 {
		log.Panic("EVP_CIPHER_CTX_ctrl failed")
	}

	// Provide authentication data
	var resultLen C.int
	if C.EVP_DecryptUpdate(ctx, nil, &resultLen, (*C.uchar)(&authData[0]), C.int(len(authData))) != 1 {
		log.Panic("EVP_DecryptUpdate authData failed")
	}
	if int(resultLen) != len(authData) {
		log.Panicf("Unexpected length %d", resultLen)
	}

	// Decrypt "ciphertext" into "buf"
	if C.EVP_DecryptUpdate(ctx, (*C.uchar)(&buf[0]), &resultLen, (*C.uchar)(&ciphertext[0]), C.int(len(ciphertext))) != 1 {
		log.Panic("EVP_DecryptUpdate failed")
	}
	if int(resultLen) != len(ciphertext) {
		log.Panicf("Unexpected length %d", resultLen)
	}

	// Check GMAC
	dummy := make([]byte, 16)
	res := C.EVP_DecryptFinal_ex(ctx, (*C.uchar)(&dummy[0]), &resultLen)
	if resultLen != 0 {
		log.Panicf("Unexpected length %d", resultLen)
	}

	// Free scratch space
	C.EVP_CIPHER_CTX_free(ctx)

	if res != 1 {
		// The error code must always be checked by the calling function, because the decrypted buffer
		// may contain corrupted data that we are returning in case the user forced reads
		if g.forceDecode == true {
			return append(dst, buf...), ErrAuth
		}
		return nil, ErrAuth
	}

	if inplace {
		return dst[:len(dst)+outLen], nil
	}
	return append(dst, buf...), nil
}
<commit_msg>stupidgcm: implement key wipe<commit_after>// +build !without_openssl

// Package stupidgcm is a thin wrapper for OpenSSL's GCM encryption and
// decryption functions. It only support 32-byte keys and 16-bit IVs.
package stupidgcm

// #include <openssl/evp.h>
// #cgo pkg-config: libcrypto
import "C"

import (
	"crypto/cipher"
	"log"
	"unsafe"
)

const (
	// BuiltWithoutOpenssl indicates if openssl been disabled at compile-time
	BuiltWithoutOpenssl = false

	keyLen = 32
	ivLen  = 16
	tagLen = 16
)

// stupidGCM implements the cipher.AEAD interface
type stupidGCM struct {
	key         []byte
	forceDecode bool
}

// Verify that we satisfy the cipher.AEAD interface
var _ cipher.AEAD = &stupidGCM{}

// New returns a new cipher.AEAD implementation..
func New(key []byte, forceDecode bool) cipher.AEAD {
	if len(key) != keyLen {
		log.Panicf("Only %d-byte keys are supported", keyLen)
	}
	return &stupidGCM{key: key, forceDecode: forceDecode}
}

func (g *stupidGCM) NonceSize() int {
	return ivLen
}

func (g *stupidGCM) Overhead() int {
	return tagLen
}

// Seal encrypts "in" using "iv" and "authData" and append the result to "dst"
func (g *stupidGCM) Seal(dst, iv, in, authData []byte) []byte {
	if len(iv) != ivLen {
		log.Panicf("Only %d-byte IVs are supported", ivLen)
	}
	if len(in) == 0 {
		log.Panic("Zero-length input data is not supported")
	}
	if len(g.key) != keyLen {
		log.Panicf("Wrong key length: %d. Key has been wiped?", len(g.key))
	}

	// If the "dst" slice is large enough we can use it as our output buffer
	outLen := len(in) + tagLen
	var buf []byte
	inplace := false
	if cap(dst)-len(dst) >= outLen {
		inplace = true
		buf = dst[len(dst) : len(dst)+outLen]
	} else {
		buf = make([]byte, outLen)
	}

	// https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption#Authenticated_Encryption_using_GCM_mode

	// Create scratch space "context"
	ctx := C.EVP_CIPHER_CTX_new()
	if ctx == nil {
		log.Panic("EVP_CIPHER_CTX_new failed")
	}

	// Set cipher to AES-256
	if C.EVP_EncryptInit_ex(ctx, C.EVP_aes_256_gcm(), nil, nil, nil) != 1 {
		log.Panic("EVP_EncryptInit_ex I failed")
	}

	// Use 16-byte IV
	if C.EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_GCM_SET_IVLEN, ivLen, nil) != 1 {
		log.Panic("EVP_CIPHER_CTX_ctrl EVP_CTRL_GCM_SET_IVLEN failed")
	}

	// Set key and IV
	if C.EVP_EncryptInit_ex(ctx, nil, nil, (*C.uchar)(&g.key[0]), (*C.uchar)(&iv[0])) != 1 {
		log.Panic("EVP_EncryptInit_ex II failed")
	}

	// Provide authentication data
	var resultLen C.int
	if C.EVP_EncryptUpdate(ctx, nil, &resultLen, (*C.uchar)(&authData[0]), C.int(len(authData))) != 1 {
		log.Panic("EVP_EncryptUpdate authData failed")
	}
	if int(resultLen) != len(authData) {
		log.Panicf("Unexpected length %d", resultLen)
	}

	// Encrypt "in" into "buf"
	if C.EVP_EncryptUpdate(ctx, (*C.uchar)(&buf[0]), &resultLen, (*C.uchar)(&in[0]), C.int(len(in))) != 1 {
		log.Panic("EVP_EncryptUpdate failed")
	}
	if int(resultLen) != len(in) {
		log.Panicf("Unexpected length %d", resultLen)
	}

	// Finalise encryption
	// Because GCM is a stream encryption, this will not write out any data.
	dummy := make([]byte, 16)
	if C.EVP_EncryptFinal_ex(ctx, (*C.uchar)(&dummy[0]), &resultLen) != 1 {
		log.Panic("EVP_EncryptFinal_ex failed")
	}
	if resultLen != 0 {
		log.Panicf("Unexpected length %d", resultLen)
	}

	// Get GMAC tag and append it to the ciphertext in "buf"
	if C.EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_GCM_GET_TAG, tagLen, (unsafe.Pointer)(&buf[len(in)])) != 1 {
		log.Panic("EVP_CIPHER_CTX_ctrl EVP_CTRL_GCM_GET_TAG failed")
	}

	// Free scratch space
	C.EVP_CIPHER_CTX_free(ctx)

	if inplace {
		return dst[:len(dst)+outLen]
	}
	return append(dst, buf...)
}

// Open decrypts "in" using "iv" and "authData" and append the result to "dst"
func (g *stupidGCM) Open(dst, iv, in, authData []byte) ([]byte, error) {
	if len(iv) != ivLen {
		log.Panicf("Only %d-byte IVs are supported", ivLen)
	}
	if len(in) <= tagLen {
		log.Panic("Input data too short")
	}
	if len(g.key) != keyLen {
		log.Panicf("Wrong key length: %d. Key has been wiped?", len(g.key))
	}

	// If the "dst" slice is large enough we can use it as our output buffer
	outLen := len(in) - tagLen
	var buf []byte
	inplace := false
	if cap(dst)-len(dst) >= outLen {
		inplace = true
		buf = dst[len(dst) : len(dst)+outLen]
	} else {
		buf = make([]byte, len(in)-tagLen)
	}

	ciphertext := in[:len(in)-tagLen]
	tag := in[len(in)-tagLen:]

	// https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption#Authenticated_Encryption_using_GCM_mode

	// Create scratch space "context"
	ctx := C.EVP_CIPHER_CTX_new()
	if ctx == nil {
		log.Panic("EVP_CIPHER_CTX_new failed")
	}

	// Set cipher to AES-256
	if C.EVP_DecryptInit_ex(ctx, C.EVP_aes_256_gcm(), nil, nil, nil) != 1 {
		log.Panic("EVP_DecryptInit_ex I failed")
	}

	// Use 16-byte IV
	if C.EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_GCM_SET_IVLEN, ivLen, nil) != 1 {
		log.Panic("EVP_CIPHER_CTX_ctrl EVP_CTRL_GCM_SET_IVLEN failed")
	}

	// Set key and IV
	if C.EVP_DecryptInit_ex(ctx, nil, nil, (*C.uchar)(&g.key[0]), (*C.uchar)(&iv[0])) != 1 {
		log.Panic("EVP_DecryptInit_ex II failed")
	}

	// Set expected GMAC tag
	if C.EVP_CIPHER_CTX_ctrl(ctx, C.EVP_CTRL_GCM_SET_TAG, tagLen, (unsafe.Pointer)(&tag[0])) != 1 {
		log.Panic("EVP_CIPHER_CTX_ctrl failed")
	}

	// Provide authentication data
	var resultLen C.int
	if C.EVP_DecryptUpdate(ctx, nil, &resultLen, (*C.uchar)(&authData[0]), C.int(len(authData))) != 1 {
		log.Panic("EVP_DecryptUpdate authData failed")
	}
	if int(resultLen) != len(authData) {
		log.Panicf("Unexpected length %d", resultLen)
	}

	// Decrypt "ciphertext" into "buf"
	if C.EVP_DecryptUpdate(ctx, (*C.uchar)(&buf[0]), &resultLen, (*C.uchar)(&ciphertext[0]), C.int(len(ciphertext))) != 1 {
		log.Panic("EVP_DecryptUpdate failed")
	}
	if int(resultLen) != len(ciphertext) {
		log.Panicf("Unexpected length %d", resultLen)
	}

	// Check GMAC
	dummy := make([]byte, 16)
	res := C.EVP_DecryptFinal_ex(ctx, (*C.uchar)(&dummy[0]), &resultLen)
	if resultLen != 0 {
		log.Panicf("Unexpected length %d", resultLen)
	}

	// Free scratch space
	C.EVP_CIPHER_CTX_free(ctx)

	if res != 1 {
		// The error code must always be checked by the calling function, because the decrypted buffer
		// may contain corrupted data that we are returning in case the user forced reads
		if g.forceDecode == true {
			return append(dst, buf...), ErrAuth
		}
		return nil, ErrAuth
	}

	if inplace {
		return dst[:len(dst)+outLen], nil
	}
	return append(dst, buf...), nil
}

// Wipe wipes the AES key from memory by overwriting it with zeros and
// setting the reference to nil.
//
// This is not bulletproof due to possible GC copies, but
// still raises to bar for extracting the key.
func (g *stupidGCM) Wipe() {
	for i := range g.key {
		g.key[i] = 0
	}
	g.key = nil
}
<|endoftext|>


<commit_before>package collectors

import (
	"fmt"
	"strconv"
	"strings"

	"bosun.org/cmd/scollector/conf"
	"bosun.org/collect"
	"bosun.org/metadata"
	"bosun.org/opentsdb"
	"bosun.org/slog"
	"github.com/garyburd/redigo/redis"
)

func init() {
	registerInit(func(c *conf.Conf) {
		for _, red := range c.RedisCounters {
			collectors = append(collectors,
				&IntervalCollector{
					name: "redisCounters_" + red.Server,
					F: func() (opentsdb.MultiDataPoint, error) {
						return c_redis_counters(red.Server, red.Database)
					},
				})
		}
	})
}

func c_redis_counters(server string, db int) (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	conn, err := redis.Dial("tcp", server, redis.DialDatabase(db))
	if err != nil {
		return md, err
	}
	defer conn.Close()
	if _, err := conn.Do("CLIENT", "SETNAME", "scollector"); err != nil {
		return md, err
	}
	cursor := 0
	for {
		vals, err := redis.Values(conn.Do("HSCAN", collect.RedisCountersKey, cursor))
		if err != nil {
			return md, err
		}
		if len(vals) != 2 {
			return md, fmt.Errorf("Unexpected number of values")
		}
		cursor, err = redis.Int(vals[0], nil)
		if err != nil {
			return md, err
		}
		pairs, err := redis.StringMap(vals[1], nil)
		if err != nil {
			return md, err
		}
		for mts, val := range pairs {
			parts := strings.Split(mts, ":")
			if len(parts) != 2 {
				slog.Errorf("Invalid metric tag set counter: %s", mts)
				continue
			}
			metric := parts[0]
			tags, err := opentsdb.ParseTags(parts[1])
			if err != nil {
				slog.Errorf("Invalid tags: %s", parts[1])
				continue
			}
			v, err := strconv.Atoi(val)
			if err != nil {
				slog.Errorf("Invalid counter value: %s", val)
				continue
			}
			Add(&md, metric, v, tags, metadata.Counter, metadata.Count, "")
		}
		if cursor == 0 {
			break
		}
	}
	return md, nil
}
<commit_msg>remove setname for ledis<commit_after>package collectors

import (
	"fmt"
	"strconv"
	"strings"

	"bosun.org/cmd/scollector/conf"
	"bosun.org/collect"
	"bosun.org/metadata"
	"bosun.org/opentsdb"
	"bosun.org/slog"
	"github.com/garyburd/redigo/redis"
)

func init() {
	registerInit(func(c *conf.Conf) {
		for _, red := range c.RedisCounters {
			collectors = append(collectors,
				&IntervalCollector{
					name: "redisCounters_" + red.Server,
					F: func() (opentsdb.MultiDataPoint, error) {
						return c_redis_counters(red.Server, red.Database)
					},
				})
		}
	})
}

func c_redis_counters(server string, db int) (opentsdb.MultiDataPoint, error) {
	var md opentsdb.MultiDataPoint
	conn, err := redis.Dial("tcp", server, redis.DialDatabase(db))
	if err != nil {
		return md, err
	}
	defer conn.Close()
	cursor := 0
	for {
		vals, err := redis.Values(conn.Do("HSCAN", collect.RedisCountersKey, cursor))
		if err != nil {
			return md, err
		}
		if len(vals) != 2 {
			return md, fmt.Errorf("Unexpected number of values")
		}
		cursor, err = redis.Int(vals[0], nil)
		if err != nil {
			return md, err
		}
		pairs, err := redis.StringMap(vals[1], nil)
		if err != nil {
			return md, err
		}
		for mts, val := range pairs {
			parts := strings.Split(mts, ":")
			if len(parts) != 2 {
				slog.Errorf("Invalid metric tag set counter: %s", mts)
				continue
			}
			metric := parts[0]
			tags, err := opentsdb.ParseTags(parts[1])
			if err != nil {
				slog.Errorf("Invalid tags: %s", parts[1])
				continue
			}
			v, err := strconv.Atoi(val)
			if err != nil {
				slog.Errorf("Invalid counter value: %s", val)
				continue
			}
			Add(&md, metric, v, tags, metadata.Counter, metadata.Count, "")
		}
		if cursor == 0 {
			break
		}
	}
	return md, nil
}
<|endoftext|>


<commit_before>package filer2

import (
	"fmt"

	"github.com/chrislusf/seaweedfs/weed/glog"
	"github.com/karlseguin/ccache"
	"os"
	"path/filepath"
	"strings"
	"time"
	"github.com/chrislusf/seaweedfs/weed/operation"
)

type Filer struct {
	masters        []string
	store          FilerStore
	directoryCache *ccache.Cache

	currentMaster string
}

func NewFiler(masters []string) *Filer {
	return &Filer{
		masters:        masters,
		directoryCache: ccache.New(ccache.Configure().MaxSize(1000).ItemsToPrune(100)),
	}
}

func (f *Filer) SetStore(store FilerStore) {
	f.store = store
}

func (f *Filer) DisableDirectoryCache() {
	f.directoryCache = nil
}

func (f *Filer) CreateEntry(entry *Entry) error {

	dirParts := strings.Split(string(entry.FullPath), "/")

	// fmt.Printf("directory parts: %+v\n", dirParts)

	var lastDirectoryEntry *Entry

	for i := 1; i < len(dirParts); i++ {
		dirPath := "/" + filepath.Join(dirParts[:i]...)
		// fmt.Printf("%d directory: %+v\n", i, dirPath)

		// first check local cache
		dirEntry := f.cacheGetDirectory(dirPath)

		// not found, check the store directly
		if dirEntry == nil {
			glog.V(4).Infof("find uncached directory: %s", dirPath)
			dirEntry, _ = f.FindEntry(FullPath(dirPath))
		} else {
			glog.V(4).Infof("found cached directory: %s", dirPath)
		}

		// no such existing directory
		if dirEntry == nil {

			// create the directory
			now := time.Now()

			dirEntry = &Entry{
				FullPath: FullPath(dirPath),
				Attr: Attr{
					Mtime:  now,
					Crtime: now,
					Mode:   os.ModeDir | 0770,
					Uid:    entry.Uid,
					Gid:    entry.Gid,
				},
			}

			glog.V(2).Infof("create directory: %s %v", dirPath, dirEntry.Mode)
			mkdirErr := f.store.InsertEntry(dirEntry)
			if mkdirErr != nil {
				return fmt.Errorf("mkdir %s: %v", dirPath, mkdirErr)
			}
		}

		// cache the directory entry
		f.cacheSetDirectory(dirPath, dirEntry, i)

		// remember the direct parent directory entry
		if i == len(dirParts)-1 {
			lastDirectoryEntry = dirEntry
		}

	}

	if lastDirectoryEntry == nil {
		return fmt.Errorf("parent folder not found: %v", entry.FullPath)
	}

	/*
		if !hasWritePermission(lastDirectoryEntry, entry) {
			glog.V(0).Infof("directory %s: %v, entry: uid=%d gid=%d",
				lastDirectoryEntry.FullPath, lastDirectoryEntry.Attr, entry.Uid, entry.Gid)
			return fmt.Errorf("no write permission in folder %v", lastDirectoryEntry.FullPath)
		}
	*/

	if oldEntry, err := f.FindEntry(entry.FullPath); err == nil {
		f.deleteChunks(oldEntry)
	}

	if err := f.store.InsertEntry(entry); err != nil {
		return fmt.Errorf("insert entry %s: %v", entry.FullPath, err)
	}

	return nil
}

func (f *Filer) UpdateEntry(entry *Entry) (err error) {
	return f.store.UpdateEntry(entry)
}

func (f *Filer) FindEntry(p FullPath) (entry *Entry, err error) {
	return f.store.FindEntry(p)
}

func (f *Filer) DeleteEntryMetaAndData(p FullPath, shouldDeleteChunks bool) (err error) {
	entry, err := f.FindEntry(p)
	if err != nil {
		return err
	}

	if entry.IsDirectory() {
		entries, err := f.ListDirectoryEntries(p, "", false, 1)
		if err != nil {
			return fmt.Errorf("list folder %s: %v", p, err)
		}
		if len(entries) > 0 {
			return fmt.Errorf("folder %s is not empty", p)
		}
	}

	if shouldDeleteChunks {
		f.deleteChunks(entry)
	}

	return f.store.DeleteEntry(p)
}

func (f *Filer) ListDirectoryEntries(p FullPath, startFileName string, inclusive bool, limit int) ([]*Entry, error) {
	if strings.HasSuffix(string(p), "/") && len(p) > 1 {
		p = p[0: len(p)-1]
	}
	return f.store.ListDirectoryEntries(p, startFileName, inclusive, limit)
}

func (f *Filer) cacheGetDirectory(dirpath string) *Entry {
	if f.directoryCache == nil {
		return nil
	}
	item := f.directoryCache.Get(dirpath)
	if item == nil {
		return nil
	}
	return item.Value().(*Entry)
}

func (f *Filer) cacheSetDirectory(dirpath string, dirEntry *Entry, level int) {

	if f.directoryCache == nil {
		return
	}

	minutes := 60
	if level < 10 {
		minutes -= level * 6
	}

	f.directoryCache.Set(dirpath, dirEntry, time.Duration(minutes)*time.Minute)
}

func (f *Filer) deleteChunks(entry *Entry) {

	if entry == nil {
		return
	}
	for _, chunk := range entry.Chunks {
		if err := operation.DeleteFile(f.GetMaster(), chunk.FileId, ""); err != nil {
			glog.V(0).Infof("deleting file %s: %v", chunk.FileId, err)
		}
	}
}
<commit_msg>delete old entry only after successful insert<commit_after>package filer2

import (
	"fmt"

	"github.com/chrislusf/seaweedfs/weed/glog"
	"github.com/karlseguin/ccache"
	"os"
	"path/filepath"
	"strings"
	"time"
	"github.com/chrislusf/seaweedfs/weed/operation"
)

type Filer struct {
	masters        []string
	store          FilerStore
	directoryCache *ccache.Cache

	currentMaster string
}

func NewFiler(masters []string) *Filer {
	return &Filer{
		masters:        masters,
		directoryCache: ccache.New(ccache.Configure().MaxSize(1000).ItemsToPrune(100)),
	}
}

func (f *Filer) SetStore(store FilerStore) {
	f.store = store
}

func (f *Filer) DisableDirectoryCache() {
	f.directoryCache = nil
}

func (f *Filer) CreateEntry(entry *Entry) error {

	dirParts := strings.Split(string(entry.FullPath), "/")

	// fmt.Printf("directory parts: %+v\n", dirParts)

	var lastDirectoryEntry *Entry

	for i := 1; i < len(dirParts); i++ {
		dirPath := "/" + filepath.Join(dirParts[:i]...)
		// fmt.Printf("%d directory: %+v\n", i, dirPath)

		// first check local cache
		dirEntry := f.cacheGetDirectory(dirPath)

		// not found, check the store directly
		if dirEntry == nil {
			glog.V(4).Infof("find uncached directory: %s", dirPath)
			dirEntry, _ = f.FindEntry(FullPath(dirPath))
		} else {
			glog.V(4).Infof("found cached directory: %s", dirPath)
		}

		// no such existing directory
		if dirEntry == nil {

			// create the directory
			now := time.Now()

			dirEntry = &Entry{
				FullPath: FullPath(dirPath),
				Attr: Attr{
					Mtime:  now,
					Crtime: now,
					Mode:   os.ModeDir | 0770,
					Uid:    entry.Uid,
					Gid:    entry.Gid,
				},
			}

			glog.V(2).Infof("create directory: %s %v", dirPath, dirEntry.Mode)
			mkdirErr := f.store.InsertEntry(dirEntry)
			if mkdirErr != nil {
				return fmt.Errorf("mkdir %s: %v", dirPath, mkdirErr)
			}
		}

		// cache the directory entry
		f.cacheSetDirectory(dirPath, dirEntry, i)

		// remember the direct parent directory entry
		if i == len(dirParts)-1 {
			lastDirectoryEntry = dirEntry
		}

	}

	if lastDirectoryEntry == nil {
		return fmt.Errorf("parent folder not found: %v", entry.FullPath)
	}

	/*
		if !hasWritePermission(lastDirectoryEntry, entry) {
			glog.V(0).Infof("directory %s: %v, entry: uid=%d gid=%d",
				lastDirectoryEntry.FullPath, lastDirectoryEntry.Attr, entry.Uid, entry.Gid)
			return fmt.Errorf("no write permission in folder %v", lastDirectoryEntry.FullPath)
		}
	*/

	oldEntry, _ := f.FindEntry(entry.FullPath)

	if err := f.store.InsertEntry(entry); err != nil {
		return fmt.Errorf("insert entry %s: %v", entry.FullPath, err)
	}

	f.deleteChunks(oldEntry)

	return nil
}

func (f *Filer) UpdateEntry(entry *Entry) (err error) {
	return f.store.UpdateEntry(entry)
}

func (f *Filer) FindEntry(p FullPath) (entry *Entry, err error) {
	return f.store.FindEntry(p)
}

func (f *Filer) DeleteEntryMetaAndData(p FullPath, shouldDeleteChunks bool) (err error) {
	entry, err := f.FindEntry(p)
	if err != nil {
		return err
	}

	if entry.IsDirectory() {
		entries, err := f.ListDirectoryEntries(p, "", false, 1)
		if err != nil {
			return fmt.Errorf("list folder %s: %v", p, err)
		}
		if len(entries) > 0 {
			return fmt.Errorf("folder %s is not empty", p)
		}
	}

	if shouldDeleteChunks {
		f.deleteChunks(entry)
	}

	return f.store.DeleteEntry(p)
}

func (f *Filer) ListDirectoryEntries(p FullPath, startFileName string, inclusive bool, limit int) ([]*Entry, error) {
	if strings.HasSuffix(string(p), "/") && len(p) > 1 {
		p = p[0: len(p)-1]
	}
	return f.store.ListDirectoryEntries(p, startFileName, inclusive, limit)
}

func (f *Filer) cacheGetDirectory(dirpath string) *Entry {
	if f.directoryCache == nil {
		return nil
	}
	item := f.directoryCache.Get(dirpath)
	if item == nil {
		return nil
	}
	return item.Value().(*Entry)
}

func (f *Filer) cacheSetDirectory(dirpath string, dirEntry *Entry, level int) {

	if f.directoryCache == nil {
		return
	}

	minutes := 60
	if level < 10 {
		minutes -= level * 6
	}

	f.directoryCache.Set(dirpath, dirEntry, time.Duration(minutes)*time.Minute)
}

func (f *Filer) deleteChunks(entry *Entry) {

	if entry == nil {
		return
	}
	for _, chunk := range entry.Chunks {
		if err := operation.DeleteFile(f.GetMaster(), chunk.FileId, ""); err != nil {
			glog.V(0).Infof("deleting file %s: %v", chunk.FileId, err)
		}
	}
}
<|endoftext|>


<commit_before>// ----------------------------------------------------------------------------
//
//     ***     AUTO GENERATED CODE    ***    Type: MMv1     ***
//
// ----------------------------------------------------------------------------
//
//     This file is automatically generated by Magic Modules and manual
//     changes will be clobbered when the file is regenerated.
//
//     Please read more about how to change this file in
//     .github/CONTRIBUTING.md.
//
// ----------------------------------------------------------------------------

package google

import (
	"fmt"
	"reflect"
	"time"
)

func GetKMSCryptoKeyCaiObject(d TerraformResourceData, config *Config) ([]Asset, error) {
	name, err := assetName(d, config, "//kms.googleapis.com/{{key_ring}}/cryptoKeys/{{name}}")
	if err != nil {
		return []Asset{}, err
	}
	if obj, err := GetKMSCryptoKeyApiObject(d, config); err == nil {
		return []Asset{{
			Name: name,
			Type: "kms.googleapis.com/CryptoKey",
			Resource: &AssetResource{
				Version:              "v1",
				DiscoveryDocumentURI: "https://www.googleapis.com/discovery/v1/apis/kms/v1/rest",
				DiscoveryName:        "CryptoKey",
				Data:                 obj,
			},
		}}, nil
	} else {
		return []Asset{}, err
	}
}

func GetKMSCryptoKeyApiObject(d TerraformResourceData, config *Config) (map[string]interface{}, error) {
	obj := make(map[string]interface{})
	labelsProp, err := expandKMSCryptoKeyLabels(d.Get("labels"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("labels"); !isEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) {
		obj["labels"] = labelsProp
	}
	purposeProp, err := expandKMSCryptoKeyPurpose(d.Get("purpose"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("purpose"); !isEmptyValue(reflect.ValueOf(purposeProp)) && (ok || !reflect.DeepEqual(v, purposeProp)) {
		obj["purpose"] = purposeProp
	}
	rotationPeriodProp, err := expandKMSCryptoKeyRotationPeriod(d.Get("rotation_period"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("rotation_period"); !isEmptyValue(reflect.ValueOf(rotationPeriodProp)) && (ok || !reflect.DeepEqual(v, rotationPeriodProp)) {
		obj["rotationPeriod"] = rotationPeriodProp
	}
	versionTemplateProp, err := expandKMSCryptoKeyVersionTemplate(d.Get("version_template"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("version_template"); !isEmptyValue(reflect.ValueOf(versionTemplateProp)) && (ok || !reflect.DeepEqual(v, versionTemplateProp)) {
		obj["versionTemplate"] = versionTemplateProp
	}

	return resourceKMSCryptoKeyEncoder(d, config, obj)
}

func resourceKMSCryptoKeyEncoder(d TerraformResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) {
	// if rotationPeriod is set, nextRotationTime must also be set.
	if d.Get("rotation_period") != "" {
		rotationPeriod := d.Get("rotation_period").(string)
		nextRotation, err := kmsCryptoKeyNextRotation(time.Now(), rotationPeriod)

		if err != nil {
			return nil, fmt.Errorf("Error setting CryptoKey rotation period: %s", err.Error())
		}

		obj["nextRotationTime"] = nextRotation
	}

	// set to false if it is not true explicitly
	if !(d.Get("skip_initial_version_creation").(bool)) {
		if err := d.Set("skip_initial_version_creation", false); err != nil {
			return nil, fmt.Errorf("Error setting skip_initial_version_creation: %s", err)
		}
	}

	return obj, nil
}

func expandKMSCryptoKeyLabels(v interface{}, d TerraformResourceData, config *Config) (map[string]string, error) {
	if v == nil {
		return map[string]string{}, nil
	}
	m := make(map[string]string)
	for k, val := range v.(map[string]interface{}) {
		m[k] = val.(string)
	}
	return m, nil
}

func expandKMSCryptoKeyPurpose(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandKMSCryptoKeyRotationPeriod(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandKMSCryptoKeyVersionTemplate(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	l := v.([]interface{})
	if len(l) == 0 || l[0] == nil {
		return nil, nil
	}
	raw := l[0]
	original := raw.(map[string]interface{})
	transformed := make(map[string]interface{})

	transformedAlgorithm, err := expandKMSCryptoKeyVersionTemplateAlgorithm(original["algorithm"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedAlgorithm); val.IsValid() && !isEmptyValue(val) {
		transformed["algorithm"] = transformedAlgorithm
	}

	transformedProtectionLevel, err := expandKMSCryptoKeyVersionTemplateProtectionLevel(original["protection_level"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedProtectionLevel); val.IsValid() && !isEmptyValue(val) {
		transformed["protectionLevel"] = transformedProtectionLevel
	}

	return transformed, nil
}

func expandKMSCryptoKeyVersionTemplateAlgorithm(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandKMSCryptoKeyVersionTemplateProtectionLevel(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}
<commit_msg>Add soft deletion retention to KMS key (#5131) (#773)<commit_after>// ----------------------------------------------------------------------------
//
//     ***     AUTO GENERATED CODE    ***    Type: MMv1     ***
//
// ----------------------------------------------------------------------------
//
//     This file is automatically generated by Magic Modules and manual
//     changes will be clobbered when the file is regenerated.
//
//     Please read more about how to change this file in
//     .github/CONTRIBUTING.md.
//
// ----------------------------------------------------------------------------

package google

import (
	"fmt"
	"reflect"
	"time"
)

func GetKMSCryptoKeyCaiObject(d TerraformResourceData, config *Config) ([]Asset, error) {
	name, err := assetName(d, config, "//kms.googleapis.com/{{key_ring}}/cryptoKeys/{{name}}")
	if err != nil {
		return []Asset{}, err
	}
	if obj, err := GetKMSCryptoKeyApiObject(d, config); err == nil {
		return []Asset{{
			Name: name,
			Type: "kms.googleapis.com/CryptoKey",
			Resource: &AssetResource{
				Version:              "v1",
				DiscoveryDocumentURI: "https://www.googleapis.com/discovery/v1/apis/kms/v1/rest",
				DiscoveryName:        "CryptoKey",
				Data:                 obj,
			},
		}}, nil
	} else {
		return []Asset{}, err
	}
}

func GetKMSCryptoKeyApiObject(d TerraformResourceData, config *Config) (map[string]interface{}, error) {
	obj := make(map[string]interface{})
	labelsProp, err := expandKMSCryptoKeyLabels(d.Get("labels"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("labels"); !isEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) {
		obj["labels"] = labelsProp
	}
	purposeProp, err := expandKMSCryptoKeyPurpose(d.Get("purpose"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("purpose"); !isEmptyValue(reflect.ValueOf(purposeProp)) && (ok || !reflect.DeepEqual(v, purposeProp)) {
		obj["purpose"] = purposeProp
	}
	rotationPeriodProp, err := expandKMSCryptoKeyRotationPeriod(d.Get("rotation_period"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("rotation_period"); !isEmptyValue(reflect.ValueOf(rotationPeriodProp)) && (ok || !reflect.DeepEqual(v, rotationPeriodProp)) {
		obj["rotationPeriod"] = rotationPeriodProp
	}
	versionTemplateProp, err := expandKMSCryptoKeyVersionTemplate(d.Get("version_template"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("version_template"); !isEmptyValue(reflect.ValueOf(versionTemplateProp)) && (ok || !reflect.DeepEqual(v, versionTemplateProp)) {
		obj["versionTemplate"] = versionTemplateProp
	}
	destroyScheduledDurationProp, err := expandKMSCryptoKeyDestroyScheduledDuration(d.Get("destroy_scheduled_duration"), d, config)
	if err != nil {
		return nil, err
	} else if v, ok := d.GetOkExists("destroy_scheduled_duration"); !isEmptyValue(reflect.ValueOf(destroyScheduledDurationProp)) && (ok || !reflect.DeepEqual(v, destroyScheduledDurationProp)) {
		obj["destroyScheduledDuration"] = destroyScheduledDurationProp
	}

	return resourceKMSCryptoKeyEncoder(d, config, obj)
}

func resourceKMSCryptoKeyEncoder(d TerraformResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) {
	// if rotationPeriod is set, nextRotationTime must also be set.
	if d.Get("rotation_period") != "" {
		rotationPeriod := d.Get("rotation_period").(string)
		nextRotation, err := kmsCryptoKeyNextRotation(time.Now(), rotationPeriod)

		if err != nil {
			return nil, fmt.Errorf("Error setting CryptoKey rotation period: %s", err.Error())
		}

		obj["nextRotationTime"] = nextRotation
	}

	// set to false if it is not true explicitly
	if !(d.Get("skip_initial_version_creation").(bool)) {
		if err := d.Set("skip_initial_version_creation", false); err != nil {
			return nil, fmt.Errorf("Error setting skip_initial_version_creation: %s", err)
		}
	}

	return obj, nil
}

func expandKMSCryptoKeyLabels(v interface{}, d TerraformResourceData, config *Config) (map[string]string, error) {
	if v == nil {
		return map[string]string{}, nil
	}
	m := make(map[string]string)
	for k, val := range v.(map[string]interface{}) {
		m[k] = val.(string)
	}
	return m, nil
}

func expandKMSCryptoKeyPurpose(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandKMSCryptoKeyRotationPeriod(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandKMSCryptoKeyVersionTemplate(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	l := v.([]interface{})
	if len(l) == 0 || l[0] == nil {
		return nil, nil
	}
	raw := l[0]
	original := raw.(map[string]interface{})
	transformed := make(map[string]interface{})

	transformedAlgorithm, err := expandKMSCryptoKeyVersionTemplateAlgorithm(original["algorithm"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedAlgorithm); val.IsValid() && !isEmptyValue(val) {
		transformed["algorithm"] = transformedAlgorithm
	}

	transformedProtectionLevel, err := expandKMSCryptoKeyVersionTemplateProtectionLevel(original["protection_level"], d, config)
	if err != nil {
		return nil, err
	} else if val := reflect.ValueOf(transformedProtectionLevel); val.IsValid() && !isEmptyValue(val) {
		transformed["protectionLevel"] = transformedProtectionLevel
	}

	return transformed, nil
}

func expandKMSCryptoKeyVersionTemplateAlgorithm(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandKMSCryptoKeyVersionTemplateProtectionLevel(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}

func expandKMSCryptoKeyDestroyScheduledDuration(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
	return v, nil
}
<|endoftext|>


<commit_before>package metadata

import (
	"strings"

	"github.com/StackExchange/scollector/opentsdb"
	"github.com/StackExchange/scollector/util"
)

func init() {
	metafuncs = append(metafuncs, metaWindowsVersion, metaWindowsIfaces)
}

func metaWindowsVersion() {
	util.ReadCommand(func(line string) error {
		fields := strings.Fields(line)
		if len(fields) == 0 {
			return nil
		}
		AddMeta("", nil, "version", strings.Join(fields, " "), true)
		return nil
	}, "cmd", "/c", "ver")
}

func metaWindowsIfaces() {
	var iface string
	util.ReadCommand(func(line string) error {
		fields := strings.Fields(line)
		sp := strings.Split(line, ":")
		if len(fields) == 0 || len(sp) != 2 {
			return nil
		}
		if line[0] != ' ' {
			iface = sp[0]
		} else if strings.HasPrefix(line, "   IPv4 Address") {
			AddMeta("", opentsdb.TagSet{"iface": iface}, "addr", strings.TrimSpace(sp[1]), true)
		}
		return nil
	}, "ipconfig")
}
<commit_msg>cmd/scollector: Use Win32_OperatingSystem to get windows version and caption<commit_after>package metadata

import (
	"strings"

	"github.com/StackExchange/scollector/opentsdb"
	"github.com/StackExchange/scollector/util"
	"github.com/StackExchange/slog"
	"github.com/StackExchange/wmi"
)

func init() {
	metafuncs = append(metafuncs, metaWindowsVersion, metaWindowsIfaces)
}

func queryWmi(query string, dst interface{}) error {
	return queryWmiNamespace(query, dst, "")
}

func queryWmiNamespace(query string, dst interface{}, namespace string) error {
	return wmi.QueryNamespace(query, dst, namespace)
}

func metaWindowsVersion() {
	var dst []Win32_OperatingSystem
	var q = wmi.CreateQuery(&dst, "")
	err := queryWmi(q, &dst)
	if err != nil {
		slog.Error(err)
		return
	} else {
		for _, v := range dst {
			AddMeta("", nil, "version", v.Version, true)
			AddMeta("", nil, "versionCaption", v.Caption, true)
		}
	}
}

type Win32_OperatingSystem struct {
	Caption         string
	CurrentTimeZone int16
	InstallDate     string
	Organization    string
	OSArchitecture  string
	OSLanguage      int32
	Version         string
}

func metaWindowsIfaces() {
	var iface string
	util.ReadCommand(func(line string) error {
		fields := strings.Fields(line)
		sp := strings.Split(line, ":")
		if len(fields) == 0 || len(sp) != 2 {
			return nil
		}
		if line[0] != ' ' {
			iface = sp[0]
		} else if strings.HasPrefix(line, "   IPv4 Address") {
			AddMeta("", opentsdb.TagSet{"iface": iface}, "addr", strings.TrimSpace(sp[1]), true)
		}
		return nil
	}, "ipconfig")
}
<|endoftext|>


<commit_before>// build !appengine
package intperm

import (
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"testing"
)

const runs = 10000

func TestPermutation(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "Permutation Suite")
}

var _ = Describe("Permutation", func() {
	var p permutation
	Context("Using a test permutation", func() {
		BeforeEach(func() {
			p = New(42)
		})
		Describe("MapTo", func() {
			It("should work", func() {
				Expect(p.MapTo(42)).To(BeNumerically("==", 4627128764160949907))
			})
			It("should not map to itself", func() {
				for i := uint64(0); i < runs; i++ {
					Expect(p.MapTo(i)).NotTo(BeNumerically("==", i))
				}
			})
		})
		Describe("MapFrom", func() {
			It("should work", func() {
				Expect(p.MapFrom(4627128764160949907)).To(BeNumerically("==", 42))
			})
			It("should be the reverse of MapTo", func() {
				for i := uint64(0); i < runs; i++ {
					Expect(p.MapFrom(p.MapTo(i))).To(BeNumerically("==", i))
				}
			})
		})
	})
})
<commit_msg>fix the tests<commit_after>package intperm_test

import (
	"github.com/attilaolah/intperm.go"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"testing"
)

const runs = 10000

func TestPermutation(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "Permutation Suite")
}

var _ = Describe("Permutation", func() {
	var p intperm.Permutation
	Context("Using a test permutation", func() {
		BeforeEach(func() {
			p = intperm.New(42)
		})
		Describe("MapTo", func() {
			It("should work", func() {
				Expect(p.MapTo(42)).To(BeNumerically("==", 4627128764160949907))
			})
			It("should not map to itself", func() {
				for i := uint64(0); i < runs; i++ {
					Expect(p.MapTo(i)).NotTo(BeNumerically("==", i))
				}
			})
		})
		Describe("MapFrom", func() {
			It("should work", func() {
				Expect(p.MapFrom(4627128764160949907)).To(BeNumerically("==", 42))
			})
			It("should be the reverse of MapTo", func() {
				for i := uint64(0); i < runs; i++ {
					Expect(p.MapFrom(p.MapTo(i))).To(BeNumerically("==", i))
				}
			})
		})
	})
})
<|endoftext|>


<commit_before><commit_msg>More pointerifying<commit_after><|endoftext|>