<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
	"strings"
	"time"
)

var pathToLESS string
var pathToCssMin string
var workingDirectory string

type Job struct {
	name        string
	cmd         *exec.Cmd
	cmd_min     *exec.Cmd
	css_out     string
	css_min_out string
}

type Worker struct {
	jobs    []*Job
	started bool

	max_jobs     int
	running_jobs int
}

var jobs_queue Worker

func main() {
	var err error
	workingDirectory, err = os.Getwd()
	if err != nil {
		log.Fatalf("Can't find the working directory.")
		os.Exit(1)
		return
	}

	flag.StringVar(&pathToLESS, "path", "lessc", "Path to the lessc executable")
	flag.StringVar(&pathToCssMin, "css-min", "", "Path to a CSS minifier which takes an input file and spits out minified CSS in stdout")
	flag.Parse()

	jobs_queue = NewWorker()

	args := flag.Args()
	for _, v := range args {
		compileFromRoot(v)
	}

	running_jobs_chan := make(chan int)
	running_jobs := 1
	for running_jobs > 0 {
		go jobs_queue.Start(running_jobs_chan)
		running_jobs = <-running_jobs_chan
	}

}

func compileFromRoot(dir string) {
	var fq_dir *os.File
	var err error

	if dir[0:1] != "/" {
		fq_dir, err = os.Open(workingDirectory + "/" + dir)
	} else {
		fq_dir, err = os.Open(dir)
	}

	if err != nil {
		fmt.Println(err)
		return
	}

	less_dir, err := os.Open(fq_dir.Name() + "/less")
	if err != nil {
		if os.IsNotExist(err) {
			log.Printf("No /less directory exists at %s", fq_dir.Name())
			return
		} else {
			log.Println(err)
			return
		}
	}

	css_dir, err := os.Open(fq_dir.Name() + "/css")
	if err != nil {
		if os.IsNotExist(err) {
			err = os.Mkdir(fq_dir.Name()+"/css", 0755)
			if err != nil {
				fmt.Println("Can't create css directory")
				return
			} else {
				css_dir, _ = os.Open(fq_dir.Name() + "/css")
			}
		} else {
			log.Println(err)
			return
		}
	}

	compileDirectory("", less_dir, css_dir)
}

func compileDirectory(prefix string, less_dir, css_dir *os.File) {
	files, err := less_dir.Readdir(-1)
	if err != nil {
		log.Panicf("Can't parse %s", less_dir.Name())
	}

	for _, v := range files {
		if v.IsDir() {

			less_deeper, _ := os.Open(less_dir.Name() + "/" + v.Name())
			css_deeper, err := os.Open(css_dir.Name() + "/" + v.Name())
			if err != nil {
				if os.IsNotExist(err) {
					err = os.Mkdir(css_dir.Name()+"/"+v.Name(), 0755)
					if err != nil {
						fmt.Println("Can't create css directory")
						return
					} else {
						css_deeper, _ = os.Open(css_dir.Name() + "/" + v.Name())
					}
				}
			}

			compileDirectory(v.Name()+"/", less_deeper, css_deeper)

		} else if v.Name()[0:1] != "_" {
			compileFile(less_dir, css_dir, v, prefix+v.Name())
		}
	}
}

func compileFile(less_dir, css_dir *os.File, less_file os.FileInfo, log_text string) {

	var cmd_min *exec.Cmd
	if pathToCssMin == "" {
		cmd_min = exec.Command(pathToLESS, "-x", less_dir.Name()+"/"+less_file.Name())
	} else {
		cmd_min = exec.Command(pathToCssMin, css_dir.Name()+"/"+strings.Replace(less_file.Name(), ".less", ".css", 1))
	}

	jobs_queue.Add(Job{
		name:        log_text,
		cmd:         exec.Command(pathToLESS, less_dir.Name()+"/"+less_file.Name()),
		cmd_min:     cmd_min,
		css_out:     css_dir.Name() + "/" + strings.Replace(less_file.Name(), ".less", ".css", 1),
		css_min_out: css_dir.Name() + "/" + strings.Replace(less_file.Name(), ".less", ".min.css", 1),
	})

}

func NewWorker() Worker {
	w := Worker{
		started:      false,
		max_jobs:     3,
		running_jobs: 0,
	}

	return w
}

func (w *Worker) Add(j Job) {
	w.jobs = append(w.jobs, &j)
}

func (w *Worker) Start(return_ch chan int) {
	if !w.started {
		w.started = true

		for len(w.jobs) > 0 {
			ch := make(chan bool)
			go w.runNextJob(ch)

			result := <-ch

			if !result {
				time.Sleep(100 * time.Millisecond)
			}
		}

		w.started = false
	}

	return_ch <- w.running_jobs
}

func (w *Worker) getNextJob() *Job {
	j := w.jobs[0]
	w.jobs = w.jobs[1:len(w.jobs)]
	return j
}

func (w *Worker) runNextJob(ch chan bool) {
	var job_ch chan int

	if w.running_jobs < w.max_jobs {
		ch <- true

		job := w.getNextJob()
		job_ch = make(chan int)
		w.running_jobs++
		go job.Run(job_ch)
	} else {
		ch <- false
	}

	<-job_ch
	w.running_jobs--
}

func (j *Job) Run(ch chan int) {

	fmt.Printf("%s\n", j.name)

	(func() {
		result, err := j.cmd.Output()
		if err != nil {
			fmt.Errorf("Command error: %s\n", err)
		} else {
			dest_file, err := os.OpenFile(j.css_out, os.O_RDWR+os.O_TRUNC+os.O_CREATE, 0644)
			if err != nil {
				fmt.Errorf("File output error: %s\n", err)
			} else {
				dest_file.Write(result)
			}
		}
	})()

	(func() {
		result, err := j.cmd_min.Output()
		if err != nil {
			fmt.Errorf("Command error: %s\n", err)
		} else {
			dest_file, err := os.OpenFile(j.css_min_out, os.O_RDWR+os.O_TRUNC+os.O_CREATE, 0644)
			if err != nil {
				fmt.Errorf("File output error: %s\n", err)
			} else {
				dest_file.Write(result)
			}
		}
	})()

	ch <- 1

}
<commit_msg>Renamed some methods<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
	"strings"
	"time"
)

var pathToLESS string
var pathToCssMin string
var workingDirectory string

type Job struct {
	name        string
	cmd         *exec.Cmd
	cmd_min     *exec.Cmd
	css_out     string
	css_min_out string
}

type Worker struct {
	jobs    []*Job
	started bool

	max_jobs     int
	running_jobs int
}

var jobs_queue Worker

func main() {
	var err error
	workingDirectory, err = os.Getwd()
	if err != nil {
		log.Fatalf("Can't find the working directory.")
		os.Exit(1)
		return
	}

	flag.StringVar(&pathToLESS, "path", "lessc", "Path to the lessc executable")
	flag.StringVar(&pathToCssMin, "css-min", "", "Path to a CSS minifier which takes an input file and spits out minified CSS in stdout")
	flag.Parse()

	jobs_queue = NewWorker()

	args := flag.Args()
	for _, v := range args {
		compileFromRoot(v)
	}

	running_jobs_chan := make(chan int)
	running_jobs := 1
	for running_jobs > 0 {
		go jobs_queue.Start(running_jobs_chan)
		running_jobs = <-running_jobs_chan
	}

}

func compileFromRoot(dir string) {
	var fq_dir *os.File
	var err error

	if dir[0:1] != "/" {
		fq_dir, err = os.Open(workingDirectory + "/" + dir)
	} else {
		fq_dir, err = os.Open(dir)
	}

	if err != nil {
		fmt.Println(err)
		return
	}

	less_dir, err := os.Open(fq_dir.Name() + "/less")
	if err != nil {
		if os.IsNotExist(err) {
			log.Printf("No /less directory exists at %s", fq_dir.Name())
			return
		} else {
			log.Println(err)
			return
		}
	}

	css_dir, err := os.Open(fq_dir.Name() + "/css")
	if err != nil {
		if os.IsNotExist(err) {
			err = os.Mkdir(fq_dir.Name()+"/css", 0755)
			if err != nil {
				fmt.Println("Can't create css directory")
				return
			} else {
				css_dir, _ = os.Open(fq_dir.Name() + "/css")
			}
		} else {
			log.Println(err)
			return
		}
	}

	addDirectory("", less_dir, css_dir)
}

func addDirectory(prefix string, less_dir, css_dir *os.File) {
	files, err := less_dir.Readdir(-1)
	if err != nil {
		log.Panicf("Can't parse %s", less_dir.Name())
	}

	for _, v := range files {
		if v.IsDir() {

			less_deeper, _ := os.Open(less_dir.Name() + "/" + v.Name())
			css_deeper, err := os.Open(css_dir.Name() + "/" + v.Name())
			if err != nil {
				if os.IsNotExist(err) {
					err = os.Mkdir(css_dir.Name()+"/"+v.Name(), 0755)
					if err != nil {
						fmt.Println("Can't create css directory")
						return
					} else {
						css_deeper, _ = os.Open(css_dir.Name() + "/" + v.Name())
					}
				}
			}

			addDirectory(v.Name()+"/", less_deeper, css_deeper)

		} else if v.Name()[0:1] != "_" {
			addFile(less_dir, css_dir, v, prefix+v.Name())
		}
	}
}

func addFile(less_dir, css_dir *os.File, less_file os.FileInfo, log_text string) {

	var cmd_min *exec.Cmd
	if pathToCssMin == "" {
		cmd_min = exec.Command(pathToLESS, "-x", less_dir.Name()+"/"+less_file.Name())
	} else {
		cmd_min = exec.Command(pathToCssMin, css_dir.Name()+"/"+strings.Replace(less_file.Name(), ".less", ".css", 1))
	}

	jobs_queue.Add(Job{
		name:        log_text,
		cmd:         exec.Command(pathToLESS, less_dir.Name()+"/"+less_file.Name()),
		cmd_min:     cmd_min,
		css_out:     css_dir.Name() + "/" + strings.Replace(less_file.Name(), ".less", ".css", 1),
		css_min_out: css_dir.Name() + "/" + strings.Replace(less_file.Name(), ".less", ".min.css", 1),
	})

}

func NewWorker() Worker {
	w := Worker{
		started:      false,
		max_jobs:     3,
		running_jobs: 0,
	}

	return w
}

func (w *Worker) Add(j Job) {
	w.jobs = append(w.jobs, &j)
}

func (w *Worker) Start(return_ch chan int) {
	if !w.started {
		w.started = true

		for len(w.jobs) > 0 {
			ch := make(chan bool)
			go w.runNextJob(ch)

			result := <-ch

			if !result {
				time.Sleep(100 * time.Millisecond)
			}
		}

		w.started = false
	}

	return_ch <- w.running_jobs
}

func (w *Worker) getNextJob() *Job {
	j := w.jobs[0]
	w.jobs = w.jobs[1:len(w.jobs)]
	return j
}

func (w *Worker) runNextJob(ch chan bool) {
	var job_ch chan int

	if w.running_jobs < w.max_jobs {
		ch <- true

		job := w.getNextJob()
		job_ch = make(chan int)
		w.running_jobs++
		go job.Run(job_ch)
	} else {
		ch <- false
	}

	<-job_ch
	w.running_jobs--
}

func (j *Job) Run(ch chan int) {

	fmt.Printf("%s\n", j.name)

	(func() {
		result, err := j.cmd.Output()
		if err != nil {
			fmt.Errorf("Command error: %s\n", err)
		} else {
			dest_file, err := os.OpenFile(j.css_out, os.O_RDWR+os.O_TRUNC+os.O_CREATE, 0644)
			if err != nil {
				fmt.Errorf("File output error: %s\n", err)
			} else {
				dest_file.Write(result)
			}
		}
	})()

	(func() {
		result, err := j.cmd_min.Output()
		if err != nil {
			fmt.Errorf("Command error: %s\n", err)
		} else {
			dest_file, err := os.OpenFile(j.css_min_out, os.O_RDWR+os.O_TRUNC+os.O_CREATE, 0644)
			if err != nil {
				fmt.Errorf("File output error: %s\n", err)
			} else {
				dest_file.Write(result)
			}
		}
	})()

	ch <- 1

}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"

	log "github.com/Sirupsen/logrus"
)

