<commit_before>package metrix

import (
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strconv"
	"strings"
)

const (
	fieldProcStatPid = iota
	fieldProcStatComm
	fieldProcStatState
	fieldProcStatPpid
	fieldProcStatPgrp
	fieldProcStatSession               // %d  (6) The session ID of the process.
	fieldProcStatTtyNr                 // %d   (7) The controlling terminal of the process.  (The minor device number is contained in the combination of bits 31
	fieldProcStatTpgid                 // %d    (8) The ID of the foreground process group of the controlling terminal of the process.
	fieldProcStatFlags                 // %u (%lu before Linux 2.6.22)
	fieldProcStatMinflt                // %lu  (10) The number of minor faults the process has made which have not required loading a memory page from disk.
	fieldProcStatCminflt               // %lu (11) The number of minor faults that the process's waited-for children have made.
	fieldProcStatMajflt                // %lu  (12) The number of major faults the process has made which have required loading a memory page from disk.
	fieldProcStatCmajflt               // %lu (13) The number of major faults that the process's waited-for children have made.
	fieldProcStatUtime                 // %lu   (14) Amount of time that this process has been scheduled in  user  mode,  measured  in  clock  ticks  (divide  by
	fieldProcStatStime                 // %lu   (15) Amount of time that this process has been scheduled in kernel mode,  measured  in  clock  ticks  (divide  by
	fieldProcStatCutime                // %ld  (16)  Amount  of time that this process's waited-for children have been scheduled in user mode, measured in clock
	fieldProcStatCstime                // %ld  (17) Amount of time that this process's waited-for children have been scheduled in kernel mode, measured in clock
	fieldProcStatPriority              // %ld
	fieldProcStatNice                  // %ld    (19) The nice value (see setpriority(2)), a value in the range 19 (low priority) to -20 (high priority).
	fieldProcStatNumThreads            // %ld
	fieldProcStatItRealValue           // %ld
	fieldProcStatStartTime             // %llu (was %lu before Linux 2.6)
	fieldProcStatVSize                 // %lu   (23) Virtual memory size in bytes.
	fieldProcStatRSS                   // %ld     (24)  Resident  Set  Size:  number  of  pages the process has in real memory.  This is just the pages which count
	fieldProcStatRSSlim                // %lu  (25) Current soft limit in bytes on the rss of the process; see the description of RLIMIT_RSS in getrlimit(2).
	fieldProcStatStartCode             // %lu (26) The address above which program text can run.
	fieldProcStatEndCode               // %lu (27) The address below which program text can run.
	fieldProcStatStartStack            // %lu (28) The address of the start (i.e., bottom) of the stack.
	fieldProcStatKstkesp               // %lu (29) The current value of ESP (stack pointer), as found in the kernel stack page for the process.
	fieldProcStatKstkeip               // %lu (30) The current EIP (instruction pointer).
	fieldProcStatSignal                // %lu  (31)  The bitmap of pending signals, displayed as a decimal number.  Obsolete, because it does not provide infor‐
	fieldProcStatBlocked               // %lu (32) The bitmap of blocked signals, displayed as a decimal number.  Obsolete, because it does not provide  infor‐
	fieldProcStatSigignore             // %lu (33)  The bitmap of ignored signals, displayed as a decimal number.
	fieldProcStatSigcatch              // %lu (34) The bitmap of caught signals, displayed as a decimal number. Obsolete, because it does not provide informa‐
	fieldProcStatWchan                 // %lu   (35)  This  is  the  "channel"  in  which the process is waiting.  It is the address of a system call, and can be
	fieldProcStatNswap                 // %lu   (36) Number of pages swapped (not maintained).
	fieldProcStatCnswap                // %lu  (37) Cumulative nswap for child processes (not maintained).
	fieldProcStatExit_signal           // %d (since Linux 2.1.22) (38) Signal to be sent to parent when we die.
	fieldProcStatProcessor             // %d (since Linux 2.2.8) (39) CPU number last executed on.
	fieldProcStatRt_priority           // %u (since Linux 2.5.19; was %lu before Linux 2.6.22) (40)  Real-time scheduling priority,
	fieldProcStatPolicy                // %u (since Linux 2.5.19; was %lu before Linux 2.6.22) (41) Scheduling policy (see sched_setscheduler(2)).
	fieldProcStatDelayacct_blkio_ticks // %llu (since Linux 2.6.18) (42) Aggregated block I/O delays, measured in clock ticks (centiseconds).
	fieldProcStatGuest_time            // %lu (since Linux 2.6.24) (43) Guest time of the process (time spent running a virtual CPU for a guest operating
	fieldProcStatCguest_time           // %ld (since Linux 2.6.24) (44) Guest time of the process's children, measured in clock ticks
)

func numeric(s string) bool {
	if len(s) == 0 {
		return false
	}
	for _, r := range s {
		if r < '0' || r > '9' {
			return false
		}
	}
	return true
}

func eachProcDir(fun func(p string) error) error {
	files, err := filepath.Glob("/proc/*")
	if err != nil {
		return err
	}
	for _, f := range files {
		if numeric(path.Base(f)) {
			err := fun(f)
			if err != nil {
				return err
			}
		}
	}
	return nil
}

func LoadProcStats() ([]*ProcStat, error) {
	defer benchmark("load proc stat")()
	out := []*ProcStat{}

	err := eachProcDir(func(f string) error {
		p, err := LoadProcStat(f + "/stat")
		if err != nil {
			return err
		}
		out = append(out, p)
		return nil
	})
	return out, err
}

func LoadProcStat(path string) (*ProcStat, error) {
	f, e := os.Open(path)
	if e != nil {
		return nil, e
	}
	p := &ProcStat{}
	return p, p.Load(f)
}

type ProcStat struct {
	Pid   int64  `json:"pid,omitempty,omitempty"`
	Comm  string `json:"comm,omitempty,omitempty"`
	State string `json:"state,omitempty,omitempty"`
	Ppid  int64  `json:"ppid,omitempty,omitempty"`
	Pgrp  int64  `json:"pgrp,omitempty,omitempty"`
	//Session int64 `json:"//session,omitempty"`
	//TtyNr   int64 `json:"//tty_nr,omitempty"`
	//Tpgid   int64 `json:"//tpgid,omitempty"`
	//Flags   int64 `json:"//flags,omitempty"`
	Minflt  int64 `json:"minflt,omitempty,omitempty"`
	Cminflt int64 `json:"cminflt,omitempty,omitempty"`
	Majflt  int64 `json:"majflt,omitempty,omitempty"`
	Cmajflt int64 `json:"cmajflt,omitempty,omitempty"`
	Utime   int64 `json:"utime,omitempty,omitempty"`
	Stime   int64 `json:"stime,omitempty,omitempty"`
	Cutime  int64 `json:"cutime,omitempty,omitempty"`
	Cstime  int64 `json:"cstime,omitempty,omitempty"`
	//Priority   int64 `json:"//priority,omitempty"`
	//Nice       int64 `json:"//nice,omitempty"`
	NumThreads    int64 `json:"num_threads,omitempty,omitempty"`
	VSize         int64 `json:"v_size,omitempty,omitempty"`
	RSS           int64 `json:"rss,omitempty,omitempty"`
	RSSlim        int64 `json:"rs_slim,omitempty,omitempty"`
	StatStartTime int64 `json:"stat_start_time,omitempty"`
}

func (p *ProcStat) Load(in io.Reader) error {
	b, e := ioutil.ReadAll(in)
	if e != nil {
		return e
	}
	for i, f := range strings.Fields(string(b)) {
		switch i {
		case fieldProcStatComm:
			p.Comm = f
		case fieldProcStatState:
			p.State = f
		default:
			value, e := strconv.ParseInt(f, 10, 64)
			if e != nil {
				continue
			}
			switch i {
			case fieldProcStatPid:
				p.Pid = value
			case fieldProcStatPpid:
				p.Ppid = value
			case fieldProcStatPgrp:
				p.Pgrp = value
			case fieldProcStatMinflt:
				p.Minflt = value
			case fieldProcStatCminflt:
				p.Cminflt = value
			case fieldProcStatMajflt:
				p.Majflt = value
			case fieldProcStatCmajflt:
				p.Cmajflt = value
			case fieldProcStatUtime:
				p.Utime = value
			case fieldProcStatStime:
				p.Stime = value
			case fieldProcStatCutime:
				p.Cutime = value
			case fieldProcStatCstime:
				p.Cstime = value
			case fieldProcStatNumThreads:
				p.NumThreads = value
			case fieldProcStatRSS:
				p.RSS = value
			case fieldProcStatRSSlim:
				p.RSSlim = value
			case fieldProcStatStartTime:
				p.StatStartTime = value
			case fieldProcStatVSize:
				p.VSize = value
			}
		}
	}
	return nil
}
<commit_msg>ignore errors when iterating stats<commit_after>package metrix

import (
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strconv"
	"strings"
)

const (
	fieldProcStatPid = iota
	fieldProcStatComm
	fieldProcStatState
	fieldProcStatPpid
	fieldProcStatPgrp
	fieldProcStatSession               // %d  (6) The session ID of the process.
	fieldProcStatTtyNr                 // %d   (7) The controlling terminal of the process.  (The minor device number is contained in the combination of bits 31
	fieldProcStatTpgid                 // %d    (8) The ID of the foreground process group of the controlling terminal of the process.
	fieldProcStatFlags                 // %u (%lu before Linux 2.6.22)
	fieldProcStatMinflt                // %lu  (10) The number of minor faults the process has made which have not required loading a memory page from disk.
	fieldProcStatCminflt               // %lu (11) The number of minor faults that the process's waited-for children have made.
	fieldProcStatMajflt                // %lu  (12) The number of major faults the process has made which have required loading a memory page from disk.
	fieldProcStatCmajflt               // %lu (13) The number of major faults that the process's waited-for children have made.
	fieldProcStatUtime                 // %lu   (14) Amount of time that this process has been scheduled in  user  mode,  measured  in  clock  ticks  (divide  by
	fieldProcStatStime                 // %lu   (15) Amount of time that this process has been scheduled in kernel mode,  measured  in  clock  ticks  (divide  by
	fieldProcStatCutime                // %ld  (16)  Amount  of time that this process's waited-for children have been scheduled in user mode, measured in clock
	fieldProcStatCstime                // %ld  (17) Amount of time that this process's waited-for children have been scheduled in kernel mode, measured in clock
	fieldProcStatPriority              // %ld
	fieldProcStatNice                  // %ld    (19) The nice value (see setpriority(2)), a value in the range 19 (low priority) to -20 (high priority).
	fieldProcStatNumThreads            // %ld
	fieldProcStatItRealValue           // %ld
	fieldProcStatStartTime             // %llu (was %lu before Linux 2.6)
	fieldProcStatVSize                 // %lu   (23) Virtual memory size in bytes.
	fieldProcStatRSS                   // %ld     (24)  Resident  Set  Size:  number  of  pages the process has in real memory.  This is just the pages which count
	fieldProcStatRSSlim                // %lu  (25) Current soft limit in bytes on the rss of the process; see the description of RLIMIT_RSS in getrlimit(2).
	fieldProcStatStartCode             // %lu (26) The address above which program text can run.
	fieldProcStatEndCode               // %lu (27) The address below which program text can run.
	fieldProcStatStartStack            // %lu (28) The address of the start (i.e., bottom) of the stack.
	fieldProcStatKstkesp               // %lu (29) The current value of ESP (stack pointer), as found in the kernel stack page for the process.
	fieldProcStatKstkeip               // %lu (30) The current EIP (instruction pointer).
	fieldProcStatSignal                // %lu  (31)  The bitmap of pending signals, displayed as a decimal number.  Obsolete, because it does not provide infor‐
	fieldProcStatBlocked               // %lu (32) The bitmap of blocked signals, displayed as a decimal number.  Obsolete, because it does not provide  infor‐
	fieldProcStatSigignore             // %lu (33)  The bitmap of ignored signals, displayed as a decimal number.
	fieldProcStatSigcatch              // %lu (34) The bitmap of caught signals, displayed as a decimal number. Obsolete, because it does not provide informa‐
	fieldProcStatWchan                 // %lu   (35)  This  is  the  "channel"  in  which the process is waiting.  It is the address of a system call, and can be
	fieldProcStatNswap                 // %lu   (36) Number of pages swapped (not maintained).
	fieldProcStatCnswap                // %lu  (37) Cumulative nswap for child processes (not maintained).
	fieldProcStatExit_signal           // %d (since Linux 2.1.22) (38) Signal to be sent to parent when we die.
	fieldProcStatProcessor             // %d (since Linux 2.2.8) (39) CPU number last executed on.
	fieldProcStatRt_priority           // %u (since Linux 2.5.19; was %lu before Linux 2.6.22) (40)  Real-time scheduling priority,
	fieldProcStatPolicy                // %u (since Linux 2.5.19; was %lu before Linux 2.6.22) (41) Scheduling policy (see sched_setscheduler(2)).
	fieldProcStatDelayacct_blkio_ticks // %llu (since Linux 2.6.18) (42) Aggregated block I/O delays, measured in clock ticks (centiseconds).
	fieldProcStatGuest_time            // %lu (since Linux 2.6.24) (43) Guest time of the process (time spent running a virtual CPU for a guest operating
	fieldProcStatCguest_time           // %ld (since Linux 2.6.24) (44) Guest time of the process's children, measured in clock ticks
)