func main() {
	flag.Parse()
	if printVersion {
		fmt.Printf("confd %s\n", Version)
		os.Exit(0)
	}
	if err := initConfig(); err != nil {
		log.Fatal(err.Error())
	}
	log.Info("Starting batond")

	sanityCheck()
}
<commit_msg>main.go: get hostname<commit_after>package main

import (
	"flag"
	"fmt"
	"os"

	log "github.com/Sirupsen/logrus"
)

func main() {
	// parse cli flags
	flag.Parse()

	// if we are just supposed to print the version, then do so
	if printVersion {
		fmt.Printf("confd %s\n", Version)
		os.Exit(0)
	}

	// load configuration
	if err := initConfig(); err != nil {
		log.Fatal(err.Error())
	}

	// get the hostname
	hostname, err := os.Hostname()
	if err != nil {
		log.Fatal(err.Error())
	}

	// check our sanity
	sanityCheck()

	log.WithField("hostname", hostname).Info("Starting batond")
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"net"
	"os/exec"
	"strings"
	"time"
)

const (
	Interface = "en0"
)

type Host struct {
	IP       string
	MAC      string
	Hostname string
	Data     []string
}

func (h Host) String() string {
	return fmt.Sprintf("Host %s has IP %s, MAC: %s", h.Hostname, h.IP, h.MAC)
}

func handleErr(err error) {
	log.Println("Error: ", err)
}

func getIPAndMAC(line string) (string, string) {
	lines := strings.Split(line, "(")
	tmp := strings.Split(lines[1], ")")
	IP := tmp[0]
	MAC := strings.Split(tmp[1], " ")[2]
	return IP, MAC
}

func arpEntries() []Host {
	var hosts []Host
	out, err := exec.Command("arp", "-na").Output()
	if err != nil {
		handleErr(err)
	}
	strOut := string(out)
	lines := strings.Split(strOut, "\n")
	for _, line := range lines {
		if strings.Contains(line, Interface) {
			h := Host{}
			h.IP, h.MAC = getIPAndMAC(line)
			hosts = append(hosts, h)
		}
	}
	return hosts
}

func display(hs []Host) {
	for idx, h := range hs {
		log.Printf("%d. %s", idx+1, h)
	}
	return
}

func myLANIP() (string, error) {
	ifis, err := net.Interfaces()
	if err != nil {
		handleErr(err)
	}
	for _, ifi := range ifis {
		if ifi.Name == Interface {
			addrs, err := ifi.Addrs()
			if err != nil {
				handleErr(err)
			}
			log.Println(addrs)
			for _, addr := range addrs {
				ip, _, err := net.ParseCIDR(addr.String())
				if err != nil {
					handleErr(err)
					continue
				}
				if ip.To4() != nil {
					return addr.String(), nil
				}
			}
		}
	}
	return "", err
}

func nmapScanAll() {
	myIP, err := myLANIP()
	handleErr(err)
	out, err := exec.Command("nmap", "-A", "-T4", myIP).Output()
	handleErr(err)
	log.Println(string(out))
}
func nmapEntries() {
	myIP, err := myLANIP()
	handleErr(err)
	out, err := exec.Command("nmap", "-sP", "-PA21,22,25,3389", myIP).Output()
	handleErr(err)
	log.Println(string(out))
}

type Event struct {
	When time.Time
	Up   bool
}

func (e Event) String() string {
	var s string
	if e.Up {
		s = "UP"
	} else {
		s = "DOWN"
	}

	return fmt.Sprintf("Event %s at %s", s, e.When)
}
func checkPing(h Host) Event {
	out, err := exec.Command("nmap", "-sP", h.IP).Output()
	if err == nil {
		if strings.Contains(string(out), "1 host up") {
			return Event{When: time.Now(), Up: true}
		}
	}
	return Event{When: time.Now(), Up: false}
}

func checkAll(hosts []Host, ch chan Event, chost chan Host) {
	for _, host := range hosts {
		ch <- checkPing(host)
		chost <- host
	}
	close(ch)
	close(chost)
}

func main() {
	hosts := arpEntries()
	ch := make(chan Event)
	chost := make(chan Host)
	go checkAll(hosts, ch, chost)
	for i := range ch {
		log.Println(<-chost, i)
	}

	// TODO add nmap entries to ping check
	nmapEntries()

	// For every 5 mins, run a check and save result to db.
	// Loop over all host in buckets and all host that nmap can ping
	// If a host change its state (leaving), save data to db and report.
	// If host is new, add it
	// If host does not change, do nothing
	nmapScanAll()
}
<commit_msg>use constant<commit_after>package main

import (
	"fmt"
	"log"
	"net"
	"os/exec"
	"strings"
	"time"
)

const (
	Interface  = "en0"
	statusUp   = "UP"
	statusDown = "DOWN"
)

type Host struct {
	IP       string
	MAC      string
	Hostname string
	Data     []string
}

func (h Host) String() string {
	return fmt.Sprintf("Host %s has IP %s, MAC: %s", h.Hostname, h.IP, h.MAC)
}

func handleErr(err error) {
	log.Println("Error: ", err)
}

func getIPAndMAC(line string) (string, string) {
	lines := strings.Split(line, "(")
	tmp := strings.Split(lines[1], ")")
	IP := tmp[0]
	MAC := strings.Split(tmp[1], " ")[2]
	return IP, MAC
}

func arpEntries() []Host {
	var hosts []Host
	out, err := exec.Command("arp", "-na").Output()
	if err != nil {
		handleErr(err)
	}
	strOut := string(out)
	lines := strings.Split(strOut, "\n")
	for _, line := range lines {
		if strings.Contains(line, Interface) {
			h := Host{}
			h.IP, h.MAC = getIPAndMAC(line)
			hosts = append(hosts, h)
		}
	}
	return hosts
}

func display(hs []Host) {
	for idx, h := range hs {
		log.Printf("%d. %s", idx+1, h)
	}
	return
}

func myLANIP() (string, error) {
	ifis, err := net.Interfaces()
	if err != nil {
		handleErr(err)
	}
	for _, ifi := range ifis {
		if ifi.Name == Interface {
			addrs, err := ifi.Addrs()
			if err != nil {
				handleErr(err)
			}
			log.Println(addrs)
			for _, addr := range addrs {
				ip, _, err := net.ParseCIDR(addr.String())
				if err != nil {
					handleErr(err)
					continue
				}
				if ip.To4() != nil {
					return addr.String(), nil
				}
			}
		}
	}
	return "", err
}

func nmapScanAll() {
	myIP, err := myLANIP()
	handleErr(err)
	out, err := exec.Command("nmap", "-A", "-T4", myIP).Output()
	handleErr(err)
	log.Println(string(out))
}
func nmapEntries() {
	myIP, err := myLANIP()
	handleErr(err)
	out, err := exec.Command("nmap", "-sP", "-PA21,22,25,3389", myIP).Output()
	handleErr(err)
	log.Println(string(out))
}

type Event struct {
	When time.Time
	Up   bool
}

func (e Event) String() string {
	var s string
	if e.Up {
		s = statusUp
	} else {
		s = statusDown
	}

	return fmt.Sprintf("Event %s at %s", s, e.When)
}
func checkPing(h Host) Event {
	out, err := exec.Command("nmap", "-sP", h.IP).Output()
	if err == nil {
		if strings.Contains(string(out), "1 host up") {
			return Event{When: time.Now(), Up: true}
		}
	}
	return Event{When: time.Now(), Up: false}
}

func checkAll(hosts []Host, ch chan Event, chost chan Host) {
	for _, host := range hosts {
		ch <- checkPing(host)
		chost <- host
	}
	close(ch)
	close(chost)
}

func main() {
	hosts := arpEntries()
	ch := make(chan Event)
	chost := make(chan Host)
	go checkAll(hosts, ch, chost)
	for i := range ch {
		log.Println(<-chost, i)
	}

	// TODO add nmap entries to ping check
	nmapEntries()

	// For every 5 mins, run a check and save result to db.
	// Loop over all host in buckets and all host that nmap can ping
	// If a host change its state (leaving), save data to db and report.
	// If host is new, add it
	// If host does not change, do nothing
	nmapScanAll()
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"os"

	"github.com/joho/godotenv"
	"github.com/Sirupsen/logrus"
	"github.com/urfave/cli"
)

var revision string // build number set at compile-time

func main() {
	app := cli.NewApp()
	app.Name = "terraform plugin"
	app.Usage = "terraform plugin"
	app.Action = run
	app.Version = revision
	app.Flags = []cli.Flag{

		//
		// plugin args
		//

		cli.BoolFlag{
			Name: "terraform.plan",
			Usage: "calculates a plan but does NOT apply it",
			EnvVar: "PLUGIN_PLAN",
		},
		cli.StringFlag{
			Name: "terraform.remote",
			Usage: "contains the configuration for the Terraform remote state tracking",
			EnvVar: "PLUGIN_REMOTE",
		},
		cli.StringFlag{
			Name: "terraform.vars",
			Usage: "a map of variables to pass to the Terraform `plan` and `apply` commands. Each value is passed as a `<key>=<value>` option",
			EnvVar: "PLUGIN_VARS",
		},
		cli.StringFlag{
			Name: "terraform.secrets",
			Usage: "a map of secrets to pass to the Terraform `plan` and `apply` commands. Each value is passed as a `<key>=<ENV>` option",
			EnvVar: "PLUGIN_SECRETS",
		},
		cli.StringFlag{
			Name: "terraform.ca_cert",
			Usage: "ca cert to add to your environment to allow terraform to use internal/private resources",
			EnvVar: "PLUGIN_CA_CERT",
		},
		cli.BoolFlag{
			Name: "terraform.sensitive",
			Usage: "whether or not to suppress terraform commands to stdout",
			EnvVar: "PLUGIN_SENSITIVE",
		},
		cli.StringFlag{
			Name: "terraform.role_arn_to_assume",
			Usage: "A role to assume before running the terraform commands",
			EnvVar: "PLUGIN_ROLE_ARN_TO_ASSUME",
		},
		cli.StringFlag{
			Name: "terraform.root_dir",
			Usage: "The root directory where the terraform files live. When unset, the top level directory will be assumed",
			EnvVar: "PLUGIN_ROOT_DIR",
		},
		cli.IntFlag{
			Name: "terraform.parallelism",
			Usage: "The number of concurrent operations as Terraform walks its graph",
			EnvVar: "PLUGIN_PARALLELISM",
		},

		cli.StringFlag{
			Name:	"env-file",
			Usage: "source env file",
		},
	}

	if err := app.Run(os.Args); err != nil {
		logrus.Fatal(err)
	}
}

func run(c *cli.Context) error {
	logrus.WithFields(logrus.Fields{
		"Revision": revision,
	}).Info("Drone Terraform Plugin Version")

	if c.String("env-file") != "" {
		_ = godotenv.Load(c.String("env-file"))
	}

	remote := Remote{}
	json.Unmarshal([]byte(c.String("terraform.remote")), &remote)

	var vars map[string]string
	if err := json.Unmarshal([]byte(c.String("terraform.vars")), &vars); err != nil {
		panic(err)
	}
	var secrets map[string]string
	if err := json.Unmarshal([]byte(c.String("terraform.secrets")), &secrets); err != nil {
		panic(err)
	}

	plugin := Plugin{
		Config: Config{
			Remote:      remote,
			Plan:        c.Bool("terraform.plan"),
			Vars:        vars,
			Secrets:     secrets,
			Cacert:      c.String("terraform.ca_cert"),
			Sensitive:   c.Bool("terraform.sensitive"),
			RoleARN:     c.String("terraform.role_arn_to_assume"),
			RootDir:     c.String("terraform.root_dir"),
			Parallelism: c.Int("terraform.parallelism"),
		},
	}

	return plugin.Exec()
}
<commit_msg>Allow 'secrets' and 'vars' to be blank<commit_after>package main

import (
	"encoding/json"
	"os"

	"github.com/joho/godotenv"
	"github.com/Sirupsen/logrus"
	"github.com/urfave/cli"
)

var revision string // build number set at compile-time

func main() {
	app := cli.NewApp()
	app.Name = "terraform plugin"
	app.Usage = "terraform plugin"
	app.Action = run
	app.Version = revision
	app.Flags = []cli.Flag{

		//
		// plugin args
		//

		cli.BoolFlag{
			Name: "terraform.plan",
			Usage: "calculates a plan but does NOT apply it",
			EnvVar: "PLUGIN_PLAN",
		},
		cli.StringFlag{
			Name: "terraform.remote",
			Usage: "contains the configuration for the Terraform remote state tracking",
			EnvVar: "PLUGIN_REMOTE",
		},
		cli.StringFlag{
			Name: "terraform.vars",
			Usage: "a map of variables to pass to the Terraform `plan` and `apply` commands. Each value is passed as a `<key>=<value>` option",
			EnvVar: "PLUGIN_VARS",
		},
		cli.StringFlag{
			Name: "terraform.secrets",
			Usage: "a map of secrets to pass to the Terraform `plan` and `apply` commands. Each value is passed as a `<key>=<ENV>` option",
			EnvVar: "PLUGIN_SECRETS",
		},
		cli.StringFlag{
			Name: "terraform.ca_cert",
			Usage: "ca cert to add to your environment to allow terraform to use internal/private resources",
			EnvVar: "PLUGIN_CA_CERT",
		},
		cli.BoolFlag{
			Name: "terraform.sensitive",
			Usage: "whether or not to suppress terraform commands to stdout",
			EnvVar: "PLUGIN_SENSITIVE",
		},
		cli.StringFlag{
			Name: "terraform.role_arn_to_assume",
			Usage: "A role to assume before running the terraform commands",
			EnvVar: "PLUGIN_ROLE_ARN_TO_ASSUME",
		},
		cli.StringFlag{
			Name: "terraform.root_dir",
			Usage: "The root directory where the terraform files live. When unset, the top level directory will be assumed",
			EnvVar: "PLUGIN_ROOT_DIR",
		},
		cli.IntFlag{
			Name: "terraform.parallelism",
			Usage: "The number of concurrent operations as Terraform walks its graph",
			EnvVar: "PLUGIN_PARALLELISM",
		},

		cli.StringFlag{
			Name:	"env-file",
			Usage: "source env file",
		},
	}

	if err := app.Run(os.Args); err != nil {
		logrus.Fatal(err)
	}
}

func run(c *cli.Context) error {
	logrus.WithFields(logrus.Fields{
		"Revision": revision,
	}).Info("Drone Terraform Plugin Version")

	if c.String("env-file") != "" {
		_ = godotenv.Load(c.String("env-file"))
	}

	remote := Remote{}
	json.Unmarshal([]byte(c.String("terraform.remote")), &remote)

	var vars map[string]string
	if c.String("terraform.vars") != "" {
		if err := json.Unmarshal([]byte(c.String("terraform.vars")), &vars); err != nil {
			panic(err)
		}
	}
	var secrets map[string]string
	if c.String("terraform.secrets") != "" {
		if err := json.Unmarshal([]byte(c.String("terraform.secrets")), &secrets); err != nil {
			panic(err)
		}
	}

	plugin := Plugin{
		Config: Config{
			Remote:      remote,
			Plan:        c.Bool("terraform.plan"),
			Vars:        vars,
			Secrets:     secrets,
			Cacert:      c.String("terraform.ca_cert"),
			Sensitive:   c.Bool("terraform.sensitive"),
			RoleARN:     c.String("terraform.role_arn_to_assume"),
			RootDir:     c.String("terraform.root_dir"),
			Parallelism: c.Int("terraform.parallelism"),
		},
	}

	return plugin.Exec()
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"github.com/codegangsta/cli"
	"github.com/codegangsta/envy/lib"
	"github.com/codegangsta/gin/lib"

	"log"
	"os"
	"os/signal"
	"path/filepath"
	"strconv"
	"syscall"
	"time"
)

var (
	startTime  = time.Now()
	logger     = log.New(os.Stdout, "[gin] ", 0)
	buildError error
)

func main() {
	app := cli.NewApp()
	app.Name = "gin"
	app.Usage = "A live reload utility for Go web applications."
	app.Action = MainAction
	app.Flags = []cli.Flag{
		cli.IntFlag{"port,p", 3000, "port for the proxy server"},
		cli.IntFlag{"appPort,a", 3001, "port for the Go web server"},
		cli.StringFlag{"bin,b", "gin-bin", "name of generated binary file"},
		cli.StringFlag{"path,t", ".", "Path to watch files from"},
	}
	app.Commands = []cli.Command{
		{
			Name:      "run",
			ShortName: "r",
			Usage:     "Run the gin proxy in the current working directory",
			Action:    MainAction,
		},
		{
			Name:      "env",
			ShortName: "e",
			Usage:     "Display environment variables set by the .env file",
			Action:    EnvAction,
		},
	}

	app.Run(os.Args)
}

func MainAction(c *cli.Context) {
	port := c.GlobalInt("port")
	appPort := strconv.Itoa(c.GlobalInt("appPort"))

	// Bootstrap the environment
	envy.Bootstrap()

	// Set the PORT env
	os.Setenv("PORT", appPort)

	wd, err := os.Getwd()
	if err != nil {
		logger.Fatal(err)
	}

	builder := gin.NewBuilder(".", c.GlobalString("bin"))
	runner := gin.NewRunner(filepath.Join(wd, builder.Binary()), c.Args()...)
	runner.SetWriter(os.Stdout)
	proxy := gin.NewProxy(builder, runner)

	config := &gin.Config{
		Port:    port,
		ProxyTo: "http://localhost:" + appPort,
	}

	err = proxy.Run(config)
	if err != nil {
		logger.Fatal(err)
	}

	logger.Printf("listening on port %d\n", port)

	shutdown(runner)

	// build right now
	build(builder, logger)

	// scan for changes
	scanChanges(c.GlobalString("path"), func(path string) {
		runner.Kill()
		build(builder, logger)
	})
}

func EnvAction(c *cli.Context) {
	// Bootstrap the environment
	env, err := envy.Bootstrap()
	if err != nil {
		logger.Fatalln(err)
	}

	for k, v := range env {
		fmt.Printf("%s: %s\n", k, v)
	}

}

func build(builder gin.Builder, logger *log.Logger) {
	err := builder.Build()
	if err != nil {
		buildError = err
		logger.Println("ERROR! Build failed.")
		fmt.Println(builder.Errors())
	} else {
		// print success only if there were errors before
		if buildError != nil {
			logger.Println("Build Successful")
		}
		buildError = nil
	}

	time.Sleep(100 * time.Millisecond)
}

type scanCallback func(path string)

func scanChanges(watchPath string, cb scanCallback) {
	for {
		filepath.Walk(watchPath, func(path string, info os.FileInfo, err error) error {
			if path == ".git" {
				return filepath.SkipDir
			}

			// ignore hidden files
			if filepath.Base(path)[0] == '.' {
				return nil
			}

			if filepath.Ext(path) == ".go" && info.ModTime().After(startTime) {
				cb(path)
				startTime = time.Now()
				return errors.New("done")
			}

			return nil
		})
		time.Sleep(500 * time.Millisecond)
	}
}

func shutdown(runner gin.Runner) {
	c := make(chan os.Signal, 2)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	go func() {
		s := <-c
		log.Println("Got signal: ", s)
		err := runner.Kill()
		if err != nil {
			log.Print("Error killing: ", err)
		}
		os.Exit(1)
	}()
}
<commit_msg>add --immediate, -i option to immediately run the web server after it's built<commit_after>package main

import (
	"errors"
	"fmt"
	"github.com/codegangsta/cli"
	"github.com/codegangsta/envy/lib"
	"github.com/codegangsta/gin/lib"

	"log"
	"os"
	"os/signal"
	"path/filepath"
	"strconv"
	"syscall"
	"time"
)

var (
	startTime  = time.Now()
	logger     = log.New(os.Stdout, "[gin] ", 0)
	immediate  = false
	buildError error
)

func main() {
	app := cli.NewApp()
	app.Name = "gin"
	app.Usage = "A live reload utility for Go web applications."
	app.Action = MainAction
	app.Flags = []cli.Flag{
		cli.IntFlag{"port,p", 3000, "port for the proxy server"},
		cli.IntFlag{"appPort,a", 3001, "port for the Go web server"},
		cli.StringFlag{"bin,b", "gin-bin", "name of generated binary file"},
		cli.StringFlag{"path,t", ".", "Path to watch files from"},
		cli.BoolFlag{"immediate,i", "run the server immediately after it's built"},
	}
	app.Commands = []cli.Command{
		{
			Name:      "run",
			ShortName: "r",
			Usage:     "Run the gin proxy in the current working directory",
			Action:    MainAction,
		},
		{
			Name:      "env",
			ShortName: "e",
			Usage:     "Display environment variables set by the .env file",
			Action:    EnvAction,
		},
	}

	app.Run(os.Args)
}

func MainAction(c *cli.Context) {
	port := c.GlobalInt("port")
	appPort := strconv.Itoa(c.GlobalInt("appPort"))
	immediate = c.GlobalBool("immediate")

	// Bootstrap the environment
	envy.Bootstrap()

	// Set the PORT env
	os.Setenv("PORT", appPort)

	wd, err := os.Getwd()
	if err != nil {
		logger.Fatal(err)
	}

	builder := gin.NewBuilder(".", c.GlobalString("bin"))
	runner := gin.NewRunner(filepath.Join(wd, builder.Binary()), c.Args()...)
	runner.SetWriter(os.Stdout)
	proxy := gin.NewProxy(builder, runner)

	config := &gin.Config{
		Port:    port,
		ProxyTo: "http://localhost:" + appPort,
	}

	err = proxy.Run(config)
	if err != nil {
		logger.Fatal(err)
	}

	logger.Printf("listening on port %d\n", port)

	shutdown(runner)

	// build right now
	build(builder, runner, logger)

	// scan for changes
	scanChanges(c.GlobalString("path"), func(path string) {
		runner.Kill()
		build(builder, runner, logger)
	})
}

func EnvAction(c *cli.Context) {
	// Bootstrap the environment
	env, err := envy.Bootstrap()
	if err != nil {
		logger.Fatalln(err)
	}

	for k, v := range env {
		fmt.Printf("%s: %s\n", k, v)
	}

}

func build(builder gin.Builder, runner gin.Runner, logger *log.Logger) {
	err := builder.Build()
	if err != nil {
		buildError = err
		logger.Println("ERROR! Build failed.")
		fmt.Println(builder.Errors())
	} else {
		// print success only if there were errors before
		if buildError != nil {
			logger.Println("Build Successful")
		}
		buildError = nil
		if immediate {
			runner.Run()
		}
	}

	time.Sleep(100 * time.Millisecond)
}

type scanCallback func(path string)

func scanChanges(watchPath string, cb scanCallback) {
	for {
		filepath.Walk(watchPath, func(path string, info os.FileInfo, err error) error {
			if path == ".git" {
				return filepath.SkipDir
			}

			// ignore hidden files
			if filepath.Base(path)[0] == '.' {
				return nil
			}

			if filepath.Ext(path) == ".go" && info.ModTime().After(startTime) {
				cb(path)
				startTime = time.Now()
				return errors.New("done")
			}

			return nil
		})
		time.Sleep(500 * time.Millisecond)
	}
}

func shutdown(runner gin.Runner) {
	c := make(chan os.Signal, 2)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	go func() {
		s := <-c
		log.Println("Got signal: ", s)
		err := runner.Kill()
		if err != nil {
			log.Print("Error killing: ", err)
		}
		os.Exit(1)
	}()
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"os/signal"
	"sync"
	"syscall"

	"github.com/Sirupsen/logrus"
)

const (
	HTTPEnableFlag  = "http-enable"
	HTTPPortFlag    = "http-port"
	HTTPLogPathFlag = "http-log-path"
)

var (
	Log = logrus.New()

	httpEnable = flag.Bool(HTTPEnableFlag, false, "Enable HTTP server.")
	httpPort   = flag.Int(HTTPPortFlag, 8001, "HTTP server listening port.")

	stopOnce sync.Once
	wg       sync.WaitGroup
)

func withLogging(f func()) {
	defer func() {
		if r := recover(); r != nil {
			err := fmt.Errorf("Recovered from panic(%+v)", r)

			Log.WithField("error", err).Panicf("Stopped with panic: %s", err.Error())
		}
	}()

	f()
}