func numeric(s string) bool {
	if len(s) == 0 {
		return false
	}
	for _, r := range s {
		if r < '0' || r > '9' {
			return false
		}
	}
	return true
}

func eachProcDir(fun func(p string) error) error {
	files, err := filepath.Glob("/proc/*")
	if err != nil {
		return err
	}
	for _, f := range files {
		if numeric(path.Base(f)) {
			err := fun(f)
			if err != nil {
				logger.Printf("ERROR: %q", err)
			}
		}
	}
	return nil
}

func LoadProcStats() ([]*ProcStat, error) {
	defer benchmark("load proc stat")()
	out := []*ProcStat{}

	err := eachProcDir(func(f string) error {
		p, err := LoadProcStat(f + "/stat")
		if err != nil {
			return err
		}
		out = append(out, p)
		return nil
	})
	return out, err
}

func LoadProcStat(path string) (*ProcStat, error) {
	f, e := os.Open(path)
	if e != nil {
		return nil, e
	}
	p := &ProcStat{}
	return p, p.Load(f)
}

type ProcStat struct {
	Pid   int64  `json:"pid,omitempty,omitempty"`
	Comm  string `json:"comm,omitempty,omitempty"`
	State string `json:"state,omitempty,omitempty"`
	Ppid  int64  `json:"ppid,omitempty,omitempty"`
	Pgrp  int64  `json:"pgrp,omitempty,omitempty"`
	//Session int64 `json:"//session,omitempty"`
	//TtyNr   int64 `json:"//tty_nr,omitempty"`
	//Tpgid   int64 `json:"//tpgid,omitempty"`
	//Flags   int64 `json:"//flags,omitempty"`
	Minflt  int64 `json:"minflt,omitempty,omitempty"`
	Cminflt int64 `json:"cminflt,omitempty,omitempty"`
	Majflt  int64 `json:"majflt,omitempty,omitempty"`
	Cmajflt int64 `json:"cmajflt,omitempty,omitempty"`
	Utime   int64 `json:"utime,omitempty,omitempty"`
	Stime   int64 `json:"stime,omitempty,omitempty"`
	Cutime  int64 `json:"cutime,omitempty,omitempty"`
	Cstime  int64 `json:"cstime,omitempty,omitempty"`
	//Priority   int64 `json:"//priority,omitempty"`
	//Nice       int64 `json:"//nice,omitempty"`
	NumThreads    int64 `json:"num_threads,omitempty,omitempty"`
	VSize         int64 `json:"v_size,omitempty,omitempty"`
	RSS           int64 `json:"rss,omitempty,omitempty"`
	RSSlim        int64 `json:"rs_slim,omitempty,omitempty"`
	StatStartTime int64 `json:"stat_start_time,omitempty"`
}

func (p *ProcStat) Load(in io.Reader) error {
	b, e := ioutil.ReadAll(in)
	if e != nil {
		return e
	}
	for i, f := range strings.Fields(string(b)) {
		switch i {
		case fieldProcStatComm:
			p.Comm = f
		case fieldProcStatState:
			p.State = f
		default:
			value, e := strconv.ParseInt(f, 10, 64)
			if e != nil {
				continue
			}
			switch i {
			case fieldProcStatPid:
				p.Pid = value
			case fieldProcStatPpid:
				p.Ppid = value
			case fieldProcStatPgrp:
				p.Pgrp = value
			case fieldProcStatMinflt:
				p.Minflt = value
			case fieldProcStatCminflt:
				p.Cminflt = value
			case fieldProcStatMajflt:
				p.Majflt = value
			case fieldProcStatCmajflt:
				p.Cmajflt = value
			case fieldProcStatUtime:
				p.Utime = value
			case fieldProcStatStime:
				p.Stime = value
			case fieldProcStatCutime:
				p.Cutime = value
			case fieldProcStatCstime:
				p.Cstime = value
			case fieldProcStatNumThreads:
				p.NumThreads = value
			case fieldProcStatRSS:
				p.RSS = value
			case fieldProcStatRSSlim:
				p.RSSlim = value
			case fieldProcStatStartTime:
				p.StatStartTime = value
			case fieldProcStatVSize:
				p.VSize = value
			}
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package mstate_test

import (
	. "launchpad.net/gocheck"
	state "launchpad.net/juju-core/mstate"
)

type AssignSuite struct {
	ConnSuite
	charm   *state.Charm
	service *state.Service
	unit    *state.Unit
}

var _ = Suite(&AssignSuite{})

func (s *AssignSuite) SetUpTest(c *C) {
	s.ConnSuite.SetUpTest(c)
	s.charm = s.AddTestingCharm(c, "dummy")
	var err error
	s.service, err = s.State.AddService("wordpress", s.charm)
	c.Assert(err, IsNil)
	s.unit, err = s.service.AddUnit()
	c.Assert(err, IsNil)
	// Create root machine that shouldn't be used unless requested explicitly.
	_, err = s.State.AddMachine()
	c.Assert(err, IsNil)
}

func (s *AssignSuite) TestUnassignUnitFromMachineWithoutBeingAssigned(c *C) {
	// When unassigning a machine from a unit, it is possible that
	// the machine has not been previously assigned, or that it
	// was assigned but the state changed beneath us.  In either
	// case, the end state is the intended state, so we simply
	// move forward without any errors here, to avoid having to
	// handle the extra complexity of dealing with the concurrency
	// problems.
	err := s.unit.UnassignFromMachine()
	c.Assert(err, IsNil)

	// Check that the unit has no machine assigned.
	_, err = s.unit.AssignedMachineId()
	c.Assert(err, ErrorMatches, `cannot get machine id of unit "wordpress/0": unit not assigned to machine`)
}

func (s *AssignSuite) TestAssignUnitToMachineAgainFails(c *C) {
	// Check that assigning an already assigned unit to
	// a machine fails if it isn't precisely the same
	// machine.
	machineOne, err := s.State.AddMachine()
	c.Assert(err, IsNil)
	machineTwo, err := s.State.AddMachine()
	c.Assert(err, IsNil)

	err = s.unit.AssignToMachine(machineOne)
	c.Assert(err, IsNil)

	// Assigning the unit to the same machine should return no error.
	err = s.unit.AssignToMachine(machineOne)
	c.Assert(err, IsNil)

	// Assigning the unit to a different machine should fail.
	// BUG(aram): use error strings from state.
	err = s.unit.AssignToMachine(machineTwo)
	c.Assert(err, ErrorMatches, `cannot assign unit "wordpress/0" to machine 2: .*`)

	machineId, err := s.unit.AssignedMachineId()
	c.Assert(err, IsNil)
	c.Assert(machineId, Equals, 1)
}
<commit_msg>mstate: continued completion of assign_test.go<commit_after>package mstate_test

import (
	. "launchpad.net/gocheck"
	state "launchpad.net/juju-core/mstate"
)

type AssignSuite struct {
	ConnSuite
	charm   *state.Charm
	service *state.Service
	unit    *state.Unit
}

var _ = Suite(&AssignSuite{})

func (s *AssignSuite) SetUpTest(c *C) {
	s.ConnSuite.SetUpTest(c)
	s.charm = s.AddTestingCharm(c, "dummy")
	var err error
	s.service, err = s.State.AddService("wordpress", s.charm)
	c.Assert(err, IsNil)
	s.unit, err = s.service.AddUnit()
	c.Assert(err, IsNil)
	// Create root machine that shouldn't be used unless requested explicitly.
	_, err = s.State.AddMachine()
	c.Assert(err, IsNil)
}

func (s *AssignSuite) TestUnassignUnitFromMachineWithoutBeingAssigned(c *C) {
	// When unassigning a machine from a unit, it is possible that
	// the machine has not been previously assigned, or that it
	// was assigned but the state changed beneath us.  In either
	// case, the end state is the intended state, so we simply
	// move forward without any errors here, to avoid having to
	// handle the extra complexity of dealing with the concurrency
	// problems.
	err := s.unit.UnassignFromMachine()
	c.Assert(err, IsNil)

	// Check that the unit has no machine assigned.
	_, err = s.unit.AssignedMachineId()
	c.Assert(err, ErrorMatches, `cannot get machine id of unit "wordpress/0": unit not assigned to machine`)
}

func (s *AssignSuite) TestAssignUnitToMachineAgainFails(c *C) {
	// Check that assigning an already assigned unit to
	// a machine fails if it isn't precisely the same
	// machine.
	machineOne, err := s.State.AddMachine()
	c.Assert(err, IsNil)
	machineTwo, err := s.State.AddMachine()
	c.Assert(err, IsNil)

	err = s.unit.AssignToMachine(machineOne)
	c.Assert(err, IsNil)

	// Assigning the unit to the same machine should return no error.
	err = s.unit.AssignToMachine(machineOne)
	c.Assert(err, IsNil)

	// Assigning the unit to a different machine should fail.
	// BUG(aram): use error strings from state.
	err = s.unit.AssignToMachine(machineTwo)
	c.Assert(err, ErrorMatches, `cannot assign unit "wordpress/0" to machine 2: .*`)

	machineId, err := s.unit.AssignedMachineId()
	c.Assert(err, IsNil)
	c.Assert(machineId, Equals, 1)
}

func (s *AssignSuite) TestUnassignUnitFromMachineWithChangingState(c *C) {
	// Check that unassigning while the state changes fails nicely.
	// Remove the unit for the tests.
	err := s.unit.Die()
	c.Assert(err, IsNil)
	err = s.service.RemoveUnit(s.unit)
	c.Assert(err, IsNil)

	err = s.unit.UnassignFromMachine()
	c.Assert(err, ErrorMatches, `cannot unassign unit "wordpress/0" from machine: not found`)
	_, err = s.unit.AssignedMachineId()
	c.Assert(err, ErrorMatches, `cannot get machine id of unit "wordpress/0": unit not assigned to machine`)

	err = s.State.RemoveService(s.service)
	c.Assert(err, IsNil)

	err = s.unit.UnassignFromMachine()
	c.Assert(err, ErrorMatches, `cannot unassign unit "wordpress/0" from machine: not found`)
	_, err = s.unit.AssignedMachineId()
	c.Assert(err, ErrorMatches, `cannot get machine id of unit "wordpress/0": unit not assigned to machine`)
}

func (s *AssignSuite) TestAssignSubordinatesToMachine(c *C) {
	// Check that assigning a principal unit assigns its subordinates too.
	subCharm := s.AddTestingCharm(c, "logging")
	logService1, err := s.State.AddService("logging1", subCharm)
	c.Assert(err, IsNil)
	logService2, err := s.State.AddService("logging2", subCharm)
	c.Assert(err, IsNil)
	log1Unit, err := logService1.AddUnitSubordinateTo(s.unit)
	c.Assert(err, IsNil)
	log2Unit, err := logService2.AddUnitSubordinateTo(s.unit)
	c.Assert(err, IsNil)

	m1, err := s.State.AddMachine()
	c.Assert(err, IsNil)
	err = s.unit.AssignToMachine(m1)
	c.Assert(err, IsNil)

	id, err := log1Unit.AssignedMachineId()
	c.Assert(err, IsNil)
	c.Check(id, Equals, m1.Id())
	id, err = log2Unit.AssignedMachineId()
	c.Check(id, Equals, m1.Id())

	// Check that unassigning the principal unassigns the
	// subordinates too.
	err = s.unit.UnassignFromMachine()
	c.Assert(err, IsNil)
	_, err = log1Unit.AssignedMachineId()
	c.Assert(err, ErrorMatches, `cannot get machine id of unit "logging1/0": unit not assigned to machine`)
	_, err = log2Unit.AssignedMachineId()
	c.Assert(err, ErrorMatches, `cannot get machine id of unit "logging2/0": unit not assigned to machine`)
}
<|endoftext|>


<commit_before>package multi

import (
	"io"
	"net/http"
	"os"
	"path"
	"time"

	"github.com/gotgo/fw/me"
)

func download(url, filename, folder string, timeout time.Duration) (*FileDownloadOutput, error) {
	output := &FileDownloadOutput{}

	//create file first, so we know we're able to save to disk
	fp := path.Join(folder, filename)
	file, err := os.Create(fp)
	if err != nil {
		return nil, me.Err(err, "create file")
	}
	defer file.Close()

	client := http.Client{
		Timeout: timeout,
	}
	resp, err := client.Get(url)
	if err != nil {
		return nil, me.Err(err, "failed to get URL ")
	}
	defer resp.Body.Close()
	//output.ContentType = resp.ContentType
	//d.Track.Duration("download", started)
	//d.Track.Size("download", resp.ContentLength)

	//save to disk
	if size, err := io.Copy(file, resp.Body); err != nil {
		return nil, me.Err(err, "failed to save downloaded file")
	} else if size == 0 {
		return nil, me.NewErr("downloaded file size was zero on copy")
	} else if size > 0 {
		output.Size = size
		//	d.Track.Size("saved", size)
	}
	file.Sync()
	file.Close()
	output.Path = fp
	return output, nil
}

const defaultTimeout = time.Second * 30

type FileDownloadTask struct {
	Folder  string
	Timeout time.Duration
}

func (d *FileDownloadTask) Run(input interface{}) (interface{}, error) {
	in, ok := input.(*FileDownloadInput)
	if !ok {
		panic("unexpected type")
	}
	timeout := d.Timeout
	if timeout <= 0 {
		timeout = defaultTimeout
	}
	return download(in.Url, in.Filename, d.Folder, timeout)
}

func (d *FileDownloadTask) Name() string {
	return "fileDownload"
}

type FileDownloadInput struct {
	Url      string
	Filename string
}

type FileDownloadOutput struct {
	Path        string
	Size        int64
	ContentType string
}
<commit_msg>rewrite<commit_after>package multi

import (
	"io/ioutil"
	"net/http"
	"path"
	"time"

	"github.com/gotgo/fw/me"
)

func download(url, filename, folder string, timeout time.Duration) (*FileDownloadOutput, error) {
	fp := path.Join(folder, filename)
	output := &FileDownloadOutput{
		Path: fp,
	}

	client := http.Client{
		Timeout: timeout,
	}

	resp, err := client.Get(url)
	if err != nil {
		return nil, me.Err(err, "failed to get URL ")
	}

	bts, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, me.Err(err, "failed to read all bytes")
	}

	resp.Body.Close()

	ioutil.WriteFile(fp, bts, 0666)

	//output.ContentType = resp.ContentType
	//d.Track.Duration("download", started)
	//d.Track.Size("download", resp.ContentLength)

	return output, nil
}

const defaultTimeout = time.Second * 60

type FileDownloadTask struct {
	Folder  string
	Timeout time.Duration
}

func (d *FileDownloadTask) Run(input interface{}) (interface{}, error) {
	in, ok := input.(*FileDownloadInput)
	if !ok {
		panic("unexpected type")
	}
	timeout := d.Timeout
	if timeout <= 0 {
		timeout = defaultTimeout
	}
	return download(in.Url, in.Filename, d.Folder, timeout)
}

func (d *FileDownloadTask) Name() string {
	return "fileDownload"
}

type FileDownloadInput struct {
	Url      string
	Filename string
}

type FileDownloadOutput struct {
	Path        string
	Size        int64
	ContentType string
}
<|endoftext|>


<commit_before>package nameserver

import (
	"github.com/fsouza/go-dockerclient"
)

func checkError(err error, apiPath string) {
	if err != nil {
		Error.Fatalf("Unable to connect to Docker API on %s: %s", apiPath, err)
	}
}

func StartUpdater(apiPath string, zone Zone) error {
	client, err := docker.NewClient(apiPath)
	checkError(err, apiPath)

	events := make(chan *docker.APIEvents)
	err = client.AddEventListener(events)
	checkError(err, apiPath)

	Info.Printf("Using Docker API on %s", apiPath)

	go func() {
		for event := range events {
			handleEvent(zone, event, client)
		}
	}()
	return nil
}

func handleEvent(zone Zone, event *docker.APIEvents, client *docker.Client) error {
	switch event.Status {
	case "die":
		id := event.ID
		Info.Printf("Container %s down. Removing records", id)
		zone.DeleteRecordsFor(id)
	}
	return nil
}
<commit_msg>Fetch docker version, to check things are working<commit_after>package nameserver

import (
	"github.com/fsouza/go-dockerclient"
)

func checkError(err error, apiPath string) {
	if err != nil {
		Error.Fatalf("Unable to connect to Docker API on %s: %s", apiPath, err)
	}
}

func StartUpdater(apiPath string, zone Zone) error {
	client, err := docker.NewClient(apiPath)
	checkError(err, apiPath)

	env, err := client.Version()
	checkError(err, apiPath)

	events := make(chan *docker.APIEvents)
	err = client.AddEventListener(events)
	checkError(err, apiPath)

	Info.Printf("Using Docker API on %s: %v", apiPath, env)

	go func() {
		for event := range events {
			handleEvent(zone, event, client)
		}
	}()
	return nil
}

func handleEvent(zone Zone, event *docker.APIEvents, client *docker.Client) error {
	switch event.Status {
	case "die":
		id := event.ID
		Info.Printf("Container %s down. Removing records", id)
		zone.DeleteRecordsFor(id)
	}
	return nil
}
<|endoftext|>


<commit_before>package githubclient

import (
	"bytes"
	"cred-alert/metrics"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"time"

	"code.cloudfoundry.org/lager"
	"github.com/cloudfoundry/gunk/urljoiner"
	"github.com/google/go-github/github"
)

const DefaultGitHubURL = "https://api.github.com/"
const ErrNotFound = Error("githubclient-not-found")

type Error string

func (e Error) Error() string { return string(e) }

//go:generate counterfeiter . Client

type Client interface {
	CompareRefs(logger lager.Logger, owner, repo, base, head string) (io.Reader, error)
	ArchiveLink(owner, repo, ref string) (*url.URL, error)
	CommitInfo(logger lager.Logger, owner, repo, sha string) (CommitInfo, error)
}

type CommitInfo struct {
	Message string
	Parents []string
}

type client struct {
	baseURL        string
	httpClient     *http.Client
	rateLimitGauge metrics.Gauge
}

func NewClient(baseURL string, httpClient *http.Client, emitter metrics.Emitter) *client {
	return &client{
		baseURL:        baseURL,
		httpClient:     httpClient,
		rateLimitGauge: emitter.Gauge("cred_alert.github_remaining_requests"),
	}
}

func (c *client) CompareRefs(logger lager.Logger, owner, repo, base, head string) (io.Reader, error) {
	logger = logger.Session("compare-refs")
	logger.Debug("starting")

	url := urljoiner.Join(c.baseURL, "repos", owner, repo, "compare", base+"..."+head)

	response, err := c.responseFrom(logger, url, map[string]string{"Accept": "application/vnd.github.diff"})
	if err != nil {
		logger.Error("failed", err)
		return nil, err
	}

	body, err := c.bodyFromResponse(logger, response)
	if err != nil {
		logger.Error("failed", err)
		return nil, err
	}

	if response.StatusCode != http.StatusOK {
		err := fmt.Errorf("bad response (!200): %d", response.StatusCode)
		logger.Error("failed", err, lager.Data{
			"status": fmt.Sprintf("%s (%d)", http.StatusText(response.StatusCode), response.StatusCode),
			"body":   body,
		})
		return nil, err
	}

	logger.Debug("done")
	return bytes.NewReader(body), nil
}

func (c *client) ArchiveLink(owner, repo string, ref string) (*url.URL, error) {
	reqUrl := urljoiner.Join(c.baseURL, "repos", owner, repo, "zipball", ref)

	req, err := http.NewRequest("GET", reqUrl, nil)
	if err != nil {
		return nil, err
	}

	var resp *http.Response
	resp, err = c.httpClient.Transport.RoundTrip(req)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode == http.StatusNotFound {
		return nil, ErrNotFound
	}
	if resp.StatusCode != http.StatusFound {
		return nil, fmt.Errorf("Unexpected response status code: %d", resp.StatusCode)
	}

	return url.Parse(resp.Header.Get("Location"))
}

type commit struct {
	Message string `json:"message"`
}

type parent struct {
	SHA string `json:"sha"`
}

var commitResponse struct {
	Commit  commit   `json:"commit"`
	Parents []parent `json:"parents"`
}

func (c *client) CommitInfo(logger lager.Logger, owner, repo, sha string) (CommitInfo, error) {
	logger = logger.Session("commit-info", lager.Data{
		"Owner": owner,
		"Repo":  repo,
		"SHA":   sha,
	})
	logger.Debug("starting")

	url := urljoiner.Join(c.baseURL, "repos", owner, repo, "commits", sha)

	response, err := c.responseFrom(logger, url, map[string]string{})
	if err != nil {
		logger.Error("failed", err)
		return CommitInfo{}, err
	}

	body, err := c.bodyFromResponse(logger, response)
	if err != nil {
		logger.Error("failed", err)
		return CommitInfo{}, err
	}

	if response.StatusCode != http.StatusOK {
		err := fmt.Errorf("bad response (!200): %d", response.StatusCode)
		logger.Error("failed", err, lager.Data{
			"status": fmt.Sprintf("%s (%d)", http.StatusText(response.StatusCode), response.StatusCode),
			"body":   body,
		})

		if response.StatusCode == http.StatusNotFound {
			return CommitInfo{}, ErrNotFound
		} else {
			return CommitInfo{}, err
		}
	}

	if err := json.Unmarshal(body, &commitResponse); err != nil {
		logger.Error("failed", err)
		return CommitInfo{}, err
	}

	parentShas := []string{}
	for _, parent := range commitResponse.Parents {
		parentShas = append(parentShas, parent.SHA)
	}

	logger.Debug("done")
	return CommitInfo{
		Message: commitResponse.Commit.Message,
		Parents: parentShas,
	}, nil
}

func (c *client) rateFromResponse(logger lager.Logger, response *http.Response) (github.Rate, error) {
	logger = logger.Session("rate-from-response")
	logger.Debug("starting")

	header := response.Header
	reset, err := strconv.ParseInt(header.Get("X-Ratelimit-Reset"), 10, 64)
	if err != nil {
		logger.Error("failed", err)
		return github.Rate{}, err
	}

	timestamp := github.Timestamp{Time: time.Unix(reset, 0)}

	remain, err := strconv.Atoi(header.Get("X-Ratelimit-Remaining"))
	if err != nil {
		logger.Error("failed", err)
		return github.Rate{}, err
	}

	logger.Debug("done")
	return github.Rate{
		Remaining: remain,
		Reset:     timestamp,
	}, nil
}

func (c *client) bodyFromResponse(logger lager.Logger, response *http.Response) ([]byte, error) {
	defer response.Body.Close()
	if response == nil {
		return []byte{}, errors.New("nil-response")
	}
	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		logger.Error("failed", err)
		return []byte{}, err
	}

	if ratelimit, err := c.rateFromResponse(logger, response); err == nil {
		c.rateLimitGauge.Update(logger, float32(ratelimit.Remaining))
	}

	logger.Debug("done")
	return body, nil
}

func (c *client) responseFrom(logger lager.Logger, url string, headers map[string]string) (*http.Response, error) {
	logger = logger.Session("response-body-from")
	logger.Info("starting", lager.Data{"url": url})

	request, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, err
	}

	for headerName, headerValue := range headers {
		request.Header.Set(headerName, headerValue)
	}

	response, err := c.httpClient.Do(request)
	if err != nil {
		logger.Error("failed", err)
		return nil, err
	}

	return response, nil
}
<commit_msg>Update githubclient.Client<commit_after>package githubclient

import (
	"bytes"
	"cred-alert/metrics"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"

	"code.cloudfoundry.org/lager"
	"github.com/cloudfoundry/gunk/urljoiner"
)

const DefaultGitHubURL = "https://api.github.com/"
const ErrNotFound = Error("githubclient-not-found")

type Error string

func (e Error) Error() string { return string(e) }

//go:generate counterfeiter . Client

type Client interface {
	CompareRefs(logger lager.Logger, owner, repo, base, head string) (io.Reader, error)
	ArchiveLink(owner, repo, ref string) (*url.URL, error)
	CommitInfo(logger lager.Logger, owner, repo, sha string) (CommitInfo, error)
}

type CommitInfo struct {
	Message string
	Parents []string
}

type client struct {
	baseURL        string
	httpClient     *http.Client
	rateLimitGauge metrics.Gauge
}

func NewClient(baseURL string, httpClient *http.Client, emitter metrics.Emitter) *client {
	return &client{
		baseURL:        baseURL,
		httpClient:     httpClient,
		rateLimitGauge: emitter.Gauge("cred_alert.github_remaining_requests"),
	}
}