func main() {
	// Set the log output to stderr since communication with ExaBGP is done via stdout.
	Log.Out = os.Stderr

	flag.Parse()

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	go func() {
		for sig := range c {
			Log.WithField("signal", sig).Infof("Signalled. Shutting down.")

			stopOnce.Do(func() { shutdown(0) })
		}
	}()

	go withLogging(readStdin)

	// If HTTP is enable start the HTTP server (which blocks).
	if *httpEnable {
		if err := <-StartHTTPServer(*httpPort); err != nil {
			Log.WithField("error", err).Fatal("Error starting HTTP server.")
		}

		return
	}

	// If HTTP is not enabled we need to block with a wait on a WaitGroup.
	wg.Add(1)
	wg.Wait()
}

func shutdown(code int) {
	Log.WithField("code", code).Infof("Stopping.")

	// If HTTP is enabled we must exit in order to cause the HTTP server to shutdown.
	if *httpEnable {
		os.Exit(0)
	}

	wg.Done()
}
<commit_msg>Remove unneeded constant HTTPLogPathFlag.<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
	"os/signal"
	"sync"
	"syscall"

	"github.com/Sirupsen/logrus"
)

const (
	HTTPEnableFlag = "http-enable"
	HTTPPortFlag   = "http-port"
)

var (
	Log = logrus.New()

	httpEnable = flag.Bool(HTTPEnableFlag, false, "Enable HTTP server.")
	httpPort   = flag.Int(HTTPPortFlag, 8001, "HTTP server listening port.")

	stopOnce sync.Once
	wg       sync.WaitGroup
)

func withLogging(f func()) {
	defer func() {
		if r := recover(); r != nil {
			err := fmt.Errorf("Recovered from panic(%+v)", r)

			Log.WithField("error", err).Panicf("Stopped with panic: %s", err.Error())
		}
	}()

	f()
}

func main() {
	// Set the log output to stderr since communication with ExaBGP is done via stdout.
	Log.Out = os.Stderr

	flag.Parse()

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	go func() {
		for sig := range c {
			Log.WithField("signal", sig).Infof("Signalled. Shutting down.")

			stopOnce.Do(func() { shutdown(0) })
		}
	}()

	go withLogging(readStdin)

	// If HTTP is enable start the HTTP server (which blocks).
	if *httpEnable {
		if err := <-StartHTTPServer(*httpPort); err != nil {
			Log.WithField("error", err).Fatal("Error starting HTTP server.")
		}

		return
	}

	// If HTTP is not enabled we need to block with a wait on a WaitGroup.
	wg.Add(1)
	wg.Wait()
}

func shutdown(code int) {
	Log.WithField("code", code).Infof("Stopping.")

	// If HTTP is enabled we must exit in order to cause the HTTP server to shutdown.
	if *httpEnable {
		os.Exit(0)
	}

	wg.Done()
}
<|endoftext|>


<commit_before>/**
* Welcome to Beacon; an application for keeping teams in sync with breaking changes in their codebases.
* This application is built with Golang! The Maintainer (yours truly) has not written much Golang so
* Refactors, tips, and working things out together is greatly appreciated.
* Please refer to our github issues page for working on this project! https://github.com/the-heap/beacon/issues
*
*** ======== Useful links, Resources, etc: ============ ***
	* Join our Slack group: https://slackin-onxcmypksl.now.sh/ <-- might take bit of time load before you can register. ⏲
	* Learn about the Heap: http://theheap.us/page/about/ 🎒
	* Resources for contributing to open source with The Heap: https://theheap.us/page/resources/ 🎩
	* Golang tips: https://gobyexample.com/ 🐹
	* Podcast about Golang if you're interested: http://gotime.fm/ 🎧
*** =================================================== ***
*
*/

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"path"
)

// ============================
// Types
// ============================

// BeaconLog represents the entire blob of json from the beacon file
type BeaconLog struct {
	Logs []Log
}

// Log is a single entry in the BeaconLog;
//
// _Example_: a user submits a breaking change to the database,
// in which they would fill out all the info in this struct.
type Log struct {
	ID      string
	Date    string
	Email   string
	Author  string
	Message string
}

// ============================
// Vars and Constants
// ============================

var logFilePath = path.Join(os.Getenv("HOME"), "/Dropbox/The Heap/Beacon/beacon_log.json")
var beaconLogData BeaconLog

// ============================
// Helpers
// ============================

func checkError(e error) {
	if e != nil {
		panic(e)
	}
}

// ============================
// MAIN!
// ============================
func main() {

	// read JSON file from disk
	beaconLogFile, err := ioutil.ReadFile(path.Join(logFilePath))
	checkError(err)

	// unmarshal json and store it in the pointer to beaconLogData {?}
	// NOTE: figure out if you can use `checkError` here; don't yet understand golang's idiomatic errors handling.
	if err := json.Unmarshal(beaconLogFile, &beaconLogData); err != nil {
		panic(err)
	}

	// an example of accessing some unmarshalled json data.
	fmt.Println(beaconLogData.Logs[0].Message)
}
<commit_msg>create a rudimentary print-log-to-terminal function<commit_after>/**
* Welcome to Beacon; an application for keeping teams in sync with breaking changes in their codebases.
* This application is built with Golang! The Maintainer (yours truly) has not written much Golang so
* Refactors, tips, and working things out together is greatly appreciated.
* Please refer to our github issues page for working on this project! https://github.com/the-heap/beacon/issues
*
*** ======== Useful links, Resources, etc: ============ ***
	* Join our Slack group: https://slackin-onxcmypksl.now.sh/ <-- might take bit of time load before you can register. ⏲
	* Learn about the Heap: http://theheap.us/page/about/ 🎒
	* Resources for contributing to open source with The Heap: https://theheap.us/page/resources/ 🎩
	* Golang tips: https://gobyexample.com/ 🐹
	* Podcast about Golang if you're interested: http://gotime.fm/ 🎧
*** =================================================== ***
*
*/

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"path"
)

// ============================
// Types
// ============================

// BeaconLog represents the entire blob of json from the beacon file
type BeaconLog struct {
	Logs []Log
}

// Log is a single entry in the BeaconLog;
//
// _Example_: a user submits a breaking change to the database,
// in which they would fill out all the info in this struct.
type Log struct {
	ID      string
	Date    string
	Email   string
	Author  string
	Message string
}

// ============================
// Vars and Constants
// ============================

var logFilePath = path.Join(os.Getenv("HOME"), "/Dropbox/The Heap/Beacon/beacon_log.json")
var beaconLogData BeaconLog

// ============================
// FUNCS
// ============================

func checkError(e error) {
	if e != nil {
		panic(e)
	}
}

// Print the beacon log to the terminal
func printLog(data BeaconLog) {
	for _, element := range data.Logs {
		fmt.Println("")
		fmt.Println("==========================================")
		fmt.Println("Date: ", element.Date)
		fmt.Println("Author: ", element.Author+" ("+element.Email+")") // I bet there's a nicer way to do this.
		fmt.Println("Message: ", element.Message)
		fmt.Println("==========================================")
	}
}

// ============================
// MAIN!
// ============================
func main() {

	// read JSON file from disk
	beaconLogFile, err := ioutil.ReadFile(path.Join(logFilePath))
	checkError(err)

	// unmarshal json and store it in the pointer to beaconLogData {?}
	// NOTE: figure out if you can use `checkError` here; don't yet understand golang's idiomatic errors handling.
	if err := json.Unmarshal(beaconLogFile, &beaconLogData); err != nil {
		panic(err)
	}

	// Print the beacon log!
	printLog(beaconLogData)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net"
	"net/http"
	"net/http/fcgi"
	"os"
	"path"
	"strings"
	"time"
	"strconv"

	"github.com/gin-gonic/gin"
)

// Logger is a simple log handler, out puts in the standard of apache access log common.
// See http://httpd.apache.org/docs/2.2/logs.html#accesslog
func Logger() gin.HandlerFunc {
	return func(c *gin.Context) {
		t := time.Now()
		ip, err := net.ResolveTCPAddr("tcp", c.Request.RemoteAddr)
		if err != nil {
			c.Abort()
		}

		// before request
		c.Next()
		// after request

		user := "-"
		if c.Request.URL.User != nil {
			user = c.Request.URL.User.Username()
		}

		latency := time.Since(t)

		// This is the format of Apache Log Common, with an additional field of latency
		fmt.Printf("%v - %v [%v] \"%v %v %v\" %v %v %v\n",
			ip.IP, user, t.Format(time.RFC3339), c.Request.Method, c.Request.URL.Path,
			c.Request.Proto, c.Writer.Status(), c.Request.ContentLength, latency)
	}
}

func stringInSlice(a string, list []string) bool {
	for _, b := range list {
		if b == a {
			return true
		}
	}
	return false
}

func testRemoteTCPPort(address string) bool {
	_, err := net.DialTimeout("tcp", address, 3 * time.Second)
	if err != nil {
		return false
	}
	return true
}

func mainHandler(c *gin.Context) {
	fields := strings.Split(c.Params.ByName("field"), ".")
	ip, err := net.ResolveTCPAddr("tcp", c.Request.RemoteAddr)
	if err != nil {
		c.Abort()
	}

	cfIP := net.ParseIP(c.Request.Header.Get("CF-Connecting-IP"))
	if cfIP != nil {
		ip.IP = cfIP
	}

        if fields[0] == "porttest" {
		if len(fields) >= 2 {
			if port, err := strconv.Atoi(fields[1]); err == nil && port > 0 && port <= 65535 {
				c.String(200, fmt.Sprintln(testRemoteTCPPort(ip.IP.String() + ":" + fields[1])))
			} else {
				c.String(400, "Invalid Port Number")
			}
		} else {
			c.String(400, "Need Port")
		}
		return
        }

	c.Set("ip", ip.IP.String())
	c.Set("port", ip.Port)
	c.Set("ua", c.Request.UserAgent())
	c.Set("lang", c.Request.Header.Get("Accept-Language"))
	c.Set("encoding", c.Request.Header.Get("Accept-Encoding"))
	c.Set("method", c.Request.Method)
	c.Set("mime", c.Request.Header.Get("Accept"))
	c.Set("referer", c.Request.Header.Get("Referer"))
	c.Set("forwarded", c.Request.Header.Get("X-Forwarded-For"))
	c.Set("country_code", c.Request.Header.Get("CF-IPCountry"))

	ua := strings.Split(c.Request.UserAgent(), "/")

	// Only lookup hostname if the results are going to need it.
	if stringInSlice(fields[0], []string{"all", "host"}) || (fields[0] == "" && ua[0] != "curl") {
		hostnames, err := net.LookupAddr(ip.IP.String())
		if err != nil {
			c.Set("host", "")
		} else {
			c.Set("host", hostnames[0])
		}
	}

	wantsJSON := false
	if len(fields) >= 2 && fields[1] == "json" {
		wantsJSON = true
	}

	switch fields[0] {
	case "":
		//If the user is using curl, then we should just return the IP, else we show the home page.
		if ua[0] == "curl" {
			c.String(200, fmt.Sprintln(ip.IP))
		} else {
			c.HTML(200, "index.html", c.Keys)
		}
		return
	case "request":
		c.JSON(200, c.Request)
		return
	case "all":
		if wantsJSON {
			c.JSON(200, c.Keys)
		} else {
			c.String(200, "%v", c.Keys)
		}
		return
	}

	fieldResult, exists := c.Get(fields[0])
	if !exists {
		c.String(404, "Not Found")
		return
	}
	c.String(200, fmt.Sprintln(fieldResult))

}

// FileServer is a basic file serve handler, this is just here as an example.
// gin.Static() should be used instead
func FileServer(root string) gin.HandlerFunc {
	return func(c *gin.Context) {
		file := c.Params.ByName("file")
		if !strings.HasPrefix(file, "/") {
			file = "/" + file
		}
		http.ServeFile(c.Writer, c.Request, path.Join(root, path.Clean(file)))
	}
}

func main() {
	r := gin.New()
	r.Use(gin.Recovery())
	r.Use(Logger())
	r.LoadHTMLGlob("templates/*")

	r.GET("/:field", mainHandler)
	r.GET("/", mainHandler)

	// Create a listener for FCGI
	fcgi_listen, err := net.Listen("tcp", "127.0.0.1:4000")
	if err != nil {
		panic(err)
	}
	errc := make(chan error)
	go func(errc chan error) {
		for err := range errc {
			panic(err)
		}
	}(errc)

	go func(errc chan error) {
		errc <- fcgi.Serve(fcgi_listen, r)
	}(errc)

	port := os.Getenv("PORT")
	host := os.Getenv("HOST")
	if port == "" {
		port = "8080"
	}
	errc <- r.Run(host + ":" + port)
}
<commit_msg>Adding newrelic application monitoring support<commit_after>package main