func (c *client) CompareRefs(logger lager.Logger, owner, repo, base, head string) (io.Reader, error) {
	logger = logger.Session("compare-refs")
	logger.Debug("starting")

	url := urljoiner.Join(c.baseURL, "repos", owner, repo, "compare", base+"..."+head)

	request, err := http.NewRequest("GET", url, nil)
	if err != nil {
		logger.Error("failed", err)
		return nil, err
	}
	request.Header.Set("Accept", "application/vnd.github.diff")

	response, err := c.doRequest(logger, request)
	if err != nil {
		logger.Error("failed", err)
		return nil, err
	}
	defer response.Body.Close()

	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		logger.Error("failed", err)
		return nil, err
	}

	if response.StatusCode != http.StatusOK {
		err := fmt.Errorf("bad response (!200): %d", response.StatusCode)
		logger.Error("failed", err, lager.Data{
			"status": fmt.Sprintf("%s (%d)", http.StatusText(response.StatusCode), response.StatusCode),
			"body":   body,
		})
		return nil, err
	}

	logger.Debug("done")
	return bytes.NewReader(body), nil
}

func (c *client) ArchiveLink(owner, repo string, ref string) (*url.URL, error) {
	reqUrl := urljoiner.Join(c.baseURL, "repos", owner, repo, "zipball", ref)

	req, err := http.NewRequest("GET", reqUrl, nil)
	if err != nil {
		return nil, err
	}

	var resp *http.Response
	resp, err = c.httpClient.Transport.RoundTrip(req)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode == http.StatusNotFound {
		return nil, ErrNotFound
	}
	if resp.StatusCode != http.StatusFound {
		return nil, fmt.Errorf("Unexpected response status code: %d", resp.StatusCode)
	}

	return url.Parse(resp.Header.Get("Location"))
}

type commit struct {
	Message string `json:"message"`
}

type parent struct {
	SHA string `json:"sha"`
}

var commitResponse struct {
	Commit  commit   `json:"commit"`
	Parents []parent `json:"parents"`
}

func (c *client) CommitInfo(logger lager.Logger, owner, repo, sha string) (CommitInfo, error) {
	logger = logger.Session("commit-info", lager.Data{
		"Owner": owner,
		"Repo":  repo,
		"SHA":   sha,
	})
	logger.Debug("starting")

	url := urljoiner.Join(c.baseURL, "repos", owner, repo, "commits", sha)

	request, err := http.NewRequest("GET", url, nil)
	if err != nil {
		logger.Error("failed", err)
		return CommitInfo{}, err
	}

	response, err := c.doRequest(logger, request)
	if err != nil {
		logger.Error("failed", err)
		return CommitInfo{}, err
	}
	defer response.Body.Close()

	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		logger.Error("failed", err)
		return CommitInfo{}, err
	}

	if response.StatusCode != http.StatusOK {
		err := fmt.Errorf("bad response (!200): %d", response.StatusCode)
		logger.Error("failed", err, lager.Data{
			"status": fmt.Sprintf("%s (%d)", http.StatusText(response.StatusCode), response.StatusCode),
			"body":   body,
		})

		if response.StatusCode == http.StatusNotFound {
			return CommitInfo{}, ErrNotFound
		} else {
			return CommitInfo{}, err
		}
	}

	if err := json.Unmarshal(body, &commitResponse); err != nil {
		logger.Error("failed", err)
		return CommitInfo{}, err
	}

	parentShas := []string{}
	for _, parent := range commitResponse.Parents {
		parentShas = append(parentShas, parent.SHA)
	}

	logger.Debug("done")
	return CommitInfo{
		Message: commitResponse.Commit.Message,
		Parents: parentShas,
	}, nil
}

func (c *client) doRequest(logger lager.Logger, request *http.Request) (*http.Response, error) {
	response, err := c.httpClient.Do(request)
	if err != nil {
		return nil, err
	}

	remain, err := strconv.Atoi(response.Header.Get("X-RateLimit-Remaining"))
	if err == nil {
		c.rateLimitGauge.Update(logger, float32(remain))
	}

	return response, nil
}
<|endoftext|>


<commit_before>package mms

import (
	"net/http"
	"testing"
	"time"

	messagebird "github.com/messagebird/go-rest-api/v9"
	"github.com/messagebird/go-rest-api/v9/internal/mbtest"
	"github.com/stretchr/testify/assert"
)

func TestMain(m *testing.M) {
	mbtest.EnableServer(m)
}

func TestCreate(t *testing.T) {
	mbtest.WillReturnTestdata(t, "mmsMessageObject.json", http.StatusOK)
	client := mbtest.Client(t)

	scheduledDateTime := time.Now()

	req := &CreateRequest{
		Body:              "Hello World",
		MediaUrls:         []string{"https://media.giphy.com/media/Vuw9m5wXviFIQ/giphy.gif", "https://media.giphy.com/media/pxy9QQUMF0glq/giphy.gif"},
		Subject:           "TestSubject",
		Reference:         "TestReference",
		ScheduledDatetime: &scheduledDateTime,
	}

	message, err := Create(client, req)

	assert.NoError(t, err)
	assert.Equal(t, "6d9e7100b1f9406c81a3c303c30ccf05", message.ID)
	assert.Equal(t, "https://rest.messagebird.com/mms/6d9e7100b1f9406c81a3c303c30ccf05", message.HRef)
	assert.Equal(t, "mt", message.Direction)
	assert.Equal(t, "TestName", message.Originator)
	assert.Equal(t, "Hello World", message.Body)
	assert.Equal(t, "https://media.giphy.com/media/Vuw9m5wXviFIQ/giphy.gif", message.MediaUrls[0])
	assert.Equal(t, "https://media.giphy.com/media/pxy9QQUMF0glq/giphy.gif", message.MediaUrls[1])
	assert.Equal(t, "TestReference", message.Reference)
	assert.Equal(t, "TestSubject", message.Subject)
	assert.Nil(t, message.ScheduledDatetime)
	assert.Equal(t, "2022-05-20T12:50:28Z", message.CreatedDatetime.Format(time.RFC3339))
	assert.Equal(t, 1, message.Recipients.TotalCount)
	assert.Equal(t, 1, message.Recipients.TotalSentCount)
	assert.Equal(t, int64(31612345678), message.Recipients.Items[0].Recipient)
	assert.Equal(t, "sent", message.Recipients.Items[0].Status)
	assert.Equal(t, "2022-05-20T12:50:28Z", message.Recipients.Items[0].StatusDatetime.Format(time.RFC3339))

	_, ok := err.(messagebird.ErrorResponse)
	assert.False(t, ok)
}

func TestRead(t *testing.T) {
	mbtest.WillReturnTestdata(t, "mmsMessageObject.json", http.StatusOK)
	client := mbtest.Client(t)

	message, err := Read(client, "6d9e7100b1f9406c81a3c303c30ccf05")

	assert.NoError(t, err)
	assert.Equal(t, "6d9e7100b1f9406c81a3c303c30ccf05", message.ID)
	assert.Equal(t, "https://rest.messagebird.com/mms/6d9e7100b1f9406c81a3c303c30ccf05", message.HRef)
	assert.Equal(t, "mt", message.Direction)
	assert.Equal(t, "TestName", message.Originator)
	assert.Equal(t, "Hello World", message.Body)
	assert.Equal(t, "https://media.giphy.com/media/Vuw9m5wXviFIQ/giphy.gif", message.MediaUrls[0])
	assert.Equal(t, "https://media.giphy.com/media/pxy9QQUMF0glq/giphy.gif", message.MediaUrls[1])
	assert.Equal(t, "TestReference", message.Reference)
	assert.Equal(t, "TestSubject", message.Subject)
	assert.Nil(t, message.ScheduledDatetime)
	assert.Equal(t, "2022-05-20T12:50:28Z", message.CreatedDatetime.Format(time.RFC3339))
	assert.Equal(t, 1, message.Recipients.TotalCount)
	assert.Equal(t, 1, message.Recipients.TotalSentCount)
	assert.Equal(t, int64(31612345678), message.Recipients.Items[0].Recipient)
	assert.Equal(t, "sent", message.Recipients.Items[0].Status)
	assert.Equal(t, "2022-05-20T12:50:28Z", message.Recipients.Items[0].StatusDatetime.Format(time.RFC3339))

	_, ok := err.(messagebird.ErrorResponse)
	assert.False(t, ok)
}

//func TestCreateError(t *testing.T) {
//	mbtest.WillReturnAccessKeyError()
//	client := mbtest.Client(t)
//
//	scheduledDateTime := time.Now()
//
//	req := &CreateRequest{
//		Body:              "Hello World",
//		ScheduledDatetime: &scheduledDateTime,
//	}
//
//	_, err := Create(client, req)
//
//	errorResponse, ok := err.(messagebird.ErrorResponse)
//	assert.True(t, ok)
//	assert.Len(t, errorResponse.Errors, 1)
//	assert.Equal(t, 2, errorResponse.Errors[0].Code)
//	assert.Equal(t, "access_key", errorResponse.Errors[0].Parameter)
//}

//func TestCreateWithEmptyParams(t *testing.T) {
//	client := mbtest.Client(t)
//
//	scheduledDateTime := time.Now()
//
//	params := &CreateRequest{
//		Body:              "",
//		Subject:           "",
//		Reference:         "",
//		ScheduledDatetime: &scheduledDateTime,
//	}
//
//	_, err := Create(client, "TestName", []string{"31612345678"}, params)
//	assert.EqualError(t, err, "Body or MediaUrls is required")
//}
<commit_msg>clear up<commit_after>package mms

import (
	"net/http"
	"testing"
	"time"

	messagebird "github.com/messagebird/go-rest-api/v9"
	"github.com/messagebird/go-rest-api/v9/internal/mbtest"
	"github.com/stretchr/testify/assert"
)

func TestMain(m *testing.M) {
	mbtest.EnableServer(m)
}

func TestCreate(t *testing.T) {
	mbtest.WillReturnTestdata(t, "mmsMessageObject.json", http.StatusOK)
	client := mbtest.Client(t)

	scheduledDateTime := time.Now()

	req := &CreateRequest{
		Body:              "Hello World",
		MediaUrls:         []string{"https://media.giphy.com/media/Vuw9m5wXviFIQ/giphy.gif", "https://media.giphy.com/media/pxy9QQUMF0glq/giphy.gif"},
		Subject:           "TestSubject",
		Reference:         "TestReference",
		ScheduledDatetime: &scheduledDateTime,
	}

	message, err := Create(client, req)

	assert.NoError(t, err)
	assert.Equal(t, "6d9e7100b1f9406c81a3c303c30ccf05", message.ID)
	assert.Equal(t, "https://rest.messagebird.com/mms/6d9e7100b1f9406c81a3c303c30ccf05", message.HRef)
	assert.Equal(t, "mt", message.Direction)
	assert.Equal(t, "TestName", message.Originator)
	assert.Equal(t, "Hello World", message.Body)
	assert.Equal(t, "https://media.giphy.com/media/Vuw9m5wXviFIQ/giphy.gif", message.MediaUrls[0])
	assert.Equal(t, "https://media.giphy.com/media/pxy9QQUMF0glq/giphy.gif", message.MediaUrls[1])
	assert.Equal(t, "TestReference", message.Reference)
	assert.Equal(t, "TestSubject", message.Subject)
	assert.Nil(t, message.ScheduledDatetime)
	assert.Equal(t, "2022-05-20T12:50:28Z", message.CreatedDatetime.Format(time.RFC3339))
	assert.Equal(t, 1, message.Recipients.TotalCount)
	assert.Equal(t, 1, message.Recipients.TotalSentCount)
	assert.Equal(t, int64(31612345678), message.Recipients.Items[0].Recipient)
	assert.Equal(t, "sent", message.Recipients.Items[0].Status)
	assert.Equal(t, "2022-05-20T12:50:28Z", message.Recipients.Items[0].StatusDatetime.Format(time.RFC3339))

	_, ok := err.(messagebird.ErrorResponse)
	assert.False(t, ok)
}

func TestRead(t *testing.T) {
	mbtest.WillReturnTestdata(t, "mmsMessageObject.json", http.StatusOK)
	client := mbtest.Client(t)

	message, err := Read(client, "6d9e7100b1f9406c81a3c303c30ccf05")

	assert.NoError(t, err)
	assert.Equal(t, "6d9e7100b1f9406c81a3c303c30ccf05", message.ID)
	assert.Equal(t, "https://rest.messagebird.com/mms/6d9e7100b1f9406c81a3c303c30ccf05", message.HRef)
	assert.Equal(t, "mt", message.Direction)
	assert.Equal(t, "TestName", message.Originator)
	assert.Equal(t, "Hello World", message.Body)
	assert.Equal(t, "https://media.giphy.com/media/Vuw9m5wXviFIQ/giphy.gif", message.MediaUrls[0])
	assert.Equal(t, "https://media.giphy.com/media/pxy9QQUMF0glq/giphy.gif", message.MediaUrls[1])
	assert.Equal(t, "TestReference", message.Reference)
	assert.Equal(t, "TestSubject", message.Subject)
	assert.Nil(t, message.ScheduledDatetime)
	assert.Equal(t, "2022-05-20T12:50:28Z", message.CreatedDatetime.Format(time.RFC3339))
	assert.Equal(t, 1, message.Recipients.TotalCount)
	assert.Equal(t, 1, message.Recipients.TotalSentCount)
	assert.Equal(t, int64(31612345678), message.Recipients.Items[0].Recipient)
	assert.Equal(t, "sent", message.Recipients.Items[0].Status)
	assert.Equal(t, "2022-05-20T12:50:28Z", message.Recipients.Items[0].StatusDatetime.Format(time.RFC3339))

	_, ok := err.(messagebird.ErrorResponse)
	assert.False(t, ok)
}
<|endoftext|>


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