import (
	"fmt"
	"net"
	"net/http"
	"net/http/fcgi"
	"os"
	"path"
	"strings"
	"time"
	"strconv"

	"github.com/gin-gonic/gin"
        "github.com/brandfolder/gin-gorelic"
)

// Logger is a simple log handler, out puts in the standard of apache access log common.
// See http://httpd.apache.org/docs/2.2/logs.html#accesslog
func Logger() gin.HandlerFunc {
	return func(c *gin.Context) {
		t := time.Now()
		ip, err := net.ResolveTCPAddr("tcp", c.Request.RemoteAddr)
		if err != nil {
			c.Abort()
		}

		// before request
		c.Next()
		// after request

		user := "-"
		if c.Request.URL.User != nil {
			user = c.Request.URL.User.Username()
		}

		latency := time.Since(t)

		// This is the format of Apache Log Common, with an additional field of latency
		fmt.Printf("%v - %v [%v] \"%v %v %v\" %v %v %v\n",
			ip.IP, user, t.Format(time.RFC3339), c.Request.Method, c.Request.URL.Path,
			c.Request.Proto, c.Writer.Status(), c.Request.ContentLength, latency)
	}
}

func stringInSlice(a string, list []string) bool {
	for _, b := range list {
		if b == a {
			return true
		}
	}
	return false
}

func testRemoteTCPPort(address string) bool {
	_, err := net.DialTimeout("tcp", address, 3 * time.Second)
	if err != nil {
		return false
	}
	return true
}

func mainHandler(c *gin.Context) {
	fields := strings.Split(c.Params.ByName("field"), ".")
	ip, err := net.ResolveTCPAddr("tcp", c.Request.RemoteAddr)
	if err != nil {
		c.Abort()
	}

	cfIP := net.ParseIP(c.Request.Header.Get("CF-Connecting-IP"))
	if cfIP != nil {
		ip.IP = cfIP
	}

        if fields[0] == "porttest" {
		if len(fields) >= 2 {
			if port, err := strconv.Atoi(fields[1]); err == nil && port > 0 && port <= 65535 {
				c.String(200, fmt.Sprintln(testRemoteTCPPort(ip.IP.String() + ":" + fields[1])))
			} else {
				c.String(400, "Invalid Port Number")
			}
		} else {
			c.String(400, "Need Port")
		}
		return
        }

	c.Set("ip", ip.IP.String())
	c.Set("port", ip.Port)
	c.Set("ua", c.Request.UserAgent())
	c.Set("lang", c.Request.Header.Get("Accept-Language"))
	c.Set("encoding", c.Request.Header.Get("Accept-Encoding"))
	c.Set("method", c.Request.Method)
	c.Set("mime", c.Request.Header.Get("Accept"))
	c.Set("referer", c.Request.Header.Get("Referer"))
	c.Set("forwarded", c.Request.Header.Get("X-Forwarded-For"))
	c.Set("country_code", c.Request.Header.Get("CF-IPCountry"))

	ua := strings.Split(c.Request.UserAgent(), "/")

	// Only lookup hostname if the results are going to need it.
	if stringInSlice(fields[0], []string{"all", "host"}) || (fields[0] == "" && ua[0] != "curl") {
		hostnames, err := net.LookupAddr(ip.IP.String())
		if err != nil {
			c.Set("host", "")
		} else {
			c.Set("host", hostnames[0])
		}
	}

	wantsJSON := false
	if len(fields) >= 2 && fields[1] == "json" {
		wantsJSON = true
	}

	switch fields[0] {
	case "":
		//If the user is using curl, then we should just return the IP, else we show the home page.
		if ua[0] == "curl" {
			c.String(200, fmt.Sprintln(ip.IP))
		} else {
			c.HTML(200, "index.html", c.Keys)
		}
		return
	case "request":
		c.JSON(200, c.Request)
		return
	case "all":
		if wantsJSON {
			c.JSON(200, c.Keys)
		} else {
			c.String(200, "%v", c.Keys)
		}
		return
	}

	fieldResult, exists := c.Get(fields[0])
	if !exists {
		c.String(404, "Not Found")
		return
	}
	c.String(200, fmt.Sprintln(fieldResult))

}

// FileServer is a basic file serve handler, this is just here as an example.
// gin.Static() should be used instead
func FileServer(root string) gin.HandlerFunc {
	return func(c *gin.Context) {
		file := c.Params.ByName("file")
		if !strings.HasPrefix(file, "/") {
			file = "/" + file
		}
		http.ServeFile(c.Writer, c.Request, path.Join(root, path.Clean(file)))
	}
}

func main() {
	r := gin.New()
	r.Use(gin.Recovery())
	r.Use(Logger())
	r.LoadHTMLGlob("templates/*")

	if NEWRELIC_LICENSE_KEY := os.Getenv("NEWRELIC_LICENSE_KEY"); NEWRELIC_LICENSE_KEY != "" {
		var NEWRELIC_APPLICATION_NAME string
		if NEWRELIC_APPLICATION_NAME = os.Getenv("NEWRELIC_APPLICATION_NAME"); NEWRELIC_APPLICATION_NAME == "" {
			NEWRELIC_APPLICATION_NAME = "ifconfig.io"
		}
		gorelic.InitNewrelicAgent(NEWRELIC_LICENSE_KEY, NEWRELIC_APPLICATION_NAME, true)
		r.Use(gorelic.Handler)
	}

	r.GET("/:field", mainHandler)
	r.GET("/", mainHandler)

	// Create a listener for FCGI
	fcgi_listen, err := net.Listen("tcp", "127.0.0.1:4000")
	if err != nil {
		panic(err)
	}
	errc := make(chan error)
	go func(errc chan error) {
		for err := range errc {
			panic(err)
		}
	}(errc)

	go func(errc chan error) {
		errc <- fcgi.Serve(fcgi_listen, r)
	}(errc)

	port := os.Getenv("PORT")
	host := os.Getenv("HOST")
	if port == "" {
		port = "8080"
	}
	errc <- r.Run(host + ":" + port)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"bytes"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
	"path"
	"strconv"
	"strings"
)

const (
	// escape = "\x1b"
	nl        = "\n"
	prefixIn  = ""
	prefixOut = ""
	protocol  = "\x1b[91m%s %s %s\x1b[0m\n"
	header    = "%s\x1b[90m%s:\x1b[0m \x1b[94m%s\x1b[0m\n"
	userAgent = "henderjon/hurl v0.1.0"
)

var (
	optFormURLEncode, optSilence,
	optQueryString, optPostForm,
	optOutFile, optReadStdin,
	help bool
	optHTTPAction, optTargetURL string
	stderr, stdout              *log.Logger
	optHeaders                  = multiParams{}
	optData                     = multiParams{}
)

func init() {

	flag.BoolVar(&help, "help", false, "display these program options")
	flag.BoolVar(&optFormURLEncode, "f", false, "sugar for adding 'Content-Type: application/x-www-form-urlencoded'")
	flag.BoolVar(&optPostForm, "pf", false, "form-urlencode the POST; sugar for '-X POST -f'")
	flag.BoolVar(&optSilence, "s", false, "shutup")
	flag.BoolVar(&optQueryString, "q", false, "append -d's to the target URL as a query string")
	flag.BoolVar(&optOutFile, "save", false, "write the output to a similarly named local file; to specify a different filename, simply redirect stdout")
	flag.BoolVar(&optReadStdin, "stdin", false, "read the request body from stdin; request will ingore all -d's")
	flag.Var(&optHeaders, "h", "`param=value` headers for the request")
	flag.Var(&optData, "d", "`param=value` data for the request")
	flag.StringVar(&optHTTPAction, "X", "GET", "specify the HTTP `action` (e.g. GET, POST, etc)")

	flag.Parse()

	args := flag.Args()

	if len(args) < 1 {
		log.Fatal("The URL should be the last arg")
	}

	optTargetURL = args[len(args)-1]

	stdout = log.New(os.Stdout, "", 0)
	stderr = log.New(os.Stderr, "", 0)
	if optSilence {
		stderr = log.New(ioutil.Discard, "", 0)
	}

}

func main() {

	if help {
		fmt.Println("\n\x1b[91mhurl is a utility for making HTTP requests. \x1b[0m\n")
		flag.PrintDefaults()
		return
	}

	client := http.Client{}

	remote, err := url.Parse(optTargetURL)
	if err != nil {
		log.Fatal("Unable to parse", optTargetURL)
	}

	if remote.Scheme == "" {
		remote.Scheme = "http"
		remote, _ = url.Parse(remote.String()) // reparse to populate remote.Host
	}

	data := url.Values{}
	for name, slice := range optData {
		for _, v := range slice {
			data.Add(name, v)
		}
	}

	if optPostForm {
		optHTTPAction = http.MethodPost
		optFormURLEncode = true
	}

	var body bytes.Buffer // io.ReadWriter
	if optQueryString {
		remote.RawQuery = data.Encode() // force a query string with -q
	} else {

		if optReadStdin {
			scanner := bufio.NewScanner(os.Stdin)
			for scanner.Scan() {
				body.Write(scanner.Bytes())
			}
		}

		if body.Len() == 0 {
			body.WriteString(data.Encode()) // send the data as the body
		}
	}

	req, err := http.NewRequest(optHTTPAction, remote.String(), &body)
	if err != nil {
		log.Fatal(err)
	}

	req.Header.Set("User-Agent", userAgent)
	req.Header.Set("Accept", "*/*")
	req.Header.Set("Host", remote.Host)
	req.Header.Set("Content-Length", strconv.Itoa(body.Len()))
	if optFormURLEncode {
		req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	}

	for name, slice := range optHeaders {
		for _, v := range slice {
			req.Header.Add(name, v)
		}
	}

	stderr.Printf(protocol, req.Method, req.URL.RequestURI(), req.Proto)
	for k, v := range req.Header {
		for _, v := range v {
			stderr.Printf(header, prefixOut, k, v)
		}
	}

	stderr.Print("\n")
	stderr.Printf("%v\n", &body)
	stderr.Print("\n")

	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	stderr.Printf(protocol, resp.Proto, resp.Status, "")

	printHeaders(resp.Header)

	stderr.Print("\n")

	local := os.Stdout
	if optOutFile {
		fname := path.Base(remote.Path)
		local, err = os.Open(fname)
		if os.IsNotExist(err) {
			local, _ = os.Create(fname)
		} else {
			log.Fatal(err)
		}
	}

	io.Copy(local, resp.Body)
}

func printHeaders(headers map[string][]string) {
	for k, v := range headers {
		for _, v := range v {
			stderr.Printf(header, prefixOut, k, v)
		}
	}
}

type multiParams map[string][]string

func (d multiParams) String() string {
	return fmt.Sprintf("%d", d)
}

func (d multiParams) Set(value string) error {
	v := strings.Split(value, "=")
	if len(v) == 2 {
		d[v[0]] = append(d[v[0]], v[1])
	}
	return nil
}
<commit_msg>uses strings.SplitN to allow for "=" in the values of data and headers<commit_after>package main

import (
	"bufio"
	"bytes"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
	"path"
	"strconv"
	"strings"
)

const (
	// escape = "\x1b"
	nl        = "\n"
	prefixIn  = ""
	prefixOut = ""
	protocol  = "\x1b[91m%s %s %s\x1b[0m\n"
	header    = "%s\x1b[90m%s:\x1b[0m \x1b[94m%s\x1b[0m\n"
	userAgent = "henderjon/hurl v0.1.0"
)

var (
	optFormURLEncode, optSilence,
	optQueryString, optPostForm,
	optOutFile, optReadStdin,
	help bool
	optHTTPAction, optTargetURL string
	stderr, stdout              *log.Logger
	optHeaders                  = multiParams{}
	optData                     = multiParams{}
)

func init() {

	flag.BoolVar(&help, "help", false, "display these program options")
	flag.BoolVar(&optFormURLEncode, "f", false, "sugar for adding 'Content-Type: application/x-www-form-urlencoded'")
	flag.BoolVar(&optPostForm, "pf", false, "form-urlencode the POST; sugar for '-X POST -f'")
	flag.BoolVar(&optSilence, "s", false, "shutup")
	flag.BoolVar(&optQueryString, "q", false, "append -d's to the target URL as a query string")
	flag.BoolVar(&optOutFile, "save", false, "write the output to a similarly named local file; to specify a different filename, simply redirect stdout")
	flag.BoolVar(&optReadStdin, "stdin", false, "read the request body from stdin; request will ingore all -d's")
	flag.Var(&optHeaders, "h", "`param=value` headers for the request")
	flag.Var(&optData, "d", "`param=value` data for the request")
	flag.StringVar(&optHTTPAction, "X", "GET", "specify the HTTP `action` (e.g. GET, POST, etc)")

	flag.Parse()

	args := flag.Args()

	if len(args) < 1 {
		log.Fatal("The URL should be the last arg")
	}

	optTargetURL = args[len(args)-1]

	stdout = log.New(os.Stdout, "", 0)
	stderr = log.New(os.Stderr, "", 0)
	if optSilence {
		stderr = log.New(ioutil.Discard, "", 0)
	}

}

func main() {

	if help {
		fmt.Println("\n\x1b[91mhurl is a utility for making HTTP requests. \x1b[0m\n")
		flag.PrintDefaults()
		return
	}

	client := http.Client{}

	remote, err := url.Parse(optTargetURL)
	if err != nil {
		log.Fatal("Unable to parse", optTargetURL)
	}

	if remote.Scheme == "" {
		remote.Scheme = "http"
		remote, _ = url.Parse(remote.String()) // reparse to populate remote.Host
	}

	data := url.Values{}
	for name, slice := range optData {
		for _, v := range slice {
			data.Add(name, v)
		}
	}

	if optPostForm {
		optHTTPAction = http.MethodPost
		optFormURLEncode = true
	}

	var body bytes.Buffer // io.ReadWriter
	if optQueryString {
		remote.RawQuery = data.Encode() // force a query string with -q
	} else {

		if optReadStdin {
			scanner := bufio.NewScanner(os.Stdin)
			for scanner.Scan() {
				body.Write(scanner.Bytes())
			}
		}

		if body.Len() == 0 {
			body.WriteString(data.Encode()) // send the data as the body
		}
	}

	req, err := http.NewRequest(optHTTPAction, remote.String(), &body)
	if err != nil {
		log.Fatal(err)
	}

	req.Header.Set("User-Agent", userAgent)
	req.Header.Set("Accept", "*/*")
	req.Header.Set("Host", remote.Host)
	req.Header.Set("Content-Length", strconv.Itoa(body.Len()))
	if optFormURLEncode {
		req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	}

	for name, slice := range optHeaders {
		for _, v := range slice {
			req.Header.Add(name, v)
		}
	}

	stderr.Printf(protocol, req.Method, req.URL.RequestURI(), req.Proto)
	for k, v := range req.Header {
		for _, v := range v {
			stderr.Printf(header, prefixOut, k, v)
		}
	}

	stderr.Print("\n")
	stderr.Printf("%v\n", &body)
	stderr.Print("\n")

	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	stderr.Printf(protocol, resp.Proto, resp.Status, "")

	printHeaders(resp.Header)

	stderr.Print("\n")

	local := os.Stdout
	if optOutFile {
		fname := path.Base(remote.Path)
		local, err = os.Open(fname)
		if os.IsNotExist(err) {
			local, _ = os.Create(fname)
		} else {
			log.Fatal(err)
		}
	}

	io.Copy(local, resp.Body)
}

func printHeaders(headers map[string][]string) {
	for k, v := range headers {
		for _, v := range v {
			stderr.Printf(header, prefixOut, k, v)
		}
	}
}

type multiParams map[string][]string

func (d multiParams) String() string {
	return fmt.Sprintf("%d", d)
}