package models

import (
	"bufio"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"strings"
	"sync"
	"time"

	"github.com/Unknwon/com"

	"github.com/gogits/gogs/modules/log"
	"github.com/gogits/gogs/modules/process"
)

const (
	// "### autogenerated by gitgos, DO NOT EDIT\n"
	_TPL_PUBLICK_KEY = `command="%s serv key-%d",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s` + "\n"
)

var (
	ErrKeyAlreadyExist = errors.New("Public key already exist")
	ErrKeyNotExist     = errors.New("Public key does not exist")
)

var sshOpLocker = sync.Mutex{}

var (
	SshPath string // SSH directory.
	appPath string // Execution(binary) path.
)

// exePath returns the executable path.
func exePath() (string, error) {
	file, err := exec.LookPath(os.Args[0])
	if err != nil {
		return "", err
	}
	return filepath.Abs(file)
}

// homeDir returns the home directory of current user.
func homeDir() string {
	home, err := com.HomeDir()
	if err != nil {
		log.Fatal(4, "Fail to get home directory: %v", err)
	}
	return home
}

func init() {
	var err error

	if appPath, err = exePath(); err != nil {
		log.Fatal(4, "fail to get app path: %v\n", err)
	}
	appPath = strings.Replace(appPath, "\\", "/", -1)

	// Determine and create .ssh path.
	SshPath = filepath.Join(homeDir(), ".ssh")
	if err = os.MkdirAll(SshPath, os.ModePerm); err != nil {
		log.Fatal(4, "fail to create SshPath(%s): %v\n", SshPath, err)
	}
}

// PublicKey represents a SSH key.
type PublicKey struct {
	Id                int64
	OwnerId           int64  `xorm:"UNIQUE(s) INDEX NOT NULL"`
	Name              string `xorm:"UNIQUE(s) NOT NULL"`
	Fingerprint       string
	Content           string    `xorm:"TEXT NOT NULL"`
	Created           time.Time `xorm:"CREATED"`
	Updated           time.Time
	HasRecentActivity bool `xorm:"-"`
	HasUsed           bool `xorm:"-"`
}

// GetAuthorizedString generates and returns formatted public key string for authorized_keys file.
func (key *PublicKey) GetAuthorizedString() string {
	return fmt.Sprintf(_TPL_PUBLICK_KEY, appPath, key.Id, key.Content)
}

var (
	MinimumKeySize = map[string]int{
		"(ED25519)": 256,
		"(ECDSA)":   256,
		"(NTRU)":    1087,
		"(MCE)":     1702,
		"(McE)":     1702,
		"(RSA)":     2048,
	}
)

// CheckPublicKeyString checks if the given public key string is recognized by SSH.
func CheckPublicKeyString(content string) (bool, error) {
	if strings.ContainsAny(content, "\n\r") {
		return false, errors.New("Only a single line with a single key please")
	}

	// write the key to a file…
	tmpFile, err := ioutil.TempFile(os.TempDir(), "keytest")
	if err != nil {
		return false, err
	}
	tmpPath := tmpFile.Name()
	defer os.Remove(tmpPath)
	tmpFile.WriteString(content)
	tmpFile.Close()

	// … see if ssh-keygen recognizes its contents
	stdout, stderr, err := process.Exec("CheckPublicKeyString", "ssh-keygen", "-l", "-f", tmpPath)
	if err != nil {
		return false, errors.New("ssh-keygen -l -f: " + stderr)
	} else if len(stdout) < 2 {
		return false, errors.New("ssh-keygen returned not enough output to evaluate the key")
	}
	sshKeygenOutput := strings.Split(stdout, " ")
	if len(sshKeygenOutput) < 4 {
		return false, errors.New("Not enough fields returned by ssh-keygen -l -f")
	}
	keySize, err := com.StrTo(sshKeygenOutput[0]).Int()
	if err != nil {
		return false, errors.New("Cannot get key size of the given key")
	}
	keyType := strings.TrimSpace(sshKeygenOutput[len(sshKeygenOutput)-1])

	if minimumKeySize := MinimumKeySize[keyType]; minimumKeySize == 0 {
		return false, errors.New("Sorry, unrecognized public key type")
	} else if keySize < minimumKeySize {
		return false, fmt.Errorf("The minimum accepted size of a public key %s is %d", keyType, minimumKeySize)
	}

	return true, nil
}

// saveAuthorizedKeyFile writes SSH key content to authorized_keys file.
func saveAuthorizedKeyFile(key *PublicKey) error {
	sshOpLocker.Lock()
	defer sshOpLocker.Unlock()

	fpath := filepath.Join(SshPath, "authorized_keys")
	f, err := os.OpenFile(fpath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
	if err != nil {
		return err
	}
	defer f.Close()

	_, err = f.WriteString(key.GetAuthorizedString())
	return err
}

// AddPublicKey adds new public key to database and authorized_keys file.
func AddPublicKey(key *PublicKey) (err error) {
	has, err := x.Get(key)
	if err != nil {
		return err
	} else if has {
		return ErrKeyAlreadyExist
	}

	// Calculate fingerprint.
	tmpPath := strings.Replace(path.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond()),
		"id_rsa.pub"), "\\", "/", -1)
	os.MkdirAll(path.Dir(tmpPath), os.ModePerm)
	if err = ioutil.WriteFile(tmpPath, []byte(key.Content), os.ModePerm); err != nil {
		return err
	}
	stdout, stderr, err := process.Exec("AddPublicKey", "ssh-keygen", "-l", "-f", tmpPath)
	if err != nil {
		return errors.New("ssh-keygen -l -f: " + stderr)
	} else if len(stdout) < 2 {
		return errors.New("Not enough output for calculating fingerprint")
	}
	key.Fingerprint = strings.Split(stdout, " ")[1]

	// Save SSH key.
	if _, err = x.Insert(key); err != nil {
		return err
	} else if err = saveAuthorizedKeyFile(key); err != nil {
		// Roll back.
		if _, err2 := x.Delete(key); err2 != nil {
			return err2
		}
		return err
	}

	return nil
}

// ListPublicKey returns a list of all public keys that user has.
func ListPublicKey(uid int64) ([]*PublicKey, error) {
	keys := make([]*PublicKey, 0, 5)
	err := x.Find(&keys, &PublicKey{OwnerId: uid})
	if err != nil {
		return nil, err
	}

	for _, key := range keys {
		key.HasUsed = key.Updated.After(key.Created)
		key.HasRecentActivity = key.Updated.Add(7 * 24 * time.Hour).After(time.Now())
	}
	return keys, nil
}

// rewriteAuthorizedKeys finds and deletes corresponding line in authorized_keys file.
func rewriteAuthorizedKeys(key *PublicKey, p, tmpP string) error {
	sshOpLocker.Lock()
	defer sshOpLocker.Unlock()

	fr, err := os.Open(p)
	if err != nil {
		return err
	}
	defer fr.Close()

	fw, err := os.OpenFile(tmpP, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
	if err != nil {
		return err
	}
	defer fw.Close()

	isFound := false
	keyword := fmt.Sprintf("key-%d", key.Id)
	buf := bufio.NewReader(fr)
	for {
		line, errRead := buf.ReadString('\n')
		line = strings.TrimSpace(line)

		if errRead != nil {
			if errRead != io.EOF {
				return errRead
			}

			// Reached end of file, if nothing to read then break,
			// otherwise handle the last line.
			if len(line) == 0 {
				break
			}
		}

		// Found the line and copy rest of file.
		if !isFound && strings.Contains(line, keyword) && strings.Contains(line, key.Content) {
			isFound = true
			continue
		}
		// Still finding the line, copy the line that currently read.
		if _, err = fw.WriteString(line + "\n"); err != nil {
			return err
		}

		if errRead == io.EOF {
			break
		}
	}
	return nil
}

// DeletePublicKey deletes SSH key information both in database and authorized_keys file.
func DeletePublicKey(key *PublicKey) error {
	has, err := x.Get(key)
	if err != nil {
		return err
	} else if !has {
		return ErrKeyNotExist
	}

	if _, err = x.Delete(key); err != nil {
		return err
	}

	fpath := filepath.Join(SshPath, "authorized_keys")
	tmpPath := filepath.Join(SshPath, "authorized_keys.tmp")
	if err = rewriteAuthorizedKeys(key, fpath, tmpPath); err != nil {
		return err
	} else if err = os.Remove(fpath); err != nil {
		return err
	}
	return os.Rename(tmpPath, fpath)
}
<commit_msg>Make sure, .ssh directory and authorized_keys file are kept at correct permissions<commit_after>// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package models

import (
	"bufio"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"strings"
	"sync"
	"time"

	"github.com/Unknwon/com"

	"github.com/gogits/gogs/modules/log"
	"github.com/gogits/gogs/modules/process"
)

const (
	// "### autogenerated by gitgos, DO NOT EDIT\n"
	_TPL_PUBLICK_KEY = `command="%s serv key-%d",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %s` + "\n"
)

var (
	ErrKeyAlreadyExist = errors.New("Public key already exist")
	ErrKeyNotExist     = errors.New("Public key does not exist")
)

var sshOpLocker = sync.Mutex{}

var (
	SshPath string // SSH directory.
	appPath string // Execution(binary) path.
)

// exePath returns the executable path.
func exePath() (string, error) {
	file, err := exec.LookPath(os.Args[0])
	if err != nil {
		return "", err
	}
	return filepath.Abs(file)
}

// homeDir returns the home directory of current user.
func homeDir() string {
	home, err := com.HomeDir()
	if err != nil {
		log.Fatal(4, "Fail to get home directory: %v", err)
	}
	return home
}

func init() {
	var err error

	if appPath, err = exePath(); err != nil {
		log.Fatal(4, "fail to get app path: %v\n", err)
	}
	appPath = strings.Replace(appPath, "\\", "/", -1)

	// Determine and create .ssh path.
	SshPath = filepath.Join(homeDir(), ".ssh")
	if err = os.MkdirAll(SshPath, 0700); err != nil {
		log.Fatal(4, "fail to create SshPath(%s): %v\n", SshPath, err)
	}
}

// PublicKey represents a SSH key.
type PublicKey struct {
	Id                int64
	OwnerId           int64  `xorm:"UNIQUE(s) INDEX NOT NULL"`
	Name              string `xorm:"UNIQUE(s) NOT NULL"`
	Fingerprint       string
	Content           string    `xorm:"TEXT NOT NULL"`
	Created           time.Time `xorm:"CREATED"`
	Updated           time.Time
	HasRecentActivity bool `xorm:"-"`
	HasUsed           bool `xorm:"-"`
}

// GetAuthorizedString generates and returns formatted public key string for authorized_keys file.
func (key *PublicKey) GetAuthorizedString() string {
	return fmt.Sprintf(_TPL_PUBLICK_KEY, appPath, key.Id, key.Content)
}

var (
	MinimumKeySize = map[string]int{
		"(ED25519)": 256,
		"(ECDSA)":   256,
		"(NTRU)":    1087,
		"(MCE)":     1702,
		"(McE)":     1702,
		"(RSA)":     2048,
	}
)

// CheckPublicKeyString checks if the given public key string is recognized by SSH.
func CheckPublicKeyString(content string) (bool, error) {
	if strings.ContainsAny(content, "\n\r") {
		return false, errors.New("Only a single line with a single key please")
	}

	// write the key to a file…
	tmpFile, err := ioutil.TempFile(os.TempDir(), "keytest")
	if err != nil {
		return false, err
	}
	tmpPath := tmpFile.Name()
	defer os.Remove(tmpPath)
	tmpFile.WriteString(content)
	tmpFile.Close()

	// … see if ssh-keygen recognizes its contents
	stdout, stderr, err := process.Exec("CheckPublicKeyString", "ssh-keygen", "-l", "-f", tmpPath)
	if err != nil {
		return false, errors.New("ssh-keygen -l -f: " + stderr)
	} else if len(stdout) < 2 {
		return false, errors.New("ssh-keygen returned not enough output to evaluate the key")
	}
	sshKeygenOutput := strings.Split(stdout, " ")
	if len(sshKeygenOutput) < 4 {
		return false, errors.New("Not enough fields returned by ssh-keygen -l -f")
	}
	keySize, err := com.StrTo(sshKeygenOutput[0]).Int()
	if err != nil {
		return false, errors.New("Cannot get key size of the given key")
	}
	keyType := strings.TrimSpace(sshKeygenOutput[len(sshKeygenOutput)-1])

	if minimumKeySize := MinimumKeySize[keyType]; minimumKeySize == 0 {
		return false, errors.New("Sorry, unrecognized public key type")
	} else if keySize < minimumKeySize {
		return false, fmt.Errorf("The minimum accepted size of a public key %s is %d", keyType, minimumKeySize)
	}

	return true, nil
}

// saveAuthorizedKeyFile writes SSH key content to authorized_keys file.
func saveAuthorizedKeyFile(key *PublicKey) error {
	sshOpLocker.Lock()
	defer sshOpLocker.Unlock()

	fpath := filepath.Join(SshPath, "authorized_keys")
	f, err := os.OpenFile(fpath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
	if err != nil {
		return err
	}
	finfo, err := f.Stat()
	if err != nil {
		return err
	}
	if finfo.Mode().Perm() > 0600 {
		log.Error("authorized_keys file has unusual permission flags: " + finfo.Mode().Perm() + " - setting to -rw-r--r--")
		f.Chmod(0600)
	}

	defer f.Close()

	_, err = f.WriteString(key.GetAuthorizedString())
	return err
}

// AddPublicKey adds new public key to database and authorized_keys file.
func AddPublicKey(key *PublicKey) (err error) {
	has, err := x.Get(key)
	if err != nil {
		return err
	} else if has {
		return ErrKeyAlreadyExist
	}

	// Calculate fingerprint.
	tmpPath := strings.Replace(path.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond()),
		"id_rsa.pub"), "\\", "/", -1)
	os.MkdirAll(path.Dir(tmpPath), os.ModePerm)
	if err = ioutil.WriteFile(tmpPath, []byte(key.Content), os.ModePerm); err != nil {
		return err
	}
	stdout, stderr, err := process.Exec("AddPublicKey", "ssh-keygen", "-l", "-f", tmpPath)
	if err != nil {
		return errors.New("ssh-keygen -l -f: " + stderr)
	} else if len(stdout) < 2 {
		return errors.New("Not enough output for calculating fingerprint")
	}
	key.Fingerprint = strings.Split(stdout, " ")[1]

	// Save SSH key.
	if _, err = x.Insert(key); err != nil {
		return err
	} else if err = saveAuthorizedKeyFile(key); err != nil {
		// Roll back.
		if _, err2 := x.Delete(key); err2 != nil {
			return err2
		}
		return err
	}

	return nil
}

// ListPublicKey returns a list of all public keys that user has.
func ListPublicKey(uid int64) ([]*PublicKey, error) {
	keys := make([]*PublicKey, 0, 5)
	err := x.Find(&keys, &PublicKey{OwnerId: uid})
	if err != nil {
		return nil, err
	}

	for _, key := range keys {
		key.HasUsed = key.Updated.After(key.Created)
		key.HasRecentActivity = key.Updated.Add(7 * 24 * time.Hour).After(time.Now())
	}
	return keys, nil
}

// rewriteAuthorizedKeys finds and deletes corresponding line in authorized_keys file.
func rewriteAuthorizedKeys(key *PublicKey, p, tmpP string) error {
	sshOpLocker.Lock()
	defer sshOpLocker.Unlock()

	fr, err := os.Open(p)
	if err != nil {
		return err
	}
	defer fr.Close()

	fw, err := os.OpenFile(tmpP, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
	if err != nil {
		return err
	}
	defer fw.Close()

	isFound := false
	keyword := fmt.Sprintf("key-%d", key.Id)
	buf := bufio.NewReader(fr)
	for {
		line, errRead := buf.ReadString('\n')
		line = strings.TrimSpace(line)

		if errRead != nil {
			if errRead != io.EOF {
				return errRead
			}

			// Reached end of file, if nothing to read then break,
			// otherwise handle the last line.
			if len(line) == 0 {
				break
			}
		}

		// Found the line and copy rest of file.
		if !isFound && strings.Contains(line, keyword) && strings.Contains(line, key.Content) {
			isFound = true
			continue
		}
		// Still finding the line, copy the line that currently read.
		if _, err = fw.WriteString(line + "\n"); err != nil {
			return err
		}

		if errRead == io.EOF {
			break
		}
	}
	return nil
}

// DeletePublicKey deletes SSH key information both in database and authorized_keys file.
func DeletePublicKey(key *PublicKey) error {
	has, err := x.Get(key)
	if err != nil {
		return err
	} else if !has {
		return ErrKeyNotExist
	}

	if _, err = x.Delete(key); err != nil {
		return err
	}

	fpath := filepath.Join(SshPath, "authorized_keys")
	tmpPath := filepath.Join(SshPath, "authorized_keys.tmp")
	if err = rewriteAuthorizedKeys(key, fpath, tmpPath); err != nil {
		return err
	} else if err = os.Remove(fpath); err != nil {
		return err
	}
	return os.Rename(tmpPath, fpath)
}
<|endoftext|>


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

package models

import (
	"strings"

	"code.gitea.io/gitea/modules/git"
	"code.gitea.io/gitea/modules/log"
	"code.gitea.io/gitea/modules/process"
	"code.gitea.io/gitea/modules/setting"
)

type signingMode string

const (
	never         signingMode = "never"
	always        signingMode = "always"
	pubkey        signingMode = "pubkey"
	twofa         signingMode = "twofa"
	parentSigned  signingMode = "parentsigned"
	baseSigned    signingMode = "basesigned"
	headSigned    signingMode = "headsigned"
	commitsSigned signingMode = "commitssigned"
	approved      signingMode = "approved"
	noKey         signingMode = "nokey"
)

func signingModeFromStrings(modeStrings []string) []signingMode {
	returnable := make([]signingMode, 0, len(modeStrings))
	for _, mode := range modeStrings {
		signMode := signingMode(strings.ToLower(mode))
		switch signMode {
		case never:
			return []signingMode{never}
		case always:
			return []signingMode{always}
		case pubkey:
			fallthrough
		case twofa:
			fallthrough
		case parentSigned:
			fallthrough
		case baseSigned:
			fallthrough
		case headSigned:
			fallthrough
		case approved:
			fallthrough
		case commitsSigned:
			returnable = append(returnable, signMode)
		}
	}
	if len(returnable) == 0 {
		return []signingMode{never}
	}
	return returnable
}

func signingKey(repoPath string) string {
	if setting.Repository.Signing.SigningKey == "none" {
		return ""
	}

	if setting.Repository.Signing.SigningKey == "default" || setting.Repository.Signing.SigningKey == "" {
		// Can ignore the error here as it means that commit.gpgsign is not set
		value, _ := git.NewCommand("config", "--get", "commit.gpgsign").RunInDir(repoPath)
		sign, valid := git.ParseBool(strings.TrimSpace(value))
		if !sign || !valid {
			return ""
		}

		signingKey, _ := git.NewCommand("config", "--get", "user.signingkey").RunInDir(repoPath)
		return strings.TrimSpace(signingKey)
	}

	return setting.Repository.Signing.SigningKey
}

// PublicSigningKey gets the public signing key within a provided repository directory
func PublicSigningKey(repoPath string) (string, error) {
	signingKey := signingKey(repoPath)
	if signingKey == "" {
		return "", nil
	}

	content, stderr, err := process.GetManager().ExecDir(-1, repoPath,
		"gpg --export -a", "gpg", "--export", "-a", signingKey)
	if err != nil {
		log.Error("Unable to get default signing key in %s: %s, %s, %v", repoPath, signingKey, stderr, err)
		return "", err
	}
	return content, nil
}

// SignInitialCommit determines if we should sign the initial commit to this repository
func SignInitialCommit(repoPath string, u *User) (bool, string, error) {
	rules := signingModeFromStrings(setting.Repository.Signing.InitialCommit)
	signingKey := signingKey(repoPath)
	if signingKey == "" {
		return false, "", &ErrWontSign{noKey}
	}

	for _, rule := range rules {
		switch rule {
		case never:
			return false, "", &ErrWontSign{never}
		case always:
			break
		case pubkey:
			keys, err := ListGPGKeys(u.ID, ListOptions{})
			if err != nil {
				return false, "", err
			}
			if len(keys) == 0 {
				return false, "", &ErrWontSign{pubkey}
			}
		case twofa:
			twofaModel, err := GetTwoFactorByUID(u.ID)
			if err != nil && !IsErrTwoFactorNotEnrolled(err) {
				return false, "", err
			}
			if twofaModel == nil {
				return false, "", &ErrWontSign{twofa}
			}
		}
	}
	return true, signingKey, nil
}

// SignWikiCommit determines if we should sign the commits to this repository wiki
func (repo *Repository) SignWikiCommit(u *User) (bool, string, error) {
	rules := signingModeFromStrings(setting.Repository.Signing.Wiki)
	signingKey := signingKey(repo.WikiPath())
	if signingKey == "" {
		return false, "", &ErrWontSign{noKey}
	}

	for _, rule := range rules {
		switch rule {
		case never:
			return false, "", &ErrWontSign{never}
		case always:
			break
		case pubkey:
			keys, err := ListGPGKeys(u.ID, ListOptions{})
			if err != nil {
				return false, "", err
			}
			if len(keys) == 0 {
				return false, "", &ErrWontSign{pubkey}
			}
		case twofa:
			twofaModel, err := GetTwoFactorByUID(u.ID)
			if err != nil && !IsErrTwoFactorNotEnrolled(err) {
				return false, "", err
			}
			if twofaModel == nil {
				return false, "", &ErrWontSign{twofa}
			}
		case parentSigned:
			gitRepo, err := git.OpenRepository(repo.WikiPath())
			if err != nil {
				return false, "", err
			}
			defer gitRepo.Close()
			commit, err := gitRepo.GetCommit("HEAD")
			if err != nil {
				return false, "", err
			}
			if commit.Signature == nil {
				return false, "", &ErrWontSign{parentSigned}
			}
			verification := ParseCommitWithSignature(commit)
			if !verification.Verified {
				return false, "", &ErrWontSign{parentSigned}
			}
		}
	}
	return true, signingKey, nil
}

// SignCRUDAction determines if we should sign a CRUD commit to this repository
func (repo *Repository) SignCRUDAction(u *User, tmpBasePath, parentCommit string) (bool, string, error) {
	rules := signingModeFromStrings(setting.Repository.Signing.CRUDActions)
	signingKey := signingKey(repo.RepoPath())
	if signingKey == "" {
		return false, "", &ErrWontSign{noKey}
	}

	for _, rule := range rules {
		switch rule {
		case never:
			return false, "", &ErrWontSign{never}
		case always:
			break
		case pubkey:
			keys, err := ListGPGKeys(u.ID, ListOptions{})
			if err != nil {
				return false, "", err
			}
			if len(keys) == 0 {
				return false, "", &ErrWontSign{pubkey}
			}
		case twofa:
			twofaModel, err := GetTwoFactorByUID(u.ID)
			if err != nil && !IsErrTwoFactorNotEnrolled(err) {
				return false, "", err
			}
			if twofaModel == nil {
				return false, "", &ErrWontSign{twofa}
			}
		case parentSigned:
			gitRepo, err := git.OpenRepository(tmpBasePath)
			if err != nil {
				return false, "", err
			}
			defer gitRepo.Close()
			commit, err := gitRepo.GetCommit(parentCommit)
			if err != nil {
				return false, "", err
			}
			if commit.Signature == nil {
				return false, "", &ErrWontSign{parentSigned}
			}
			verification := ParseCommitWithSignature(commit)
			if !verification.Verified {
				return false, "", &ErrWontSign{parentSigned}
			}
		}
	}
	return true, signingKey, nil
}
<commit_msg>models: break out of loops (#12159)<commit_after>// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package models

import (
	"strings"

	"code.gitea.io/gitea/modules/git"
	"code.gitea.io/gitea/modules/log"
	"code.gitea.io/gitea/modules/process"
	"code.gitea.io/gitea/modules/setting"
)

type signingMode string

const (
	never         signingMode = "never"
	always        signingMode = "always"
	pubkey        signingMode = "pubkey"
	twofa         signingMode = "twofa"
	parentSigned  signingMode = "parentsigned"
	baseSigned    signingMode = "basesigned"
	headSigned    signingMode = "headsigned"
	commitsSigned signingMode = "commitssigned"
	approved      signingMode = "approved"
	noKey         signingMode = "nokey"
)

func signingModeFromStrings(modeStrings []string) []signingMode {
	returnable := make([]signingMode, 0, len(modeStrings))
	for _, mode := range modeStrings {
		signMode := signingMode(strings.ToLower(mode))
		switch signMode {
		case never:
			return []signingMode{never}
		case always:
			return []signingMode{always}
		case pubkey:
			fallthrough
		case twofa:
			fallthrough
		case parentSigned:
			fallthrough
		case baseSigned:
			fallthrough
		case headSigned:
			fallthrough
		case approved:
			fallthrough
		case commitsSigned:
			returnable = append(returnable, signMode)
		}
	}
	if len(returnable) == 0 {
		return []signingMode{never}
	}
	return returnable
}

func signingKey(repoPath string) string {
	if setting.Repository.Signing.SigningKey == "none" {
		return ""
	}

	if setting.Repository.Signing.SigningKey == "default" || setting.Repository.Signing.SigningKey == "" {
		// Can ignore the error here as it means that commit.gpgsign is not set
		value, _ := git.NewCommand("config", "--get", "commit.gpgsign").RunInDir(repoPath)
		sign, valid := git.ParseBool(strings.TrimSpace(value))
		if !sign || !valid {
			return ""
		}

		signingKey, _ := git.NewCommand("config", "--get", "user.signingkey").RunInDir(repoPath)
		return strings.TrimSpace(signingKey)
	}

	return setting.Repository.Signing.SigningKey
}

// PublicSigningKey gets the public signing key within a provided repository directory
func PublicSigningKey(repoPath string) (string, error) {
	signingKey := signingKey(repoPath)
	if signingKey == "" {
		return "", nil
	}

	content, stderr, err := process.GetManager().ExecDir(-1, repoPath,
		"gpg --export -a", "gpg", "--export", "-a", signingKey)
	if err != nil {
		log.Error("Unable to get default signing key in %s: %s, %s, %v", repoPath, signingKey, stderr, err)
		return "", err
	}
	return content, nil
}

// SignInitialCommit determines if we should sign the initial commit to this repository
func SignInitialCommit(repoPath string, u *User) (bool, string, error) {
	rules := signingModeFromStrings(setting.Repository.Signing.InitialCommit)
	signingKey := signingKey(repoPath)
	if signingKey == "" {
		return false, "", &ErrWontSign{noKey}
	}

Loop:
	for _, rule := range rules {
		switch rule {
		case never:
			return false, "", &ErrWontSign{never}
		case always:
			break Loop
		case pubkey:
			keys, err := ListGPGKeys(u.ID, ListOptions{})
			if err != nil {
				return false, "", err
			}
			if len(keys) == 0 {
				return false, "", &ErrWontSign{pubkey}
			}
		case twofa:
			twofaModel, err := GetTwoFactorByUID(u.ID)
			if err != nil && !IsErrTwoFactorNotEnrolled(err) {
				return false, "", err
			}
			if twofaModel == nil {
				return false, "", &ErrWontSign{twofa}
			}
		}
	}
	return true, signingKey, nil
}

// SignWikiCommit determines if we should sign the commits to this repository wiki
func (repo *Repository) SignWikiCommit(u *User) (bool, string, error) {
	rules := signingModeFromStrings(setting.Repository.Signing.Wiki)
	signingKey := signingKey(repo.WikiPath())
	if signingKey == "" {
		return false, "", &ErrWontSign{noKey}
	}

Loop:
	for _, rule := range rules {
		switch rule {
		case never:
			return false, "", &ErrWontSign{never}
		case always:
			break Loop
		case pubkey:
			keys, err := ListGPGKeys(u.ID, ListOptions{})
			if err != nil {
				return false, "", err
			}
			if len(keys) == 0 {
				return false, "", &ErrWontSign{pubkey}
			}
		case twofa:
			twofaModel, err := GetTwoFactorByUID(u.ID)
			if err != nil && !IsErrTwoFactorNotEnrolled(err) {
				return false, "", err
			}
			if twofaModel == nil {
				return false, "", &ErrWontSign{twofa}
			}
		case parentSigned:
			gitRepo, err := git.OpenRepository(repo.WikiPath())
			if err != nil {
				return false, "", err
			}
			defer gitRepo.Close()
			commit, err := gitRepo.GetCommit("HEAD")
			if err != nil {
				return false, "", err
			}
			if commit.Signature == nil {
				return false, "", &ErrWontSign{parentSigned}
			}
			verification := ParseCommitWithSignature(commit)
			if !verification.Verified {
				return false, "", &ErrWontSign{parentSigned}
			}
		}
	}
	return true, signingKey, nil
}

// SignCRUDAction determines if we should sign a CRUD commit to this repository
func (repo *Repository) SignCRUDAction(u *User, tmpBasePath, parentCommit string) (bool, string, error) {
	rules := signingModeFromStrings(setting.Repository.Signing.CRUDActions)
	signingKey := signingKey(repo.RepoPath())
	if signingKey == "" {
		return false, "", &ErrWontSign{noKey}
	}

Loop:
	for _, rule := range rules {
		switch rule {
		case never:
			return false, "", &ErrWontSign{never}
		case always:
			break Loop
		case pubkey:
			keys, err := ListGPGKeys(u.ID, ListOptions{})
			if err != nil {
				return false, "", err
			}
			if len(keys) == 0 {
				return false, "", &ErrWontSign{pubkey}
			}
		case twofa:
			twofaModel, err := GetTwoFactorByUID(u.ID)
			if err != nil && !IsErrTwoFactorNotEnrolled(err) {
				return false, "", err
			}
			if twofaModel == nil {
				return false, "", &ErrWontSign{twofa}
			}
		case parentSigned:
			gitRepo, err := git.OpenRepository(tmpBasePath)
			if err != nil {
				return false, "", err
			}
			defer gitRepo.Close()
			commit, err := gitRepo.GetCommit(parentCommit)
			if err != nil {
				return false, "", err
			}
			if commit.Signature == nil {
				return false, "", &ErrWontSign{parentSigned}
			}
			verification := ParseCommitWithSignature(commit)
			if !verification.Verified {
				return false, "", &ErrWontSign{parentSigned}
			}
		}
	}
	return true, signingKey, nil
}
<|endoftext|>


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

package dashboard

// This file handles identities of people.

import (
	"sort"
)

var (
	emailToPerson  = make(map[string]string) // email => person
	preferredEmail = make(map[string]string) // person => email
	personList     []string
)

func init() {
	// People we assume have golang.org and google.com accounts,
	// and prefer to use their golang.org address for code review.
	gophers := [...]string{
		"adg",
		"bradfitz",
		"dsymonds",
		"gri",
		"iant",
		"nigeltao",
		"r",
		"rsc",
		"sameer",
	}
	for _, p := range gophers {
		personList = append(personList, p)
		emailToPerson[p+"@golang.org"] = p
		emailToPerson[p+"@google.com"] = p
		preferredEmail[p] = p + "@golang.org"
	}

	sort.Strings(personList)
}
<commit_msg>misc/dashboard/codereview: add campoy to list of gophers<commit_after>// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package dashboard

// This file handles identities of people.

import (
	"sort"
)

var (
	emailToPerson  = make(map[string]string) // email => person
	preferredEmail = make(map[string]string) // person => email
	personList     []string
)

func init() {
	// People we assume have golang.org and google.com accounts,
	// and prefer to use their golang.org address for code review.
	gophers := [...]string{
		"adg",
		"bradfitz",
		"campoy",
		"dsymonds",
		"gri",
		"iant",
		"nigeltao",
		"r",
		"rsc",
		"sameer",
	}
	for _, p := range gophers {
		personList = append(personList, p)
		emailToPerson[p+"@golang.org"] = p
		emailToPerson[p+"@google.com"] = p
		preferredEmail[p] = p + "@golang.org"
	}

	sort.Strings(personList)
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/rds"
	"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
	"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
)

func resourceAwsDbSnapshot() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsDbSnapshotCreate,
		Read:   resourceAwsDbSnapshotRead,
		Update: resourceAwsDbSnapshotUpdate,
		Delete: resourceAwsDbSnapshotDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Timeouts: &schema.ResourceTimeout{
			Read: schema.DefaultTimeout(20 * time.Minute),
		},

		Schema: map[string]*schema.Schema{
			"db_snapshot_identifier": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"db_instance_identifier": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"allocated_storage": {
				Type:     schema.TypeInt,
				Computed: true,
			},
			"availability_zone": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"db_snapshot_arn": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"encrypted": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"engine": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"engine_version": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"iops": {
				Type:     schema.TypeInt,
				Computed: true,
			},
			"kms_key_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"license_model": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"option_group_name": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"port": {
				Type:     schema.TypeInt,
				Computed: true,
			},
			"source_db_snapshot_identifier": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"source_region": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"snapshot_type": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"status": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"storage_type": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"vpc_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"tags": tagsSchema(),
		},
	}
}

func resourceAwsDbSnapshotCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).rdsconn
	tags := keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().RdsTags()
	dBInstanceIdentifier := d.Get("db_instance_identifier").(string)

	params := &rds.CreateDBSnapshotInput{
		DBInstanceIdentifier: aws.String(dBInstanceIdentifier),
		DBSnapshotIdentifier: aws.String(d.Get("db_snapshot_identifier").(string)),
		Tags:                 tags,
	}

	_, err := conn.CreateDBSnapshot(params)
	if err != nil {
		return fmt.Errorf("Error creating AWS DB Snapshot %s: %s", dBInstanceIdentifier, err)
	}
	d.SetId(d.Get("db_snapshot_identifier").(string))

	stateConf := &resource.StateChangeConf{
		Pending:    []string{"creating"},
		Target:     []string{"available"},
		Refresh:    resourceAwsDbSnapshotStateRefreshFunc(d, meta),
		Timeout:    d.Timeout(schema.TimeoutRead),
		MinTimeout: 10 * time.Second,
		Delay:      30 * time.Second, // Wait 30 secs before starting
	}

	// Wait, catching any errors
	_, err = stateConf.WaitForState()
	if err != nil {
		return err
	}

	return resourceAwsDbSnapshotRead(d, meta)
}

func resourceAwsDbSnapshotRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).rdsconn

	params := &rds.DescribeDBSnapshotsInput{
		DBSnapshotIdentifier: aws.String(d.Id()),
	}
	resp, err := conn.DescribeDBSnapshots(params)

	if isAWSErr(err, rds.ErrCodeDBSnapshotNotFoundFault, "") {
		log.Printf("[WARN] AWS DB Snapshot (%s) is already gone", d.Id())
		d.SetId("")
		return nil
	}

	if err != nil {
		return fmt.Errorf("Error describing AWS DB Snapshot %s: %s", d.Id(), err)
	}

	snapshot := resp.DBSnapshots[0]

	arn := aws.StringValue(snapshot.DBSnapshotArn)
	d.Set("db_snapshot_identifier", snapshot.DBSnapshotIdentifier)
	d.Set("db_instance_identifier", snapshot.DBInstanceIdentifier)
	d.Set("allocated_storage", snapshot.AllocatedStorage)
	d.Set("availability_zone", snapshot.AvailabilityZone)
	d.Set("db_snapshot_arn", arn)
	d.Set("encrypted", snapshot.Encrypted)
	d.Set("engine", snapshot.Engine)
	d.Set("engine_version", snapshot.EngineVersion)
	d.Set("iops", snapshot.Iops)
	d.Set("kms_key_id", snapshot.KmsKeyId)
	d.Set("license_model", snapshot.LicenseModel)
	d.Set("option_group_name", snapshot.OptionGroupName)
	d.Set("port", snapshot.Port)
	d.Set("source_db_snapshot_identifier", snapshot.SourceDBSnapshotIdentifier)
	d.Set("source_region", snapshot.SourceRegion)
	d.Set("snapshot_type", snapshot.SnapshotType)
	d.Set("status", snapshot.Status)
	d.Set("vpc_id", snapshot.VpcId)

	tags, err := keyvaluetags.RdsListTags(conn, arn)

	if err != nil {
		return fmt.Errorf("error listing tags for RDS DB Snapshot (%s): %s", arn, err)
	}

	if err := d.Set("tags", tags.IgnoreAws().Map()); err != nil {
		return fmt.Errorf("error setting tags: %s", err)
	}

	return nil
}

func resourceAwsDbSnapshotDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).rdsconn

	params := &rds.DeleteDBSnapshotInput{
		DBSnapshotIdentifier: aws.String(d.Id()),
	}
	_, err := conn.DeleteDBSnapshot(params)
	if isAWSErr(err, rds.ErrCodeDBSnapshotNotFoundFault, "") {
		return nil
	}

	if err != nil {
		return fmt.Errorf("Error deleting AWS DB Snapshot %s: %s", d.Id(), err)
	}

	return nil
}

func resourceAwsDbSnapshotUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).rdsconn

	if d.HasChange("tags") {
		o, n := d.GetChange("tags")

		if err := keyvaluetags.RdsUpdateTags(conn, d.Get("db_snapshot_arn").(string), o, n); err != nil {
			return fmt.Errorf("error updating RDS DB Snapshot (%s) tags: %s", d.Get("db_snapshot_arn").(string), err)
		}
	}

	return nil
}