func (d multiParams) Set(value string) error {
	v := strings.SplitN(value, "=", 2)
	if len(v) == 2 {
		d[v[0]] = append(d[v[0]], v[1])
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"
	"text/tabwriter"

	"github.com/alecthomas/kingpin"
	"github.com/getantibody/antibody/antibodylib"
	"github.com/getantibody/antibody/project"
	"github.com/getantibody/antibody/shell"
	"github.com/getantibody/folder"
	"golang.org/x/crypto/ssh/terminal"
)

// nolint: gochecknoglobals
var (
	version = "dev"

	app         = kingpin.New("antibody", "The fastest shell plugin manager")
	parallelism = app.Flag("parallelism", "max amount of tasks to launch in parallel").
			Short('p').
			Default(strconv.Itoa(runtime.NumCPU())).
			Int()
	bundleCmd = app.Command("bundle", "downloads a bundle and prints its source line")
	bundles   = bundleCmd.Arg("bundles", "bundle list").Strings()
	updateCmd = app.Command("update", "updates all previously bundled bundles")
	homeCmd   = app.Command("home", "prints where antibody is cloning the bundles")
	purgeCmd  = app.Command("purge", "purges a bundle from your computer")
	purgee    = purgeCmd.Arg("bundle", "bundle to be purged").Required().String()
	listCmd   = app.Command("list", "lists all currently installed bundles").Alias("ls")
	initCmd   = app.Command("init", "initializes the shell so Antibody can work as expected")
)

// nolint: gochecknoinits
func init() {
	log.SetOutput(os.Stderr)
	log.SetPrefix("antibody: ")
	log.SetFlags(0)
}

func main() {
	app.Author("Carlos Alexandro Becker <caarlos0@gmail.com>")
	app.Version("antibody version " + version)
	app.VersionFlag.Short('v')
	app.HelpFlag.Short('h')

	switch kingpin.MustParse(app.Parse(os.Args[1:])) {
	case bundleCmd.FullCommand():
		bundle()
	case updateCmd.FullCommand():
		update()
	case homeCmd.FullCommand():
		fmt.Println(antibodylib.Home())
	case purgeCmd.FullCommand():
		purge()
	case listCmd.FullCommand():
		list()
	case initCmd.FullCommand():
		sh, err := shell.Init()
		app.FatalIfError(err, "failed to init")
		fmt.Println(sh)
	}
}

func bundle() {
	var input io.Reader
	if !terminal.IsTerminal(int(os.Stdin.Fd())) && len(*bundles) == 0 {
		input = os.Stdin
	} else {
		input = bytes.NewBufferString(strings.Join(*bundles, " "))
	}
	sh, err := antibodylib.New(antibodylib.Home(), input, *parallelism).Bundle()
	app.FatalIfError(err, "failed to bundle")
	fmt.Println(sh)
}

func update() {
	var home = antibodylib.Home()
	fmt.Printf("Updating all bundles in %v...\n", home)
	var err = project.Update(home, *parallelism)
	app.FatalIfError(err, "failed to update")
}

func purge() {
	fmt.Printf("Removing %s...\n", *purgee)
	var path = project.New(antibodylib.Home(), *purgee).Path()
	if _, err := os.Stat(path); os.IsNotExist(err) {
		app.Fatalf("%s does not exist on expected location: %s", *purgee, path)
	}
	app.FatalIfError(os.RemoveAll(path), "failed to purge")
	fmt.Println("removed!")
}

func list() {
	home := antibodylib.Home()
	projects, err := project.List(home)
	app.FatalIfError(err, "failed to list bundles")
	w := tabwriter.NewWriter(os.Stdout, 0, 1, 4, ' ', tabwriter.TabIndent)
	for _, b := range projects {
		fmt.Fprintf(w, "%s\t%s\n", folder.ToURL(b), filepath.Join(home, b))
	}
	app.FatalIfError(w.Flush(), "failed to flush")
}
<commit_msg>Add path command. (#314)<commit_after>package main

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"
	"text/tabwriter"

	"github.com/alecthomas/kingpin"
	"github.com/getantibody/antibody/antibodylib"
	"github.com/getantibody/antibody/project"
	"github.com/getantibody/antibody/shell"
	"github.com/getantibody/folder"
	"golang.org/x/crypto/ssh/terminal"
)

// nolint: gochecknoglobals
var (
	version = "dev"

	app         = kingpin.New("antibody", "The fastest shell plugin manager")
	parallelism = app.Flag("parallelism", "max amount of tasks to launch in parallel").
			Short('p').
			Default(strconv.Itoa(runtime.NumCPU())).
			Int()
	bundleCmd = app.Command("bundle", "downloads a bundle and prints its source line")
	bundles   = bundleCmd.Arg("bundles", "bundle list").Strings()
	updateCmd = app.Command("update", "updates all previously bundled bundles")
	homeCmd   = app.Command("home", "prints where antibody is cloning the bundles")
	purgeCmd  = app.Command("purge", "purges a bundle from your computer")
	purgee    = purgeCmd.Arg("bundle", "bundle to be purged").Required().String()
	listCmd   = app.Command("list", "lists all currently installed bundles").Alias("ls")
	pathCmd   = app.Command("path", "prints the path of a currently cloned bundle")
	pathee    = pathCmd.Arg("bundle", "bundle in which to find and print cloned path").Required().String()
	initCmd   = app.Command("init", "initializes the shell so Antibody can work as expected")
)

// nolint: gochecknoinits
func init() {
	log.SetOutput(os.Stderr)
	log.SetPrefix("antibody: ")
	log.SetFlags(0)
}

func main() {
	app.Author("Carlos Alexandro Becker <caarlos0@gmail.com>")
	app.Version("antibody version " + version)
	app.VersionFlag.Short('v')
	app.HelpFlag.Short('h')

	switch kingpin.MustParse(app.Parse(os.Args[1:])) {
	case bundleCmd.FullCommand():
		bundle()
	case updateCmd.FullCommand():
		update()
	case homeCmd.FullCommand():
		fmt.Println(antibodylib.Home())
	case purgeCmd.FullCommand():
		purge()
	case listCmd.FullCommand():
		list()
	case pathCmd.FullCommand():
		path()
	case initCmd.FullCommand():
		sh, err := shell.Init()
		app.FatalIfError(err, "failed to init")
		fmt.Println(sh)
	}
}

func bundle() {
	var input io.Reader
	if !terminal.IsTerminal(int(os.Stdin.Fd())) && len(*bundles) == 0 {
		input = os.Stdin
	} else {
		input = bytes.NewBufferString(strings.Join(*bundles, " "))
	}
	sh, err := antibodylib.New(antibodylib.Home(), input, *parallelism).Bundle()
	app.FatalIfError(err, "failed to bundle")
	fmt.Println(sh)
}

func update() {
	var home = antibodylib.Home()
	fmt.Printf("Updating all bundles in %v...\n", home)
	var err = project.Update(home, *parallelism)
	app.FatalIfError(err, "failed to update")
}

func purge() {
	fmt.Printf("Removing %s...\n", *purgee)
	var path = project.New(antibodylib.Home(), *purgee).Path()
	if _, err := os.Stat(path); os.IsNotExist(err) {
		app.Fatalf("%s does not exist on expected location: %s", *purgee, path)
	}
	app.FatalIfError(os.RemoveAll(path), "failed to purge")
	fmt.Println("removed!")
}

func list() {
	home := antibodylib.Home()
	projects, err := project.List(home)
	app.FatalIfError(err, "failed to list bundles")
	w := tabwriter.NewWriter(os.Stdout, 0, 1, 4, ' ', tabwriter.TabIndent)
	for _, b := range projects {
		fmt.Fprintf(w, "%s\t%s\n", folder.ToURL(b), filepath.Join(home, b))
	}
	app.FatalIfError(w.Flush(), "failed to flush")
}

func path() {
	var path = project.New(antibodylib.Home(), *pathee).Path()
	if _, err := os.Stat(path); os.IsNotExist(err) {
		app.Fatalf("%s does not exist in cloned paths", *pathee)
	} else {
		fmt.Println(path)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"gofred"
	"io/ioutil"
	"log"
	"net"
	"os"
	"os/exec"
	"sort"
	"strings"

	"gopkg.in/yaml.v2"
)

const (
	noSubtitle     = ""
	noArg          = ""
	noAutocomplete = ""
)

type compose struct {
	Services map[string]interface{}
}

// Config is
type Config struct {
	FilePath    string   `yaml:"filepath"`
	Environment []string `yaml:"environment"`
}

// Message adds simple message
func Message(response *gofred.Response, title, subtitle string, err bool) {
	msg := gofred.NewItem(title, subtitle, noAutocomplete)
	// if err {
	// 	msg = msg.AddIcon(iconError, defaultIconType)
	// } else {
	// 	msg = msg.AddIcon(iconDone, defaultIconType)
	// }
	response.AddItems(msg)
	fmt.Println(response)
}

func init() {
	flag.Parse()
}

func exists(name string) bool {
	_, err := os.Stat(name)
	if os.IsNotExist(err) {
		return false
	}
	return err == nil
}
func getOutboundIP() net.IP {
	conn, err := net.Dial("udp", "8.8.8.8:80")
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	return conn.LocalAddr().(*net.UDPAddr).IP
}

const configfile = "config.yml"

func main() {
	path := os.Getenv("PATH")
	if !strings.Contains(path, "/usr/local/bin") {
		os.Setenv("PATH", path+":/usr/local/bin")
	}
	response := gofred.NewResponse()
	content, err := ioutil.ReadFile(configfile)
	if err != nil {
		item := gofred.NewItem("Reading config file error", "Modify Configuration", noAutocomplete).
			AddIcon("modify.png", "").Executable(configfile)
		item.VarMap = make(map[string]string)
		item.VarMap["cmd"] = "filewrite"

		response.AddItems(item)
		fmt.Println(response)
		return
	}

	conf := make(map[string]Config)
	err = yaml.Unmarshal(content, &conf)
	if err != nil {
		item := gofred.NewItem("Parsing config file error", "Modify Configuration", noAutocomplete).
			AddIcon("modify.png", "").Executable(configfile)
		item.VarMap = make(map[string]string)
		item.VarMap["cmd"] = "filewrite"

		response.AddItems(item)
		fmt.Println(response)
		return
	}
	response.VarMap = make(map[string]string)
	configItems := []gofred.Item{}
	selected := ""

	for name, config := range conf {
		if flag.Arg(0) == name {
			selected = name
		} else {
			configItems = append(configItems, gofred.NewItem("Select #"+name, config.FilePath, name).AddIcon("docker.png", ""))
		}
	}
	if len(selected) == 0 {
		response.AddMatchedItems(flag.Arg(0), configItems...)
		item := gofred.NewItem("Modify Configuration", noSubtitle, noAutocomplete).
			AddIcon("modify.png", "").Executable(configfile)
		item.VarMap = make(map[string]string)
		item.VarMap["cmd"] = "filewrite"
		response.AddItems(item)
		fmt.Println(response)
		return
	}

	response.VarMap["cmd"] = "bash"
	items := []gofred.Item{}
	comp := compose{}
	if exists(conf[selected].FilePath) {
		content, err := ioutil.ReadFile(conf[selected].FilePath)
		err = yaml.Unmarshal(content, &comp)
		if err != nil {
			Message(response, "Can not parse docker-compose file", "please check if yaml file is well written", true)
			return
		}
	} else {
		item := gofred.NewItem("Can not read docker-compose file", "Set docker-compose file path", noAutocomplete).
			AddIcon("plus.png", "").Executable(configfile)
		item.VarMap = make(map[string]string)
		item.VarMap["cmd"] = "filewrite"

		response.AddItems(item)
		fmt.Println(response)
		return
	}

	var services []string
	for service := range comp.Services {
		services = append(services, service)
	}
	sort.Strings(services)
	outboundIP := getOutboundIP().String()
	envStr := ""
	if len(conf[selected].Environment) > 0 {
		envStr = "env"
		for _, str := range conf[selected].Environment {
			envStr += " " + strings.Replace(str, "localhost", outboundIP, -1)
		}
	}

	baseCommand := fmt.Sprintf("%s /usr/local/bin/docker-compose -f %s ", envStr, conf[selected].FilePath)

	runningServices, err := exec.Command("bash", "-c", fmt.Sprintf("%sps | grep Up | awk '{print $1}'", baseCommand)).CombinedOutput()
	if err != nil {
		if err != nil {
			Message(response, "Can not parse docker-compose file", "please check if yaml file is well written", true)
			return
		}
		return
	}
	if strings.Contains(string(runningServices), "Couldn't connect to Docker daemon") {
		response.AddItems(gofred.NewItem("Docker deamon is not running", "start Docker", noAutocomplete).
			Executable("open -a Docker.app"))
		fmt.Println(response)
		return
	}

	{
		baseItem := gofred.NewItem("All Services", "create & start all services up", noAutocomplete).
			AddIcon("docker.png", "").Executable(baseCommand+"up -d").
			AddOptionKeyAction("Recreate and start all services", baseCommand+"up --force-recreate -d", true).
			AddCommandKeyAction("Stop all services conatainers", baseCommand+"stop", true)
		logItem := gofred.NewItem("Check logs on terminal", "Open terminal and show logs", noAutocomplete).
			AddIcon("docker.png", "").Executable(baseCommand + "logs -f -t")
		logItem.VarMap = make(map[string]string)
		logItem.VarMap["cmd"] = "terminal"

		items = append(items, baseItem, logItem)
	}

	for _, service := range services {
		running := false
		if strings.Contains(string(runningServices), service) {
			running = true
		}

		if running {
			items = append(items, gofred.NewItem(service, "Stop service", noAutocomplete).
				AddIcon("On.png", "").Executable(baseCommand+"stop "+service).
				AddOptionKeyAction("Recreate and start service", baseCommand+"up --force-recreate -d "+service, true))
		} else {
			items = append(items, gofred.NewItem(service, "Start service", noAutocomplete).
				AddIcon("Off.png", "").
				Executable(baseCommand+"up -d "+service).
				AddOptionKeyAction("Recreate and start service", baseCommand+"up --force-recreate -d "+service, true))
		}
	}
	response.AddItems(items...)
	fmt.Println(response)
}
<commit_msg>update to use new functions<commit_after>package main

import (
	"flag"
	"fmt"
	"gofred"
	"io/ioutil"
	"log"
	"net"
	"os"
	"os/exec"
	"sort"
	"strings"

	"gopkg.in/yaml.v2"
)

const (
	noSubtitle     = ""
	noArg          = ""
	noAutocomplete = ""
)

type compose struct {
	Services map[string]interface{}
}

// Config is
type Config struct {
	FilePath    string   `yaml:"filepath"`
	Environment []string `yaml:"environment"`
}

// Message adds simple message
func Message(response *gofred.Response, title, subtitle string, err bool) {
	msg := gofred.NewItem(title, subtitle, noAutocomplete)
	// if err {
	// 	msg = msg.AddIcon(iconError, defaultIconType)
	// } else {
	// 	msg = msg.AddIcon(iconDone, defaultIconType)
	// }
	response.AddItems(msg)
	fmt.Println(response)
}

func init() {
	flag.Parse()
}

func exists(name string) bool {
	_, err := os.Stat(name)
	if os.IsNotExist(err) {
		return false
	}
	return err == nil
}
func getOutboundIP() net.IP {
	conn, err := net.Dial("udp", "8.8.8.8:80")
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	return conn.LocalAddr().(*net.UDPAddr).IP
}

const configfile = "config.yml"

func main() {
	path := os.Getenv("PATH")
	if !strings.Contains(path, "/usr/local/bin") {
		os.Setenv("PATH", path+":/usr/local/bin")
	}
	response := gofred.NewResponse()
	content, err := ioutil.ReadFile(configfile)
	if err != nil {
		response.AddItems(gofred.NewItem("Reading config file error", "Modify Configuration", noAutocomplete).
			AddIcon("modify.png", "").Executable(configfile).AddVariables(gofred.NewVariable("cmd", "filewrite")))
		fmt.Println(response)
		return
	}

	conf := make(map[string]Config)
	err = yaml.Unmarshal(content, &conf)
	if err != nil {
		response.AddItems(gofred.NewItem("Parsing config file error", "Modify Configuration", noAutocomplete).
			AddIcon("modify.png", "").Executable(configfile).AddVariables(gofred.NewVariable("cmd", "filewrite")))
		fmt.Println(response)
		return
	}

	configItems := []gofred.Item{}
	selected := ""
	for name, config := range conf {
		if flag.Arg(0) == name {
			selected = name
		} else {
			configItems = append(configItems, gofred.NewItem("Select #"+name, config.FilePath, name).AddIcon("docker.png", ""))
		}
	}
	if len(selected) == 0 {
		response.AddMatchedItems(flag.Arg(0), configItems...)
		response.AddItems(gofred.NewItem("Modify Configuration", noSubtitle, noAutocomplete).
			AddIcon("modify.png", "").Executable(configfile).AddVariables(gofred.NewVariable("cmd", "filewrite")))
		fmt.Println(response)
		return
	}

	response.AddVariable("cmd", "bash")
	items := []gofred.Item{}
	comp := compose{}
	if exists(conf[selected].FilePath) {
		content, err := ioutil.ReadFile(conf[selected].FilePath)
		err = yaml.Unmarshal(content, &comp)
		if err != nil {
			Message(response, "Can not parse docker-compose file", "please check if yaml file is well written", true)
			return
		}
	} else {
		item := gofred.NewItem("Can not read docker-compose file", "Set docker-compose file path", noAutocomplete).
			AddIcon("plus.png", "").Executable(configfile).AddVariables(gofred.NewVariable("cmd", "filewrite"))
		response.AddItems(item)
		fmt.Println(response)
		return
	}

	var services []string
	for service := range comp.Services {
		services = append(services, service)
	}
	sort.Strings(services)
	outboundIP := getOutboundIP().String()
	envStr := ""
	if len(conf[selected].Environment) > 0 {
		envStr = "env"
		for _, str := range conf[selected].Environment {
			envStr += " " + strings.Replace(str, "localhost", outboundIP, -1)
		}
	}

	baseCommand := fmt.Sprintf("%s /usr/local/bin/docker-compose -f %s ", envStr, conf[selected].FilePath)

	runningServices, err := exec.Command("bash", "-c", fmt.Sprintf("%sps | grep Up | awk '{print $1}'", baseCommand)).CombinedOutput()
	if err != nil {
		if err != nil {
			Message(response, "Can not parse docker-compose file", "please check if yaml file is well written", true)
			return
		}
		return
	}
	if strings.Contains(string(runningServices), "Couldn't connect to Docker daemon") {
		response.AddItems(gofred.NewItem("Docker deamon is not running", "start Docker", noAutocomplete).
			Executable("open -a Docker.app"))
		fmt.Println(response)
		return
	}

	{
		items = append(items, gofred.NewItem("All Services", "create & start all services up", noAutocomplete).
			AddIcon("docker.png", "").Executable(baseCommand+"up -d").
			AddOptionKeyAction("Recreate and start all services", baseCommand+"up --force-recreate -d", true).
			AddCommandKeyAction("Stop all services conatainers", baseCommand+"stop", true),
			gofred.NewItem("Check logs on terminal", "Open terminal and show logs", noAutocomplete).
				AddIcon("docker.png", "").Executable(baseCommand+"logs -f -t").AddVariables(gofred.NewVariable("cmd", "terminal")))
	}

	for _, service := range services {
		running := false
		if strings.Contains(string(runningServices), service) {
			running = true
		}

		if running {
			items = append(items, gofred.NewItem(service, "Stop service", noAutocomplete).
				AddIcon("On.png", "").Executable(baseCommand+"stop "+service).
				AddOptionKeyAction("Recreate and start service", baseCommand+"up --force-recreate -d "+service, true))
		} else {
			items = append(items, gofred.NewItem(service, "Start service", noAutocomplete).
				AddIcon("Off.png", "").
				Executable(baseCommand+"up -d "+service).
				AddOptionKeyAction("Recreate and start service", baseCommand+"up --force-recreate -d "+service, true))
		}
	}
	response.AddItems(items...)
	fmt.Println(response)
}
<|endoftext|>


<commit_before>// main module to startup the statsd proxy
package main

import (
	"flag"
	"github.com/mrtazz/go-statsd-proxy/statsdproxy"
)

func main() {
	// note, that variables are pointers
	configfile := flag.String("f", "", "config file path")
	debug := flag.Bool("d", false, "enable debug mode")
	flag.Parse()
	statsdproxy.DebugMode = *debug
  // TODO: catch sigterm and actually tell the process to quit
  quit := make(chan bool)
	statsdproxy.StartProxy(*configfile, quit)
}
<commit_msg>Add sigterm/interrupt handling<commit_after>// main module to startup the statsd proxy
package main

import (
	"flag"
	"os"
	"os/signal"
	"syscall"

	"github.com/mrtazz/go-statsd-proxy/statsdproxy"
)

var (
	configfile = flag.String("f", "/etc/statsdproxy.json", "Configuration file path")
	debug      = flag.Bool("d", false, "enable debug mode")
)

func main() {
	flag.Parse()

	statsdproxy.DebugMode = *debug

	quit := make(chan bool)

	handleSignals(quit)

	statsdproxy.StartProxy(
		*configfile,
		quit,
	)
}

func handleSignals(quitChan chan bool) {
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP)
	go func(chan os.Signal) {
		for sig := range c {
			if sig == os.Interrupt || sig == syscall.SIGTERM {
				quitChan <- true
				os.Exit(0)
			}
		}
	}(c)
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/ec2"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSVpcEndpointSubnetAssociation_basic(t *testing.T) {
	var vpce ec2.VpcEndpoint

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckVpcEndpointSubnetAssociationDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccVpcEndpointSubnetAssociationConfig_basic,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckVpcEndpointSubnetAssociationExists(
						"aws_vpc_endpoint_subnet_association.a", &vpce),
				),
			},
		},
	})
}

func TestAccAwsVpcEndpointSubnetAssociation_multiple(t *testing.T) {
	var vpce ec2.VpcEndpoint

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckVpcEndpointSubnetAssociationDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccVpcEndpointSubnetAssociationConfig_multiple,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckVpcEndpointSubnetAssociationExists(
						"aws_vpc_endpoint_subnet_association.a.0", &vpce),
					testAccCheckVpcEndpointSubnetAssociationExists(
						"aws_vpc_endpoint_subnet_association.a.1", &vpce),
					testAccCheckVpcEndpointSubnetAssociationExists(
						"aws_vpc_endpoint_subnet_association.a.2", &vpce),
				),
			},
		},
	})
}

func testAccCheckVpcEndpointSubnetAssociationDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).ec2conn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_vpc_endpoint_subnet_association" {
			continue
		}

		// Try to find the resource
		resp, err := conn.DescribeVpcEndpoints(&ec2.DescribeVpcEndpointsInput{
			VpcEndpointIds: aws.StringSlice([]string{rs.Primary.Attributes["vpc_endpoint_id"]}),
		})
		if err != nil {
			// Verify the error is what we want
			ec2err, ok := err.(awserr.Error)
			if !ok {
				return err
			}
			if ec2err.Code() != "InvalidVpcEndpointId.NotFound" {
				return err
			}
			return nil
		}

		vpce := resp.VpcEndpoints[0]
		if len(vpce.SubnetIds) > 0 {
			return fmt.Errorf(
				"Vpc endpoint %s has subnets", *vpce.VpcEndpointId)
		}
	}

	return nil
}

func testAccCheckVpcEndpointSubnetAssociationExists(n string, vpce *ec2.VpcEndpoint) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No ID is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).ec2conn
		resp, err := conn.DescribeVpcEndpoints(&ec2.DescribeVpcEndpointsInput{
			VpcEndpointIds: aws.StringSlice([]string{rs.Primary.Attributes["vpc_endpoint_id"]}),
		})
		if err != nil {
			return err
		}
		if len(resp.VpcEndpoints) == 0 {
			return fmt.Errorf("Vpc endpoint not found")
		}

		*vpce = *resp.VpcEndpoints[0]

		if len(vpce.SubnetIds) == 0 {
			return fmt.Errorf("no subnet associations")
		}

		for _, id := range vpce.SubnetIds {
			if aws.StringValue(id) == rs.Primary.Attributes["subnet_id"] {
				return nil
			}
		}

		return fmt.Errorf("subnet association not found")
	}
}

const testAccVpcEndpointSubnetAssociationConfig_basic = `
provider "aws" {
  region = "us-west-2"
}

resource "aws_vpc" "foo" {
  cidr_block = "10.0.0.0/16"
  tags {
    Name = "terraform-testacc-vpc-endpoint-subnet-association"
  }
}

data "aws_security_group" "default" {
  vpc_id = "${aws_vpc.foo.id}"
  name   = "default"
}

data "aws_availability_zones" "available" {}

resource "aws_vpc_endpoint" "ec2" {
  vpc_id              = "${aws_vpc.foo.id}"
  vpc_endpoint_type   = "Interface"
  service_name        = "com.amazonaws.us-west-2.ec2"
  security_group_ids  = ["${data.aws_security_group.default.id}"]
  private_dns_enabled = false
}

resource "aws_subnet" "sn" {
  vpc_id            = "${aws_vpc.foo.id}"
  availability_zone = "${data.aws_availability_zones.available.names[0]}"
	cidr_block        = "10.0.0.0/17"
  tags {
    Name = "tf-acc-vpc-endpoint-subnet-association"
  }
}

resource "aws_vpc_endpoint_subnet_association" "a" {
  vpc_endpoint_id = "${aws_vpc_endpoint.ec2.id}"
  subnet_id       = "${aws_subnet.sn.id}"
}
`

const testAccVpcEndpointSubnetAssociationConfig_multiple = `
provider "aws" {
  region = "us-west-2"
}

resource "aws_vpc" "foo" {
	cidr_block = "10.0.0.0/16"
  tags {
    Name = "terraform-testacc-vpc-endpoint-subnet-association"
  }
}

data "aws_security_group" "default" {
  vpc_id = "${aws_vpc.foo.id}"
  name   = "default"
}

data "aws_availability_zones" "available" {}

resource "aws_vpc_endpoint" "ec2" {
  vpc_id              = "${aws_vpc.foo.id}"
  vpc_endpoint_type   = "Interface"
  service_name        = "com.amazonaws.us-west-2.ec2"
  security_group_ids  = ["${data.aws_security_group.default.id}"]
  private_dns_enabled = false
}

resource "aws_subnet" "sn" {
  count = 3

  vpc_id            = "${aws_vpc.foo.id}"
  availability_zone = "${data.aws_availability_zones.available.names[count.index]}"
	cidr_block        = "${cidrsubnet(aws_vpc.foo.cidr_block, 2, count.index)}"
  tags {
    Name = "tf-acc-vpc-endpoint-subnet-association"
  }
}

resource "aws_vpc_endpoint_subnet_association" "a" {
  count = 3

  vpc_endpoint_id = "${aws_vpc_endpoint.ec2.id}"
  subnet_id       = "${aws_subnet.sn.*.id[count.index]}"
}
`
<commit_msg>Make aws_vpc_endpoint_subnet_association acceptance tests region-agnostic.<commit_after>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/ec2"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSVpcEndpointSubnetAssociation_basic(t *testing.T) {
	var vpce ec2.VpcEndpoint

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckVpcEndpointSubnetAssociationDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccVpcEndpointSubnetAssociationConfig_basic,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckVpcEndpointSubnetAssociationExists(
						"aws_vpc_endpoint_subnet_association.a", &vpce),
				),
			},
		},
	})
}

func TestAccAWSVpcEndpointSubnetAssociation_multiple(t *testing.T) {
	var vpce ec2.VpcEndpoint

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckVpcEndpointSubnetAssociationDestroy,
		Steps: []resource.TestStep{
			resource.TestStep{
				Config: testAccVpcEndpointSubnetAssociationConfig_multiple,
				Check: resource.ComposeTestCheckFunc(
					testAccCheckVpcEndpointSubnetAssociationExists(
						"aws_vpc_endpoint_subnet_association.a.0", &vpce),
					testAccCheckVpcEndpointSubnetAssociationExists(
						"aws_vpc_endpoint_subnet_association.a.1", &vpce),
					testAccCheckVpcEndpointSubnetAssociationExists(
						"aws_vpc_endpoint_subnet_association.a.2", &vpce),
				),
			},
		},
	})
}

func testAccCheckVpcEndpointSubnetAssociationDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).ec2conn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_vpc_endpoint_subnet_association" {
			continue
		}

		// Try to find the resource
		resp, err := conn.DescribeVpcEndpoints(&ec2.DescribeVpcEndpointsInput{
			VpcEndpointIds: aws.StringSlice([]string{rs.Primary.Attributes["vpc_endpoint_id"]}),
		})
		if err != nil {
			// Verify the error is what we want
			ec2err, ok := err.(awserr.Error)
			if !ok {
				return err
			}
			if ec2err.Code() != "InvalidVpcEndpointId.NotFound" {
				return err
			}
			return nil
		}

		vpce := resp.VpcEndpoints[0]
		if len(vpce.SubnetIds) > 0 {
			return fmt.Errorf(
				"Vpc endpoint %s has subnets", *vpce.VpcEndpointId)
		}
	}

	return nil
}

func testAccCheckVpcEndpointSubnetAssociationExists(n string, vpce *ec2.VpcEndpoint) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[n]
		if !ok {
			return fmt.Errorf("Not found: %s", n)
		}

		if rs.Primary.ID == "" {
			return fmt.Errorf("No ID is set")
		}

		conn := testAccProvider.Meta().(*AWSClient).ec2conn
		resp, err := conn.DescribeVpcEndpoints(&ec2.DescribeVpcEndpointsInput{
			VpcEndpointIds: aws.StringSlice([]string{rs.Primary.Attributes["vpc_endpoint_id"]}),
		})
		if err != nil {
			return err
		}
		if len(resp.VpcEndpoints) == 0 {
			return fmt.Errorf("Vpc endpoint not found")
		}

		*vpce = *resp.VpcEndpoints[0]

		if len(vpce.SubnetIds) == 0 {
			return fmt.Errorf("no subnet associations")
		}

		for _, id := range vpce.SubnetIds {
			if aws.StringValue(id) == rs.Primary.Attributes["subnet_id"] {
				return nil
			}
		}

		return fmt.Errorf("subnet association not found")
	}
}

const testAccVpcEndpointSubnetAssociationConfig_basic = `
resource "aws_vpc" "foo" {
  cidr_block = "10.0.0.0/16"
  tags {
    Name = "terraform-testacc-vpc-endpoint-subnet-association"
  }
}

data "aws_security_group" "default" {
  vpc_id = "${aws_vpc.foo.id}"
  name   = "default"
}

data "aws_region" "current" {}

data "aws_availability_zones" "available" {}

resource "aws_vpc_endpoint" "ec2" {
  vpc_id              = "${aws_vpc.foo.id}"
  vpc_endpoint_type   = "Interface"
  service_name        = "com.amazonaws.${data.aws_region.current.name}.ec2"
  security_group_ids  = ["${data.aws_security_group.default.id}"]
  private_dns_enabled = false
}

resource "aws_subnet" "sn" {
  vpc_id            = "${aws_vpc.foo.id}"
  availability_zone = "${data.aws_availability_zones.available.names[0]}"
  cidr_block        = "10.0.0.0/17"
  tags {
    Name = "tf-acc-vpc-endpoint-subnet-association"
  }
}

resource "aws_vpc_endpoint_subnet_association" "a" {
  vpc_endpoint_id = "${aws_vpc_endpoint.ec2.id}"
  subnet_id       = "${aws_subnet.sn.id}"
}
`

const testAccVpcEndpointSubnetAssociationConfig_multiple = `
resource "aws_vpc" "foo" {
  cidr_block = "10.0.0.0/16"
  tags {
    Name = "terraform-testacc-vpc-endpoint-subnet-association"
  }
}

data "aws_security_group" "default" {
  vpc_id = "${aws_vpc.foo.id}"
  name   = "default"
}

data "aws_region" "current" {}

data "aws_availability_zones" "available" {}

resource "aws_vpc_endpoint" "ec2" {
  vpc_id              = "${aws_vpc.foo.id}"
  vpc_endpoint_type   = "Interface"
  service_name        = "com.amazonaws.${data.aws_region.current.name}.ec2"
  security_group_ids  = ["${data.aws_security_group.default.id}"]
  private_dns_enabled = false
}

resource "aws_subnet" "sn" {
  count = 3

  vpc_id            = "${aws_vpc.foo.id}"
  availability_zone = "${data.aws_availability_zones.available.names[count.index]}"
  cidr_block        = "${cidrsubnet(aws_vpc.foo.cidr_block, 2, count.index)}"
  tags {
		Name = "${format("tf-acc-vpc-endpoint-subnet-association-%d", count.index + 1)}"
  }
}

resource "aws_vpc_endpoint_subnet_association" "a" {
  count = 3

  vpc_endpoint_id = "${aws_vpc_endpoint.ec2.id}"
  subnet_id       = "${aws_subnet.sn.*.id[count.index]}"
}
`
<|endoftext|>