func resourceAwsDbSnapshotStateRefreshFunc(
	d *schema.ResourceData, meta interface{}) resource.StateRefreshFunc {
	return func() (interface{}, string, error) {
		conn := meta.(*AWSClient).rdsconn

		opts := &rds.DescribeDBSnapshotsInput{
			DBSnapshotIdentifier: aws.String(d.Id()),
		}

		log.Printf("[DEBUG] DB Snapshot describe configuration: %#v", opts)

		resp, err := conn.DescribeDBSnapshots(opts)
		if isAWSErr(err, rds.ErrCodeDBSnapshotNotFoundFault, "") {
			return nil, "", nil
		}
		if err != nil {
			return nil, "", fmt.Errorf("Error retrieving DB Snapshots: %s", err)
		}

		if len(resp.DBSnapshots) != 1 {
			return nil, "", fmt.Errorf("No snapshots returned for %s", d.Id())
		}

		snapshot := resp.DBSnapshots[0]

		return resp, *snapshot.Status, nil
	}
}
<commit_msg>use create out put for setting id<commit_after>package aws

import (
	"fmt"
	"log"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/rds"
	"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
	"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
)

func resourceAwsDbSnapshot() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsDbSnapshotCreate,
		Read:   resourceAwsDbSnapshotRead,
		Update: resourceAwsDbSnapshotUpdate,
		Delete: resourceAwsDbSnapshotDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Timeouts: &schema.ResourceTimeout{
			Read: schema.DefaultTimeout(20 * time.Minute),
		},

		Schema: map[string]*schema.Schema{
			"db_snapshot_identifier": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"db_instance_identifier": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"allocated_storage": {
				Type:     schema.TypeInt,
				Computed: true,
			},
			"availability_zone": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"db_snapshot_arn": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"encrypted": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"engine": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"engine_version": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"iops": {
				Type:     schema.TypeInt,
				Computed: true,
			},
			"kms_key_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"license_model": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"option_group_name": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"port": {
				Type:     schema.TypeInt,
				Computed: true,
			},
			"source_db_snapshot_identifier": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"source_region": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"snapshot_type": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"status": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"storage_type": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"vpc_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"tags": tagsSchema(),
		},
	}
}

func resourceAwsDbSnapshotCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).rdsconn
	tags := keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().RdsTags()
	dBInstanceIdentifier := d.Get("db_instance_identifier").(string)

	params := &rds.CreateDBSnapshotInput{
		DBInstanceIdentifier: aws.String(dBInstanceIdentifier),
		DBSnapshotIdentifier: aws.String(d.Get("db_snapshot_identifier").(string)),
		Tags:                 tags,
	}

	resp, err := conn.CreateDBSnapshot(params)
	if err != nil {
		return fmt.Errorf("Error creating AWS DB Snapshot %s: %s", dBInstanceIdentifier, err)
	}
	d.SetId(aws.StringValue(resp.DBSnapshot.DBSnapshotIdentifier))

	stateConf := &resource.StateChangeConf{
		Pending:    []string{"creating"},
		Target:     []string{"available"},
		Refresh:    resourceAwsDbSnapshotStateRefreshFunc(d, meta),
		Timeout:    d.Timeout(schema.TimeoutRead),
		MinTimeout: 10 * time.Second,
		Delay:      30 * time.Second, // Wait 30 secs before starting
	}

	// Wait, catching any errors
	_, err = stateConf.WaitForState()
	if err != nil {
		return err
	}

	return resourceAwsDbSnapshotRead(d, meta)
}

func resourceAwsDbSnapshotRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).rdsconn

	params := &rds.DescribeDBSnapshotsInput{
		DBSnapshotIdentifier: aws.String(d.Id()),
	}
	resp, err := conn.DescribeDBSnapshots(params)

	if isAWSErr(err, rds.ErrCodeDBSnapshotNotFoundFault, "") {
		log.Printf("[WARN] AWS DB Snapshot (%s) is already gone", d.Id())
		d.SetId("")
		return nil
	}

	if err != nil {
		return fmt.Errorf("Error describing AWS DB Snapshot %s: %s", d.Id(), err)
	}

	snapshot := resp.DBSnapshots[0]

	arn := aws.StringValue(snapshot.DBSnapshotArn)
	d.Set("db_snapshot_identifier", snapshot.DBSnapshotIdentifier)
	d.Set("db_instance_identifier", snapshot.DBInstanceIdentifier)
	d.Set("allocated_storage", snapshot.AllocatedStorage)
	d.Set("availability_zone", snapshot.AvailabilityZone)
	d.Set("db_snapshot_arn", arn)
	d.Set("encrypted", snapshot.Encrypted)
	d.Set("engine", snapshot.Engine)
	d.Set("engine_version", snapshot.EngineVersion)
	d.Set("iops", snapshot.Iops)
	d.Set("kms_key_id", snapshot.KmsKeyId)
	d.Set("license_model", snapshot.LicenseModel)
	d.Set("option_group_name", snapshot.OptionGroupName)
	d.Set("port", snapshot.Port)
	d.Set("source_db_snapshot_identifier", snapshot.SourceDBSnapshotIdentifier)
	d.Set("source_region", snapshot.SourceRegion)
	d.Set("snapshot_type", snapshot.SnapshotType)
	d.Set("status", snapshot.Status)
	d.Set("vpc_id", snapshot.VpcId)

	tags, err := keyvaluetags.RdsListTags(conn, arn)

	if err != nil {
		return fmt.Errorf("error listing tags for RDS DB Snapshot (%s): %s", arn, err)
	}

	if err := d.Set("tags", tags.IgnoreAws().Map()); err != nil {
		return fmt.Errorf("error setting tags: %s", err)
	}

	return nil
}

func resourceAwsDbSnapshotDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).rdsconn

	params := &rds.DeleteDBSnapshotInput{
		DBSnapshotIdentifier: aws.String(d.Id()),
	}
	_, err := conn.DeleteDBSnapshot(params)
	if isAWSErr(err, rds.ErrCodeDBSnapshotNotFoundFault, "") {
		return nil
	}

	if err != nil {
		return fmt.Errorf("Error deleting AWS DB Snapshot %s: %s", d.Id(), err)
	}

	return nil
}

func resourceAwsDbSnapshotUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).rdsconn

	if d.HasChange("tags") {
		o, n := d.GetChange("tags")

		if err := keyvaluetags.RdsUpdateTags(conn, d.Get("db_snapshot_arn").(string), o, n); err != nil {
			return fmt.Errorf("error updating RDS DB Snapshot (%s) tags: %s", d.Get("db_snapshot_arn").(string), err)
		}
	}

	return nil
}

func resourceAwsDbSnapshotStateRefreshFunc(
	d *schema.ResourceData, meta interface{}) resource.StateRefreshFunc {
	return func() (interface{}, string, error) {
		conn := meta.(*AWSClient).rdsconn

		opts := &rds.DescribeDBSnapshotsInput{
			DBSnapshotIdentifier: aws.String(d.Id()),
		}

		log.Printf("[DEBUG] DB Snapshot describe configuration: %#v", opts)

		resp, err := conn.DescribeDBSnapshots(opts)
		if isAWSErr(err, rds.ErrCodeDBSnapshotNotFoundFault, "") {
			return nil, "", nil
		}
		if err != nil {
			return nil, "", fmt.Errorf("Error retrieving DB Snapshots: %s", err)
		}

		if len(resp.DBSnapshots) != 1 {
			return nil, "", fmt.Errorf("No snapshots returned for %s", d.Id())
		}

		snapshot := resp.DBSnapshots[0]

		return resp, *snapshot.Status, nil
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net/smtp"
)

type Notifier interface {
	SendProblem(problem Problem) error
}

type EmailNotifier struct {
	Contacts []*EmailContact
	Relay SMTPRelay
}

func (n *EmailNotifier) SendProblem(problem Problem) error {
	content := ("A Problem occured: " + problem.Description + "\r\n" +
		"ReplicaSet: " + fmt.Sprint(problem.ReplicaSet) + "\r\n" +
		"Slave: " + fmt.Sprint(problem.Slave) + "\r\n" +
		"long Description:" + problem.LongDescription) + "\r\n"
	subject := ("Subject:" + "KIT-MAMID: Problem in " + fmt.Sprint(problem.ReplicaSet) + "/" + fmt.Sprint(problem.Slave))
	msg := []byte("From: kit.mamid@gmail.com\r\n" +
		subject + "\r\n" +
		content)
	return n.sendMailToContacts(msg)
}

func (n *EmailNotifier) sendMailToContacts(msg []byte) error {
	auth := smtp.PlainAuth("", "kit.mamid@gmail.com", "uwsngsdlsnh", "smtp.gmail.com")
	var to []string
	for i := 0; i < len(n.Contacts); i++ {
		to = append(to, n.Contacts[i].Address)
	}
	err := smtp.SendMail(
		"smtp.gmail.com:587",
		auth,
		"kit.mamid@gmail.com",
		to,
		msg)
	return err
}
<commit_msg>FMT: notifiers<commit_after>package main

import (
	"fmt"
	"net/smtp"
)

type Notifier interface {
	SendProblem(problem Problem) error
}

type EmailNotifier struct {
	Contacts []*EmailContact
	Relay    SMTPRelay
}

func (n *EmailNotifier) SendProblem(problem Problem) error {
	content := ("A Problem occured: " + problem.Description + "\r\n" +
		"ReplicaSet: " + fmt.Sprint(problem.ReplicaSet) + "\r\n" +
		"Slave: " + fmt.Sprint(problem.Slave) + "\r\n" +
		"long Description:" + problem.LongDescription) + "\r\n"
	subject := ("Subject:" + "KIT-MAMID: Problem in " + fmt.Sprint(problem.ReplicaSet) + "/" + fmt.Sprint(problem.Slave))
	msg := []byte("From: kit.mamid@gmail.com\r\n" +
		subject + "\r\n" +
		content)
	return n.sendMailToContacts(msg)
}

func (n *EmailNotifier) sendMailToContacts(msg []byte) error {
	auth := smtp.PlainAuth("", "kit.mamid@gmail.com", "uwsngsdlsnh", "smtp.gmail.com")
	var to []string
	for i := 0; i < len(n.Contacts); i++ {
		to = append(to, n.Contacts[i].Address)
	}
	err := smtp.SendMail(
		"smtp.gmail.com:587",
		auth,
		"kit.mamid@gmail.com",
		to,
		msg)
	return err
}
<|endoftext|>


<commit_before>package lbreg

import (
	r "github.com/open-lambda/code-registry/registry"
	"github.com/open-lambda/load-balancer/balancer/inspect/codegen"
)

type LBFileProcessor struct{}

func (p LBFileProcessor) Process(name string, files map[string][]byte) ([]r.DBInsert, error) {
	ret := make([]r.DBInsert, 0)
	pb, err := codegen.GenPB(files[PROTO], name)
	if err != nil {
		return ret, err
	}

	parser, err := codegen.GenParser(name, files[PROTO])
	if err != nil {
		return ret, err
	}

	sfiles := map[string]interface{}{
		"id":      name,
		"handler": files[HANDLER],
		"pb":      pb,
	}
	sinsert := r.DBInsert{
		Table: r.SERVER,
		Data:  &sfiles,
	}
	ret = append(ret, sinsert)

	lbfiles := map[string]interface{}{
		"id":     name,
		"parser": parser,
	}
	lbinsert := r.DBInsert{
		Table: r.BALANCER,
		Data:  &lbfiles,
	}
	ret = append(ret, lbinsert)

	return ret, nil
}

func InitPushServer(cluster []string) *r.PushServer {
	proc := LBFileProcessor{}
	return r.InitPushServer(cluster, DATABASE, proc, SPORT, CHUNK_SIZE)
}
<commit_msg>fixed more constants<commit_after>package lbreg

import (
	r "github.com/open-lambda/code-registry/registry"
	"github.com/open-lambda/load-balancer/balancer/inspect/codegen"
)

type LBFileProcessor struct{}

func (p LBFileProcessor) Process(name string, files map[string][]byte) ([]r.DBInsert, error) {
	ret := make([]r.DBInsert, 0)
	pb, err := codegen.GenPB(files[PROTO], name)
	if err != nil {
		return ret, err
	}

	parser, err := codegen.GenParser(name, files[PROTO])
	if err != nil {
		return ret, err
	}

	sfiles := map[string]interface{}{
		"id":      name,
		"handler": files[HANDLER],
		"pb":      pb,
	}
	sinsert := r.DBInsert{
		Table: SERVER,
		Data:  &sfiles,
	}
	ret = append(ret, sinsert)

	lbfiles := map[string]interface{}{
		"id":     name,
		"parser": parser,
	}
	lbinsert := r.DBInsert{
		Table: BALANCER,
		Data:  &lbfiles,
	}
	ret = append(ret, lbinsert)

	return ret, nil
}

func InitPushServer(cluster []string) *r.PushServer {
	proc := LBFileProcessor{}
	return r.InitPushServer(cluster, DATABASE, proc, SPORT, CHUNK_SIZE)
}
<|endoftext|>