<commit_before>package main

import (
	"bufio"
	"bytes"
	"fmt"
	"log"
	"net"
	"strings"
	"time"
)

type User struct {
	nick       string
	user       string
	ident      string
	dead       bool
	nickset    bool
	waiting    bool
	connection net.Conn
	id         int
	realname   string
	userset    bool
	registered bool
	ip         string
	host       string
	epoch      time.Time
	lastrcv    time.Time
	nextcheck  time.Time
	chanlist   map[string]*Channel
}

func (user *User) PingChecker() {
	for {
		if user.dead {
			break
		}
		if time.Now().After(user.nextcheck) {
			if user.waiting {
				since := time.Since(user.lastrcv).Seconds()
				user.Quit(fmt.Sprintf("Ping Timeout: %.0f seconds", since))
				break
			} else {
				user.SendLine(fmt.Sprintf("PING :%s", sname))
				user.waiting = true
				user.nextcheck.Add(ping_time * time.Second)
				log.Printf("Sent user %s ping", user.nick)
			}
		}
		time.Sleep(ping_check_time * time.Second)
	}
}

func (user *User) QuitCommandHandler(args []string) {
	var reason string
	if len(args) > 1 {
		args[1] = StripLeading(args[1], ":")
		var buffer bytes.Buffer
		for i := 1; i < len(args); i++ {
			buffer.WriteString(args[i])
			buffer.WriteString(" ")
		}
		reason = strings.TrimSpace(buffer.String())
	} else {
		reason = "Leaving"
	}
	user.Quit(reason)
	log.Printf("User %s Quit (%s)", user.nick, reason)
}

func (user *User) Quit(reason string) {
	targets := []*User{user}
	for _, k := range user.chanlist {
		targets = append(targets, k.GetUserList()...)
		delete(k.userlist, user.id)
		delete(user.chanlist, k.name)
		k.ShouldIDie()
	}
	SendToMany(fmt.Sprintf(":%s QUIT :%s", user.GetHostMask(), reason), targets)
	user.SendLinef("ERROR :Closing Link: %s (%s)", user.host, reason)
	user.dead = true
	if user.connection != nil {
		user.connection.Close()
	}
	delete(userlist, user.id)
}

func (user *User) FireNumeric(numeric int, args ...interface{}) {
	msg := strcat(fmt.Sprintf(":%s %.3d %s ", sname, numeric, user.nick), fmt.Sprintf(NUM[numeric], args...))
	user.SendLine(msg)
}

func NewUser(conn net.Conn) *User {
	userip := GetIpFromConn(conn)
	log.Println("New connection from", userip)
	counter = counter + 1
	user := &User{id: counter, connection: conn, ip: userip, nick: "*"}
	user.chanlist = make(map[string]*Channel)
	user.host = user.ip
	user.epoch = time.Now()
	user.lastrcv = time.Now()
	user.nextcheck = time.Now().Add(ping_time * time.Second)
	userlist[user.id] = user
	if resolvehosts {
		go user.UserHostLookup()
	}
	go user.PingChecker()
	return user
}

func (user *User) SendLine(msg string) {
	msg = fmt.Sprintf("%s\n", msg)
	if user.dead {
		return
	}
	_, err := user.connection.Write([]byte(msg))
	if err != nil {
		user.dead = true
		user.Quit("Error")
		log.Printf("Error sending message to %s, disconnecting\n", user.nick)
	}
	//log.Printf("Send to %s: %s", user.nick, msg)
}

func (user *User) SendLinef(msg string, args ...interface{}) {
	user.SendLine(fmt.Sprintf(msg, args...))
}

func (user *User) HandleRequests() {
	b := bufio.NewReader(user.connection)
	for {
		if user.dead {
			break
		}
		line, err := b.ReadString('\n')
		if err != nil {
			log.Println("Error reading:", err.Error())
			user.dead = true
			user.Quit("Error")
		}
		if line == "" {
			user.dead = true
			user.Quit("Error")
			break
		}
		line = strings.TrimSpace(line)
		//log.Println("Receive from", fmt.Sprintf("%s:", user.nick), line)
		ProcessLine(user, line)
	}
}
func (user *User) NickHandler(args []string) {
	oldnick := user.nick
	if len(args) < 2 {
		user.FireNumeric(ERR_NONICKNAMEGIVEN)
		return
	}
	if NickHasBadChars(args[1]) {
		user.FireNumeric(ERR_ERRONEOUSNICKNAME, args[1])
		return
	}
	if GetUserByNick(args[1]) != nil {
		user.FireNumeric(ERR_NICKNAMEINUSE, args[1])
		return
	}
	if !user.nickset {
		user.nickset = true
	} else if user.registered {
		targets := []*User{}
		targets = append(targets, user)
		for _, k := range user.chanlist {
			targets = append(targets, k.GetUserList()...)
		}
		SendToMany(fmt.Sprintf(":%s NICK %s", user.GetHostMask(), args[1]), targets)
	}
	user.nick = args[1]
	log.Printf("User %s changed nick to %s", oldnick, user.nick)
	if !user.registered && user.userset {
		user.UserRegistrationFinished()
	}
}

func (user *User) UserHandler(args []string) {
	if len(args) < 5 {
		user.FireNumeric(ERR_NEEDMOREPARAMS, "USER")
		return
	}
	user.ident = args[1]
	args[4] = StripLeading(args[4], ":")
	var buffer bytes.Buffer
	for i := 4; i < len(args); i++ {
		buffer.WriteString(args[i])
		buffer.WriteString(" ")
	}
	user.realname = strings.TrimSpace(buffer.String())
	user.userset = true
	if !user.registered && user.nickset {
		user.UserRegistrationFinished()
	}
}

func (user *User) UserRegistrationFinished() {
	user.registered = true
	log.Printf("User %d finished registration\n", user.id)
	user.FireNumeric(RPL_WELCOME, user.nick, user.ident, user.host)
	user.FireNumeric(RPL_YOURHOST, sname, software, softwarev)
	user.FireNumeric(RPL_CREATED, epoch)
	//TODO fire RPL_MYINFO when we actually have enough stuff to do it
	user.FireNumeric(RPL_ISUPPORT, isupport)
	user.FireLusers()
}

func (user *User) UserHostLookup() {
	user.SendLinef(":%s NOTICE %s :*** Looking up your hostname...", sname, user.nick)
	adds, err := net.LookupAddr(user.ip)
	if err != nil {
		user.SendLinef("%s NOTICE %s :*** Unable to resolve your hostname", sname, user.nick)
		return
	}
	addstring := adds[0]
	adds, err = net.LookupHost(addstring)
	if err != nil {
		user.SendLinef("%s NOTICE %s :*** Unable to resolve your hostname", sname, user.nick)
		return
	}
	for _, k := range adds {
		if user.ip == k {
			user.host = addstring
			user.SendLinef(":%s NOTICE %s :*** Found your hostname", sname, user.nick)
			return
		}
	}
	user.SendLinef(":%s NOTICE %s :*** Your forward and reverse DNS do not match, ignoring hostname", sname, user.nick)
}

func (user *User) CommandNotFound(args []string) {
	log.Printf("User %s attempted unknown command %s", user.nick, args[0])
	user.FireNumeric(ERR_UNKNOWNCOMMAND, args[0])
}

func (user *User) GetHostMask() string {
	return fmt.Sprintf("%s!%s@%s", user.nick, user.ident, user.host)
}

func (user *User) JoinHandler(args []string) {
	if len(args) < 2 {
		user.FireNumeric(ERR_NEEDMOREPARAMS, "JOIN")
		return
	}
	if !ValidChanName(args[1]) {
		user.FireNumeric(ERR_NOSUCHCHANNEL, args[1])
		return
	}
	channel := GetChannelByName(args[1])
	if channel == nil {
		channel = NewChannel(args[1])
	}
	channel.JoinUser(user)
	user.chanlist[channel.name] = channel
	log.Printf("User %s joined %s", user.nick, channel.name)
}

func (user *User) FireLusers() {
	user.FireNumeric(RPL_LUSERCLIENT, len(userlist), 0, 1) //0 services and 1 servers for now
	user.FireNumeric(RPL_LUSEROP, 0)                       //also 0 for now
	user.FireNumeric(RPL_LUSERUNKNOWN, 0)                  //also 0...
	user.FireNumeric(RPL_LUSERCHANNELS, len(chanlist))
	user.FireNumeric(RPL_LUSERME, len(userlist), 1)
}

func (user *User) PartHandler(args []string) {
	if len(args) < 2 {
		user.FireNumeric(ERR_NEEDMOREPARAMS, "PART")
		return
	}
	channel := GetChannelByName(args[1])
	if channel != nil {
		list := channel.GetUserList()
		delete(channel.userlist, user.id)
		delete(user.chanlist, channel.name)
		SendToMany2f(list, ":%s PART %s :%s", user.GetHostMask(), channel.name, "Leaving")
		log.Printf("User %s PART %s: %s", user.nick, channel.name, "Leaving")
		channel.ShouldIDie()
	} //else?
}

func (user *User) PrivmsgHandler(args []string) {
	if len(args) < 3 {
		user.FireNumeric(ERR_NEEDMOREPARAMS, "PRIVMSG")
		return
	}
	if ValidChanName(args[1]) { //TODO part of this should be sent to the channel "object"
		//presumably a channel
		j := GetChannelByName(args[1])
		if j != nil {
			//channel exists, send the message
			msg := FormatMessageArgs(args)
			list := j.GetUserList()
			for _, l := range list {
				if l != user {
					l.SendLinef(":%s PRIVMSG %s :%s", user.GetHostMask(), j.name, msg)
				}
			}
			log.Printf("User %s CHANMSG %s: %s", user.nick, j.name, msg)
			return
		} else {
			//channel didnt exist but get channel by name makes one anyways, lets kill it...
			user.FireNumeric(ERR_NOSUCHCHANNEL, args[1])
			return
		}
	} else {
		//maybe its a user
		target := GetUserByNick(args[1])
		if target != nil {
			msg := FormatMessageArgs(args)
			target.SendLinef(":%s PRIVMSG %s :%s", user.GetHostMask(), target.nick, msg)
			log.Printf("User %s PRIVMSG %s: %s", user.nick, target.nick, msg)
		}
	}
}

func (user *User) TopicHandler(args []string) {
	if len(args) < 2 {
		user.FireNumeric(ERR_NEEDMOREPARAMS, "TOPIC")
		return
	}
	k := GetChannelByName(args[1])
	if k == nil {
		user.FireNumeric(ERR_NOSUCHCHANNEL, args[1])
		return
	}
	if len(args) < 3 {
		k.FireTopic(user)
		return
	}
	msg := FormatMessageArgs(args)
	k.SetTopic(msg, user.GetHostMask())
}

func (user *User) ModeHandler(args []string) {
	if len(args) < 2 {
		user.FireNumeric(ERR_NEEDMOREPARAMS, "MODE")
		return
	}
	if ChanUserNone(args[1]) == 1 {
		channel := GetChannelByName(args[1])
		if len(args) < 3 {
			//just digging around...
			channel.FireModes(user)
		}
	}
}
<commit_msg>add log statement for mode<commit_after>package main

import (
	"bufio"
	"bytes"
	"fmt"
	"log"
	"net"
	"strings"
	"time"
)

type User struct {
	nick       string
	user       string
	ident      string
	dead       bool
	nickset    bool
	waiting    bool
	connection net.Conn
	id         int
	realname   string
	userset    bool
	registered bool
	ip         string
	host       string
	epoch      time.Time
	lastrcv    time.Time
	nextcheck  time.Time
	chanlist   map[string]*Channel
}

func (user *User) PingChecker() {
	for {
		if user.dead {
			break
		}
		if time.Now().After(user.nextcheck) {
			if user.waiting {
				since := time.Since(user.lastrcv).Seconds()
				user.Quit(fmt.Sprintf("Ping Timeout: %.0f seconds", since))
				break
			} else {
				user.SendLine(fmt.Sprintf("PING :%s", sname))
				user.waiting = true
				user.nextcheck.Add(ping_time * time.Second)
				log.Printf("Sent user %s ping", user.nick)
			}
		}
		time.Sleep(ping_check_time * time.Second)
	}
}

func (user *User) QuitCommandHandler(args []string) {
	var reason string
	if len(args) > 1 {
		args[1] = StripLeading(args[1], ":")
		var buffer bytes.Buffer
		for i := 1; i < len(args); i++ {
			buffer.WriteString(args[i])
			buffer.WriteString(" ")
		}
		reason = strings.TrimSpace(buffer.String())
	} else {
		reason = "Leaving"
	}
	user.Quit(reason)
	log.Printf("User %s Quit (%s)", user.nick, reason)
}

func (user *User) Quit(reason string) {
	targets := []*User{user}
	for _, k := range user.chanlist {
		targets = append(targets, k.GetUserList()...)
		delete(k.userlist, user.id)
		delete(user.chanlist, k.name)
		k.ShouldIDie()
	}
	SendToMany(fmt.Sprintf(":%s QUIT :%s", user.GetHostMask(), reason), targets)
	user.SendLinef("ERROR :Closing Link: %s (%s)", user.host, reason)
	user.dead = true
	if user.connection != nil {
		user.connection.Close()
	}
	delete(userlist, user.id)
}

func (user *User) FireNumeric(numeric int, args ...interface{}) {
	msg := strcat(fmt.Sprintf(":%s %.3d %s ", sname, numeric, user.nick), fmt.Sprintf(NUM[numeric], args...))
	user.SendLine(msg)
}

func NewUser(conn net.Conn) *User {
	userip := GetIpFromConn(conn)
	log.Println("New connection from", userip)
	counter = counter + 1
	user := &User{id: counter, connection: conn, ip: userip, nick: "*"}
	user.chanlist = make(map[string]*Channel)
	user.host = user.ip
	user.epoch = time.Now()
	user.lastrcv = time.Now()
	user.nextcheck = time.Now().Add(ping_time * time.Second)
	userlist[user.id] = user
	if resolvehosts {
		go user.UserHostLookup()
	}
	go user.PingChecker()
	return user
}

func (user *User) SendLine(msg string) {
	msg = fmt.Sprintf("%s\n", msg)
	if user.dead {
		return
	}
	_, err := user.connection.Write([]byte(msg))
	if err != nil {
		user.dead = true
		user.Quit("Error")
		log.Printf("Error sending message to %s, disconnecting\n", user.nick)
	}
	//log.Printf("Send to %s: %s", user.nick, msg)
}

func (user *User) SendLinef(msg string, args ...interface{}) {
	user.SendLine(fmt.Sprintf(msg, args...))
}

func (user *User) HandleRequests() {
	b := bufio.NewReader(user.connection)
	for {
		if user.dead {
			break
		}
		line, err := b.ReadString('\n')
		if err != nil {
			log.Println("Error reading:", err.Error())
			user.dead = true
			user.Quit("Error")
		}
		if line == "" {
			user.dead = true
			user.Quit("Error")
			break
		}
		line = strings.TrimSpace(line)
		//log.Println("Receive from", fmt.Sprintf("%s:", user.nick), line)
		ProcessLine(user, line)
	}
}
func (user *User) NickHandler(args []string) {
	oldnick := user.nick
	if len(args) < 2 {
		user.FireNumeric(ERR_NONICKNAMEGIVEN)
		return
	}
	if NickHasBadChars(args[1]) {
		user.FireNumeric(ERR_ERRONEOUSNICKNAME, args[1])
		return
	}
	if GetUserByNick(args[1]) != nil {
		user.FireNumeric(ERR_NICKNAMEINUSE, args[1])
		return
	}
	if !user.nickset {
		user.nickset = true
	} else if user.registered {
		targets := []*User{}
		targets = append(targets, user)
		for _, k := range user.chanlist {
			targets = append(targets, k.GetUserList()...)
		}
		SendToMany(fmt.Sprintf(":%s NICK %s", user.GetHostMask(), args[1]), targets)
	}
	user.nick = args[1]
	log.Printf("User %s changed nick to %s", oldnick, user.nick)
	if !user.registered && user.userset {
		user.UserRegistrationFinished()
	}
}

func (user *User) UserHandler(args []string) {
	if len(args) < 5 {
		user.FireNumeric(ERR_NEEDMOREPARAMS, "USER")
		return
	}
	user.ident = args[1]
	args[4] = StripLeading(args[4], ":")
	var buffer bytes.Buffer
	for i := 4; i < len(args); i++ {
		buffer.WriteString(args[i])
		buffer.WriteString(" ")
	}
	user.realname = strings.TrimSpace(buffer.String())
	user.userset = true
	if !user.registered && user.nickset {
		user.UserRegistrationFinished()
	}
}

func (user *User) UserRegistrationFinished() {
	user.registered = true
	log.Printf("User %d finished registration\n", user.id)
	user.FireNumeric(RPL_WELCOME, user.nick, user.ident, user.host)
	user.FireNumeric(RPL_YOURHOST, sname, software, softwarev)
	user.FireNumeric(RPL_CREATED, epoch)
	//TODO fire RPL_MYINFO when we actually have enough stuff to do it
	user.FireNumeric(RPL_ISUPPORT, isupport)
	user.FireLusers()
}

func (user *User) UserHostLookup() {
	user.SendLinef(":%s NOTICE %s :*** Looking up your hostname...", sname, user.nick)
	adds, err := net.LookupAddr(user.ip)
	if err != nil {
		user.SendLinef("%s NOTICE %s :*** Unable to resolve your hostname", sname, user.nick)
		return
	}
	addstring := adds[0]
	adds, err = net.LookupHost(addstring)
	if err != nil {
		user.SendLinef("%s NOTICE %s :*** Unable to resolve your hostname", sname, user.nick)
		return
	}
	for _, k := range adds {
		if user.ip == k {
			user.host = addstring
			user.SendLinef(":%s NOTICE %s :*** Found your hostname", sname, user.nick)
			return
		}
	}
	user.SendLinef(":%s NOTICE %s :*** Your forward and reverse DNS do not match, ignoring hostname", sname, user.nick)
}

func (user *User) CommandNotFound(args []string) {
	log.Printf("User %s attempted unknown command %s", user.nick, args[0])
	user.FireNumeric(ERR_UNKNOWNCOMMAND, args[0])
}

func (user *User) GetHostMask() string {
	return fmt.Sprintf("%s!%s@%s", user.nick, user.ident, user.host)
}

func (user *User) JoinHandler(args []string) {
	if len(args) < 2 {
		user.FireNumeric(ERR_NEEDMOREPARAMS, "JOIN")
		return
	}
	if !ValidChanName(args[1]) {
		user.FireNumeric(ERR_NOSUCHCHANNEL, args[1])
		return
	}
	channel := GetChannelByName(args[1])
	if channel == nil {
		channel = NewChannel(args[1])
	}
	channel.JoinUser(user)
	user.chanlist[channel.name] = channel
	log.Printf("User %s joined %s", user.nick, channel.name)
}

func (user *User) FireLusers() {
	user.FireNumeric(RPL_LUSERCLIENT, len(userlist), 0, 1) //0 services and 1 servers for now
	user.FireNumeric(RPL_LUSEROP, 0)                       //also 0 for now
	user.FireNumeric(RPL_LUSERUNKNOWN, 0)                  //also 0...
	user.FireNumeric(RPL_LUSERCHANNELS, len(chanlist))
	user.FireNumeric(RPL_LUSERME, len(userlist), 1)
}

func (user *User) PartHandler(args []string) {
	if len(args) < 2 {
		user.FireNumeric(ERR_NEEDMOREPARAMS, "PART")
		return
	}
	channel := GetChannelByName(args[1])
	if channel != nil {
		list := channel.GetUserList()
		delete(channel.userlist, user.id)
		delete(user.chanlist, channel.name)
		SendToMany2f(list, ":%s PART %s :%s", user.GetHostMask(), channel.name, "Leaving")
		log.Printf("User %s PART %s: %s", user.nick, channel.name, "Leaving")
		channel.ShouldIDie()
	} //else?
}

func (user *User) PrivmsgHandler(args []string) {
	if len(args) < 3 {
		user.FireNumeric(ERR_NEEDMOREPARAMS, "PRIVMSG")
		return
	}
	if ValidChanName(args[1]) { //TODO part of this should be sent to the channel "object"
		//presumably a channel
		j := GetChannelByName(args[1])
		if j != nil {
			//channel exists, send the message
			msg := FormatMessageArgs(args)
			list := j.GetUserList()
			for _, l := range list {
				if l != user {
					l.SendLinef(":%s PRIVMSG %s :%s", user.GetHostMask(), j.name, msg)
				}
			}
			log.Printf("User %s CHANMSG %s: %s", user.nick, j.name, msg)
			return
		} else {
			//channel didnt exist but get channel by name makes one anyways, lets kill it...
			user.FireNumeric(ERR_NOSUCHCHANNEL, args[1])
			return
		}
	} else {
		//maybe its a user
		target := GetUserByNick(args[1])
		if target != nil {
			msg := FormatMessageArgs(args)
			target.SendLinef(":%s PRIVMSG %s :%s", user.GetHostMask(), target.nick, msg)
			log.Printf("User %s PRIVMSG %s: %s", user.nick, target.nick, msg)
		}
	}
}

func (user *User) TopicHandler(args []string) {
	if len(args) < 2 {
		user.FireNumeric(ERR_NEEDMOREPARAMS, "TOPIC")
		return
	}
	k := GetChannelByName(args[1])
	if k == nil {
		user.FireNumeric(ERR_NOSUCHCHANNEL, args[1])
		return
	}
	if len(args) < 3 {
		k.FireTopic(user)
		return
	}
	msg := FormatMessageArgs(args)
	k.SetTopic(msg, user.GetHostMask())
}

func (user *User) ModeHandler(args []string) {
	if len(args) < 2 {
		user.FireNumeric(ERR_NEEDMOREPARAMS, "MODE")
		return
	}
	if ChanUserNone(args[1]) == 1 {
		channel := GetChannelByName(args[1])
		if len(args) < 3 {
			//just digging around...
			channel.FireModes(user)
			log.Printf("User %s requested modes for %s", user.nick, channel.name)
		}
	}
}
<|endoftext|>


<commit_before>// BucketReader gets a list of files awaiting processing in the S3 intake buckets
// and adds each item to the queue for processing.
package main

import (
	"bytes"
	"flag"
	"log"
	"fmt"
	"encoding/json"
	"net/http"
	"github.com/APTrust/bagman"
)

var config bagman.Config
var jsonLog *log.Logger
var messageLog *log.Logger

func main() {
	initialize()
	run()
}

func initialize() {
	// Load the config or die.
	requestedConfig := flag.String("config", "", "configuration to run")
	flag.Parse()
	config = bagman.LoadRequestedConfig(requestedConfig)
	jsonLog, messageLog = bagman.InitLoggers(config.LogDirectory, "bucket_reader")
}

func run() {
	bucketSummaries, err := bagman.CheckAllBuckets(config.Buckets)
	if err != nil {
		messageLog.Println("[ERROR]", err)
		return
	}
	url := fmt.Sprintf("%s/put?topic=%s", config.NsqdHttpAddress,
		config.BagProcessorTopic)
	messageLog.Printf("[INFO] Sending S3 file info to %s \n", url)
	for _, bucketSummary := range bucketSummaries {
		for _, key := range bucketSummary.Keys {
			if key.Size < config.MaxFileSize {
				s3File := bagman.S3File{bucketSummary.BucketName, key}
				enqueue(url, s3File)
			}
		}
	}
}

// enqueue adds an item to the nsqd work queue
func enqueue(url string, s3File bagman.S3File) {
	jsonData, err := json.Marshal(s3File)
	if err != nil {
		messageLog.Printf("[ERROR] Error marshalling s3 file to JSON: %v", err)
	}
	resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		messageLog.Printf("[ERROR] nsqd returned an error: %v", err)
	}
	// TODO: Check for 200 response
	fmt.Println(resp)
	messageLog.Println("[INFO]", "Put", s3File.Key.Key, "into fetch queue")
}
<commit_msg>Add items to queue in batches, so we don't max out network connections<commit_after>// BucketReader gets a list of files awaiting processing in the S3
// intake buckets and adds each item to the queue for processing.
package main

import (
	"bytes"
	"flag"
	"log"
	"fmt"
	"strings"
	"time"
	"encoding/json"
	"net/http"
	"github.com/APTrust/bagman"
)

// Send S3 files to queue in batches of 500.
// Wait X milliseconds between batches. The wait time is really
// only necessary when the queue is running on an AWS small EC2
// instance, where the number of open network connections is
// severely restricted.
const (
	batchSize = 500
	waitMilliseconds = 5000
)
var config bagman.Config
var jsonLog *log.Logger
var messageLog *log.Logger

func main() {
	initialize()
	run()
}

func initialize() {
	// Load the config or die.
	requestedConfig := flag.String("config", "", "configuration to run")
	flag.Parse()
	config = bagman.LoadRequestedConfig(requestedConfig)
	jsonLog, messageLog = bagman.InitLoggers(config.LogDirectory, "bucket_reader")
}

func run() {
	bucketSummaries, err := bagman.CheckAllBuckets(config.Buckets)
	if err != nil {
		messageLog.Println("[ERROR]", err)
		return
	}
	url := fmt.Sprintf("%s/mput?topic=%s", config.NsqdHttpAddress,
		config.BagProcessorTopic)
	messageLog.Printf("[INFO] Sending S3 file info to %s \n", url)
	s3Files := filterLargeFiles(bucketSummaries)
	start := 0
	end := min(len(s3Files) - 1, batchSize)
	for start < end {
		batch := s3Files[start:end]
		enqueue(url, batch)
		start = end + 1
		if start < len(s3Files) {
			end = min(len(s3Files) - 1, start + batchSize)
		}
		// Sleep so we don't max out connections on EC2 small.
		// The utility server is running a lot of other network I/O
		// in addition to our queue.
		time.Sleep(time.Millisecond * waitMilliseconds)
	}
}

// min returns the minimum of x or y. The Math package has this function
// but you have to cast to floats.
func min (x, y int) (int) {
	if x < y {
		return x
	} else {
		return y
	}
}

// filterLargeFiles returns only those S3 files that are not larger
// than config.MaxFileSize. This is useful when running tests and
// demos on your local machine, so that you can limit your test
// runs to files under 100k (or whatever you set in config.json).
// You don't want to pull down lots of multi-gig files when you're
// just running local tests. In production, set maxFileSize to
// zero, or to some huge value to get all files.
func filterLargeFiles (bucketSummaries []*bagman.BucketSummary) (s3Files []*bagman.S3File) {
	for _, bucketSummary := range bucketSummaries {
		for _, key := range bucketSummary.Keys {
			if config.MaxFileSize == 0 || key.Size < config.MaxFileSize {
				s3Files = append(s3Files, &bagman.S3File{bucketSummary.BucketName, key})
			}
		}
	}
	return s3Files
}

// enqueue adds a batch of items to the nsqd work queue
func enqueue(url string, s3Files []*bagman.S3File) {
	jsonData := make([]string, len(s3Files))
	for i, s3File := range s3Files {
		json, err := json.Marshal(s3File)
		if err != nil {
			messageLog.Printf("[ERROR] Error marshalling s3 file to JSON: %v", err)
		} else {
			jsonData[i] = string(json)
			messageLog.Println("[INFO]", "Put", s3File.Key.Key, "into fetch queue")
			//fmt.Println(s3File.Key.Key)
		}
	}
	batch := strings.Join(jsonData, "\n")
	resp, err := http.Post(url, "application/json", bytes.NewBuffer([]byte(batch)))
	if err != nil {
		messageLog.Printf("[ERROR] nsqd returned an error: %v", err)
	}
	if resp.StatusCode != 200 {
		messageLog.Printf("[ERROR] nsqd returned status code %d on last mput", resp.StatusCode)
	}
}
<|endoftext|>


<commit_before>package gedis

import (
	"bytes"
	"errors"
	"strconv"
)

/*
 Redis protocoal

 Redis uses a very simple text protocol, which is binary safe.

 *<num args> CR LF
 $<num bytes arg1> CR LF
 <arg data> CR LF
 ...
 $<num bytes argn> CR LF
 <arg data>
*/

// Writes a string as a sequence of bytes to be send to a Redis
// instance, using the Redis Bulk format.
func WriteBulk(bulk string) []byte {
	var buffer bytes.Buffer

	buffer.WriteByte('$')
	buffer.WriteString(strconv.Itoa(len(bulk)))
	buffer.WriteString("\r\n")

	buffer.WriteString(bulk)
	buffer.WriteString("\r\n")

	return buffer.Bytes()
}

// Writes a sequence of strings as a sequence of bytes to be send to a
// Redis instance, using the Redis Multi-Bulk format.
func WriteMultiBulk(cmd string, args ...string) []byte {
	var buffer bytes.Buffer

	buffer.WriteByte('*')
	buffer.WriteString(strconv.Itoa(1 + len(args)))
	buffer.WriteString("\r\n")

	buffer.Write(WriteBulk(cmd))

	for _, elem := range args {
		buffer.Write(WriteBulk(elem))
	}

	return buffer.Bytes()
}

const (
	StatusReply    = '+'
	ErrorReply     = '-'
	IntegerReply   = ':'
	BulkReply      = '$'
	MultiBulkReply = '*'
)

// Represents a response sent by a Redis server.
type Response struct {
	kind   byte
	status string
	value  []byte
	null   bool
	values [][]byte
}

type ResponseError struct {
	kind, msg string
}

// Returns true if the response is a status response.
func (r *Response) IsStatus() bool {
	return r.kind == StatusReply
}

// Returns true if the response is an integer response.
func (r *Response) IsInteger() bool {
	return r.kind == IntegerReply
}

// Returns true if the response is a bulk response
func (r *Response) IsBulk() bool {
	return r.kind == BulkReply
}

// Returns true if the response is a multi-bulk response.
func (r *Response) IsMultiBulk() bool {
	return r.kind == MultiBulkReply
}

// Returns the status returned in a status response.
func (r *Response) Status() string {
	return string(r.value)
}

// Returns the Int64 in an integer response.
func (r *Response) Integer() (int64, error) {
	return strconv.ParseInt(string(r.value), 10, 64)
}

// Returns the raw value of the response.
func (r *Response) Value() []byte {
	return r.value
}

// Returns true if the bulk or multi-bulk response was nil.
func (r *Response) IsNull() bool {
	return r.null
}

// Returns the raw values in a multi-bulk response.
func (r *Response) Values() [][]byte {
	return r.values
}

func readLine(data []byte, offset int64) ([]byte, int64) {
	n := int64(len(data))
	i := 0

	buffer := make([]byte, n-offset)

	for offset < n {
		if data[offset] == '\r' && data[offset+1] == '\n' {
			break
		} else {
			buffer[i] = data[offset]
			i++
			offset++
		}
	}

	return buffer[:i], int64(offset + 2)
}

// Reads the first bulk response from a sequence of bytes.
func ReadBulk(data []byte, offset int64) ([]byte, int64, error) {
	var value []byte
	var n_offset int64

	value, offset = readLine(data, offset+1)

	num_bytes, err := strconv.ParseInt(string(value), 10, 64)
	if err != nil {
		return value, offset, err
	}

	if num_bytes == int64(-1) {
		return []byte{}, offset, nil
	}

	n_offset = offset + num_bytes

	// This magic 2 is for ending \r\n
	if offset+num_bytes+2 <= int64(len(data)) {
		return data[offset:n_offset], n_offset + 2, nil
	} else {
		return []byte{}, offset, errors.New("not enough bytes in data stream")
	}
}

// Creates a new Response object from a sequence of bytes.
func NewResponse(data []byte) (r Response, err error) {
	r.kind = data[0]

	switch r.kind {
	case StatusReply, IntegerReply, ErrorReply:
		value, _ := readLine(data, 1)

		if r.kind == '-' {
			return r, errors.New(string(value))
		} else {
			r.value = value
		}
	case BulkReply:
		r.value, _, err = ReadBulk(data, 0)

		if len(r.value) == 0 {
			r.null = true
		}

		if err != nil {
			return
		}
	case MultiBulkReply:
		value, offset := readLine(data, 1)

		num_values, err := strconv.ParseInt(string(value), 10, 64)
		if err != nil {
			return r, err
		}

		if num_values == -1 {
			r.null = true
		} else {
			r.values = make([][]byte, num_values)

			for i := int64(0); i < num_values; i++ {
				r.values[i], offset, err = ReadBulk(data, offset)
			}
		}
	}

	return
}
<commit_msg>Improve WriteBulk performance<commit_after>package gedis

import (
	"bytes"
	"errors"
	"strconv"
)

/*
 Redis protocoal

 Redis uses a very simple text protocol, which is binary safe.

 *<num args> CR LF
 $<num bytes arg1> CR LF
 <arg data> CR LF
 ...
 $<num bytes argn> CR LF
 <arg data>
*/

// Writes a string as a sequence of bytes to be send to a Redis
// instance, using the Redis Bulk format.
func WriteBulk(bulk string) []byte {
	bulk_len := strconv.Itoa(len(bulk))

	// '$' + len(string(len(bulk))) + "\r\n" + len(bulk) + "\r\n"
	n := 1 + len(bulk_len) + 2 + len(bulk) + 2

	bytes := make([]byte, n)

	bytes[0] = '$'

	j := 1

	for _, c := range bulk_len {
		bytes[j] = byte(c)
		j++
	}

	bytes[j] = '\r'
	bytes[j+1] = '\n'
	j += 2

	for _, c := range bulk {
		bytes[j] = byte(c)
		j++
	}

	bytes[j] = '\r'
	bytes[j+1] = '\n'

	return bytes
}

// Writes a sequence of strings as a sequence of bytes to be send to a
// Redis instance, using the Redis Multi-Bulk format.
func WriteMultiBulk(cmd string, args ...string) []byte {
	var buffer bytes.Buffer

	buffer.WriteByte('*')
	buffer.WriteString(strconv.Itoa(1 + len(args)))
	buffer.WriteString("\r\n")

	buffer.Write(WriteBulk(cmd))

	for _, elem := range args {
		buffer.Write(WriteBulk(elem))
	}

	return buffer.Bytes()
}

const (
	StatusReply    = '+'
	ErrorReply     = '-'
	IntegerReply   = ':'
	BulkReply      = '$'
	MultiBulkReply = '*'
)

// Represents a response sent by a Redis server.
type Response struct {
	kind   byte
	status string
	value  []byte
	null   bool
	values [][]byte
}

type ResponseError struct {
	kind, msg string
}

// Returns true if the response is a status response.
func (r *Response) IsStatus() bool {
	return r.kind == StatusReply
}

// Returns true if the response is an integer response.
func (r *Response) IsInteger() bool {
	return r.kind == IntegerReply
}

// Returns true if the response is a bulk response
func (r *Response) IsBulk() bool {
	return r.kind == BulkReply
}

// Returns true if the response is a multi-bulk response.
func (r *Response) IsMultiBulk() bool {
	return r.kind == MultiBulkReply
}

// Returns the status returned in a status response.
func (r *Response) Status() string {
	return string(r.value)
}

// Returns the Int64 in an integer response.
func (r *Response) Integer() (int64, error) {
	return strconv.ParseInt(string(r.value), 10, 64)
}

// Returns the raw value of the response.
func (r *Response) Value() []byte {
	return r.value
}

// Returns true if the bulk or multi-bulk response was nil.
func (r *Response) IsNull() bool {
	return r.null
}

// Returns the raw values in a multi-bulk response.
func (r *Response) Values() [][]byte {
	return r.values
}

func readLine(data []byte, offset int64) ([]byte, int64) {
	n := int64(len(data))
	i := 0

	buffer := make([]byte, n-offset)

	for offset < n {
		if data[offset] == '\r' && data[offset+1] == '\n' {
			break
		} else {
			buffer[i] = data[offset]
			i++
			offset++
		}
	}

	return buffer[:i], int64(offset + 2)
}

// Reads the first bulk response from a sequence of bytes.
func ReadBulk(data []byte, offset int64) ([]byte, int64, error) {
	var value []byte
	var n_offset int64

	value, offset = readLine(data, offset+1)

	num_bytes, err := strconv.ParseInt(string(value), 10, 64)
	if err != nil {
		return value, offset, err
	}

	if num_bytes == int64(-1) {
		return []byte{}, offset, nil
	}

	n_offset = offset + num_bytes

	// This magic 2 is for ending \r\n
	if offset+num_bytes+2 <= int64(len(data)) {
		return data[offset:n_offset], n_offset + 2, nil
	} else {
		return []byte{}, offset, errors.New("not enough bytes in data stream")
	}
}

// Creates a new Response object from a sequence of bytes.
func NewResponse(data []byte) (r Response, err error) {
	r.kind = data[0]

	switch r.kind {
	case StatusReply, IntegerReply, ErrorReply:
		value, _ := readLine(data, 1)

		if r.kind == '-' {
			return r, errors.New(string(value))
		} else {
			r.value = value
		}
	case BulkReply:
		r.value, _, err = ReadBulk(data, 0)

		if len(r.value) == 0 {
			r.null = true
		}

		if err != nil {
			return
		}
	case MultiBulkReply:
		value, offset := readLine(data, 1)

		num_values, err := strconv.ParseInt(string(value), 10, 64)
		if err != nil {
			return r, err
		}

		if num_values == -1 {
			r.null = true
		} else {
			r.values = make([][]byte, num_values)

			for i := int64(0); i < num_values; i++ {
				r.values[i], offset, err = ReadBulk(data, offset)
			}
		}
	}

	return
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"errors"
	"github.com/franela/goreq"
	"github.com/gin-gonic/gin"
	"log"
	"strconv"
	"sync/atomic"
	"time"
)

var errTaskNotFresh = errors.New("This task has been running too long to request a token.")
var errAlreadyGivenKey = errors.New("This task has already been given a token.")
var usedTaskIds = NewTtlSet()

func createToken(token string, opts interface{}) (string, error) {
	r, err := VaultRequest{goreq.Request{
		Uri:             vaultPath("/v1/auth/token/create", ""),
		Method:          "POST",
		Body:            opts,
		MaxRedirects:    10,
		RedirectHeaders: true,
	}.WithHeader("X-Vault-Token", token)}.Do()
	if err == nil {
		defer r.Body.Close()
		switch r.StatusCode {
		case 200:
			var t vaultTokenResp
			if err := r.Body.FromJsonTo(&t); err == nil {
				return t.Auth.ClientToken, nil
			} else {
				return "", err
			}
		default:
			var e vaultError
			e.Code = r.StatusCode
			if err := r.Body.FromJsonTo(&e); err == nil {
				return "", e
			} else {
				e.Errors = []string{"communication error."}
				return "", e
			}
		}
	} else {
		return "", err
	}
}

func createWrappedToken(token string, opts interface{}, wrapTTL time.Duration) (string, error) {
	wrapTTLSeconds := strconv.Itoa(int(wrapTTL.Seconds()))

	r, err := VaultRequest{
		goreq.Request{
			Uri:             vaultPath("/v1/auth/token/create", ""),
			Method:          "POST",
			Body:            opts,
			MaxRedirects:    10,
			RedirectHeaders: true,
		}.WithHeader("X-Vault-Token", token).WithHeader("X-Vault-Wrap-TTL", wrapTTLSeconds),
	}.Do()
	defer r.Body.Close()

	if err != nil {
		return "", err
	}

	if r.StatusCode != 200 {
		var e vaultError
		e.Code = r.StatusCode
		if err := r.Body.FromJsonTo(&e); err == nil {
			return "", e
		} else {
			e.Errors = []string{"communication error."}
			return "", e
		}
	}

	t := &vaultTokenResp{}
	if err := r.Body.FromJsonTo(t); err != nil {
		return "", err
	}

	if t.WrapInfo.Token == "" {
		return "",  errors.New("Request for wrapped token did not return wrapped response")
	}

	return t.WrapInfo.Token, nil
}

func createTokenPair(token string, p *policy) (string, error) {
	pol := p.Policies
	if len(pol) == 0 { // explicitly set the policy, else the token will inherit ours
		pol = []string{"default"}
	}

	permTokenOpts := struct {
		Ttl       string            `json:"ttl,omitempty"`
		Policies  []string          `json:"policies"`
		Meta      map[string]string `json:"meta,omitempty"`
		NumUses   int               `json:"num_uses"`
		NoParent  bool              `json:"no_parent"`
		Renewable bool              `json:"renewable"`
	}{time.Duration(time.Duration(p.Ttl) * time.Second).String(), pol, p.Meta, p.NumUses, true, true}

	return createWrappedToken(token, permTokenOpts, 10*time.Minute)
}

func Provide(c *gin.Context) {
	requestStartTime := time.Now()
	state.RLock()
	status := state.Status
	token := state.Token
	state.RUnlock()

	remoteIp := c.Request.RemoteAddr

	atomic.AddInt32(&state.Stats.Requests, 1)

	if status == StatusSealed {
		log.Printf("Rejected token request from %s. Reason: sealed.", remoteIp)
		atomic.AddInt32(&state.Stats.Denied, 1)
		c.JSON(503, struct {
			Status string `json:"status"`
			Ok     bool   `json:"ok"`
			Error  string `json:"error"`
		}{string(state.Status), false, "Gatekeeper is sealed."})
		return
	}

	var reqParams struct {
		TaskId    string `json:"task_id"`
	}
	decoder := json.NewDecoder(c.Request.Body)
	if err := decoder.Decode(&reqParams); err == nil {
		if usedTaskIds.Has(reqParams.TaskId) {
			log.Printf("Rejected token request from %s (Task Id: %s). Reason: %v", remoteIp, reqParams.TaskId, errAlreadyGivenKey)
			atomic.AddInt32(&state.Stats.Denied, 1)
			c.JSON(403, struct {
				Status string `json:"status"`
				Ok     bool   `json:"ok"`
				Error  string `json:"error"`
			}{string(state.Status), false, errAlreadyGivenKey.Error()})
			return
		}
		/*
			The task can start, but the task's framework may have not reported
			that it is RUNNING back to mesos. In this case, the task will still
			be STAGING and have a statuses length of 0.

			This is a network race, so we just sleep and try again.
		*/
		gMT := func(taskId string) (mesosTask, error) {
			task, err := getMesosTask(taskId)
			for i := time.Duration(0); i < 3 && err == nil && len(task.Statuses) == 0; i++ {
				time.Sleep((500 + 250*i) * time.Millisecond)
				task, err = getMesosTask(taskId)
			}
			return task, err
		}
		if task, err := gMT(reqParams.TaskId); err == nil {
			if len(task.Statuses) == 0 {
				log.Printf("Rejected token request from %s (Task Id: %s). Reason: %v (no status)", remoteIp, reqParams.TaskId, errTaskNotFresh)
				atomic.AddInt32(&state.Stats.Denied, 1)
				c.JSON(403, struct {
					Status string `json:"status"`
					Ok     bool   `json:"ok"`
					Error  string `json:"error"`
				}{string(state.Status), false, errTaskNotFresh.Error()})
				return
			}
			// https://github.com/apache/mesos/blob/a61074586d778d432ba991701c9c4de9459db897/src/webui/master/static/js/controllers.js#L148
			startTime := time.Unix(0, int64(task.Statuses[0].Timestamp*1000000000))
			if time.Now().Sub(startTime) > config.MaxTaskLife {
				log.Printf("Rejected token request from %s (Task Id: %s). Reason: %v (no status)", remoteIp, reqParams.TaskId, errTaskNotFresh)
				atomic.AddInt32(&state.Stats.Denied, 1)
				c.JSON(403, struct {
					Status string `json:"status"`
					Ok     bool   `json:"ok"`
					Error  string `json:"error"`
				}{string(state.Status), false, errTaskNotFresh.Error()})
				return
			}
			state.RLock()
			policy := activePolicies.Get(task.Name)
			state.RUnlock()
			if tempToken, err := createTokenPair(token, policy); err == nil {
				log.Printf("Provided token pair for %s in %v. (Task Id: %s) (Task Name: %s). Policies: %v", remoteIp, time.Now().Sub(requestStartTime), reqParams.TaskId, task.Name, policy.Policies)
				atomic.AddInt32(&state.Stats.Successful, 1)
				usedTaskIds.Put(reqParams.TaskId, config.MaxTaskLife+1*time.Minute)
				c.JSON(200, struct {
					Status string `json:"status"`
					Ok     bool   `json:"ok"`
					Token  string `json:"token"`
				}{string(state.Status), true, tempToken})
			} else {
				log.Printf("Failed to create token pair for %s (Task Id: %s). Reason: %v", remoteIp, reqParams.TaskId, errTaskNotFresh)
				atomic.AddInt32(&state.Stats.Denied, 1)
				c.JSON(500, struct {
					Status string `json:"status"`
					Ok     bool   `json:"ok"`
					Error  string `json:"error"`
				}{string(state.Status), false, err.Error()})
			}
		} else if err == errNoSuchTask {
			log.Printf("Rejected token request from %s (Task Id: %s). Reason: %v", remoteIp, reqParams.TaskId, errNoSuchTask)
			atomic.AddInt32(&state.Stats.Denied, 1)
			c.JSON(403, struct {
				Status string `json:"status"`
				Ok     bool   `json:"ok"`
				Error  string `json:"error"`
			}{string(state.Status), false, err.Error()})
		} else {
			log.Printf("Failed to retrieve task information for %s (Task Id: %s). Reason: %v", remoteIp, reqParams.TaskId, err)
			atomic.AddInt32(&state.Stats.Denied, 1)
			c.JSON(500, struct {
				Status string `json:"status"`
				Ok     bool   `json:"ok"`
				Error  string `json:"error"`
			}{string(state.Status), false, err.Error()})
		}
	} else {
		log.Printf("Rejected token request from %s. Reason: %v", remoteIp, err)
		atomic.AddInt32(&state.Stats.Denied, 1)
		c.JSON(400, struct {
			Status string `json:"status"`
			Ok     bool   `json:"ok"`
			Error  string `json:"error"`
		}{string(state.Status), false, err.Error()})
	}
}
<commit_msg>Provider.go: go fmt<commit_after>package main

import (
	"encoding/json"
	"errors"
	"github.com/franela/goreq"
	"github.com/gin-gonic/gin"
	"log"
	"strconv"
	"sync/atomic"
	"time"
)

var errTaskNotFresh = errors.New("This task has been running too long to request a token.")
var errAlreadyGivenKey = errors.New("This task has already been given a token.")
var usedTaskIds = NewTtlSet()

func createToken(token string, opts interface{}) (string, error) {
	r, err := VaultRequest{goreq.Request{
		Uri:             vaultPath("/v1/auth/token/create", ""),
		Method:          "POST",
		Body:            opts,
		MaxRedirects:    10,
		RedirectHeaders: true,
	}.WithHeader("X-Vault-Token", token)}.Do()
	if err == nil {
		defer r.Body.Close()
		switch r.StatusCode {
		case 200:
			var t vaultTokenResp
			if err := r.Body.FromJsonTo(&t); err == nil {
				return t.Auth.ClientToken, nil
			} else {
				return "", err
			}
		default:
			var e vaultError
			e.Code = r.StatusCode
			if err := r.Body.FromJsonTo(&e); err == nil {
				return "", e
			} else {
				e.Errors = []string{"communication error."}
				return "", e
			}
		}
	} else {
		return "", err
	}
}

func createWrappedToken(token string, opts interface{}, wrapTTL time.Duration) (string, error) {
	wrapTTLSeconds := strconv.Itoa(int(wrapTTL.Seconds()))

	r, err := VaultRequest{
		goreq.Request{
			Uri:             vaultPath("/v1/auth/token/create", ""),
			Method:          "POST",
			Body:            opts,
			MaxRedirects:    10,
			RedirectHeaders: true,
		}.WithHeader("X-Vault-Token", token).WithHeader("X-Vault-Wrap-TTL", wrapTTLSeconds),
	}.Do()
	defer r.Body.Close()

	if err != nil {
		return "", err
	}

	if r.StatusCode != 200 {
		var e vaultError
		e.Code = r.StatusCode
		if err := r.Body.FromJsonTo(&e); err == nil {
			return "", e
		} else {
			e.Errors = []string{"communication error."}
			return "", e
		}
	}

	t := &vaultTokenResp{}
	if err := r.Body.FromJsonTo(t); err != nil {
		return "", err
	}

	if t.WrapInfo.Token == "" {
		return "", errors.New("Request for wrapped token did not return wrapped response")
	}

	return t.WrapInfo.Token, nil
}

func createTokenPair(token string, p *policy) (string, error) {
	pol := p.Policies
	if len(pol) == 0 { // explicitly set the policy, else the token will inherit ours
		pol = []string{"default"}
	}

	permTokenOpts := struct {
		Ttl       string            `json:"ttl,omitempty"`
		Policies  []string          `json:"policies"`
		Meta      map[string]string `json:"meta,omitempty"`
		NumUses   int               `json:"num_uses"`
		NoParent  bool              `json:"no_parent"`
		Renewable bool              `json:"renewable"`
	}{time.Duration(time.Duration(p.Ttl) * time.Second).String(), pol, p.Meta, p.NumUses, true, true}

	return createWrappedToken(token, permTokenOpts, 10*time.Minute)
}

func Provide(c *gin.Context) {
	requestStartTime := time.Now()
	state.RLock()
	status := state.Status
	token := state.Token
	state.RUnlock()

	remoteIp := c.Request.RemoteAddr

	atomic.AddInt32(&state.Stats.Requests, 1)

	if status == StatusSealed {
		log.Printf("Rejected token request from %s. Reason: sealed.", remoteIp)
		atomic.AddInt32(&state.Stats.Denied, 1)
		c.JSON(503, struct {
			Status string `json:"status"`
			Ok     bool   `json:"ok"`
			Error  string `json:"error"`
		}{string(state.Status), false, "Gatekeeper is sealed."})
		return
	}

	var reqParams struct {
		TaskId string `json:"task_id"`
	}
	decoder := json.NewDecoder(c.Request.Body)
	if err := decoder.Decode(&reqParams); err == nil {
		if usedTaskIds.Has(reqParams.TaskId) {
			log.Printf("Rejected token request from %s (Task Id: %s). Reason: %v", remoteIp, reqParams.TaskId, errAlreadyGivenKey)
			atomic.AddInt32(&state.Stats.Denied, 1)
			c.JSON(403, struct {
				Status string `json:"status"`
				Ok     bool   `json:"ok"`
				Error  string `json:"error"`
			}{string(state.Status), false, errAlreadyGivenKey.Error()})
			return
		}
		/*
			The task can start, but the task's framework may have not reported
			that it is RUNNING back to mesos. In this case, the task will still
			be STAGING and have a statuses length of 0.

			This is a network race, so we just sleep and try again.
		*/
		gMT := func(taskId string) (mesosTask, error) {
			task, err := getMesosTask(taskId)
			for i := time.Duration(0); i < 3 && err == nil && len(task.Statuses) == 0; i++ {
				time.Sleep((500 + 250*i) * time.Millisecond)
				task, err = getMesosTask(taskId)
			}
			return task, err
		}
		if task, err := gMT(reqParams.TaskId); err == nil {
			if len(task.Statuses) == 0 {
				log.Printf("Rejected token request from %s (Task Id: %s). Reason: %v (no status)", remoteIp, reqParams.TaskId, errTaskNotFresh)
				atomic.AddInt32(&state.Stats.Denied, 1)
				c.JSON(403, struct {
					Status string `json:"status"`
					Ok     bool   `json:"ok"`
					Error  string `json:"error"`
				}{string(state.Status), false, errTaskNotFresh.Error()})
				return
			}
			// https://github.com/apache/mesos/blob/a61074586d778d432ba991701c9c4de9459db897/src/webui/master/static/js/controllers.js#L148
			startTime := time.Unix(0, int64(task.Statuses[0].Timestamp*1000000000))
			if time.Now().Sub(startTime) > config.MaxTaskLife {
				log.Printf("Rejected token request from %s (Task Id: %s). Reason: %v (no status)", remoteIp, reqParams.TaskId, errTaskNotFresh)
				atomic.AddInt32(&state.Stats.Denied, 1)
				c.JSON(403, struct {
					Status string `json:"status"`
					Ok     bool   `json:"ok"`
					Error  string `json:"error"`
				}{string(state.Status), false, errTaskNotFresh.Error()})
				return
			}
			state.RLock()
			policy := activePolicies.Get(task.Name)
			state.RUnlock()
			if tempToken, err := createTokenPair(token, policy); err == nil {
				log.Printf("Provided token pair for %s in %v. (Task Id: %s) (Task Name: %s). Policies: %v", remoteIp, time.Now().Sub(requestStartTime), reqParams.TaskId, task.Name, policy.Policies)
				atomic.AddInt32(&state.Stats.Successful, 1)
				usedTaskIds.Put(reqParams.TaskId, config.MaxTaskLife+1*time.Minute)
				c.JSON(200, struct {
					Status string `json:"status"`
					Ok     bool   `json:"ok"`
					Token  string `json:"token"`
				}{string(state.Status), true, tempToken})
			} else {
				log.Printf("Failed to create token pair for %s (Task Id: %s). Reason: %v", remoteIp, reqParams.TaskId, errTaskNotFresh)
				atomic.AddInt32(&state.Stats.Denied, 1)
				c.JSON(500, struct {
					Status string `json:"status"`
					Ok     bool   `json:"ok"`
					Error  string `json:"error"`
				}{string(state.Status), false, err.Error()})
			}
		} else if err == errNoSuchTask {
			log.Printf("Rejected token request from %s (Task Id: %s). Reason: %v", remoteIp, reqParams.TaskId, errNoSuchTask)
			atomic.AddInt32(&state.Stats.Denied, 1)
			c.JSON(403, struct {
				Status string `json:"status"`
				Ok     bool   `json:"ok"`
				Error  string `json:"error"`
			}{string(state.Status), false, err.Error()})
		} else {
			log.Printf("Failed to retrieve task information for %s (Task Id: %s). Reason: %v", remoteIp, reqParams.TaskId, err)
			atomic.AddInt32(&state.Stats.Denied, 1)
			c.JSON(500, struct {
				Status string `json:"status"`
				Ok     bool   `json:"ok"`
				Error  string `json:"error"`
			}{string(state.Status), false, err.Error()})
		}
	} else {
		log.Printf("Rejected token request from %s. Reason: %v", remoteIp, err)
		atomic.AddInt32(&state.Stats.Denied, 1)
		c.JSON(400, struct {
			Status string `json:"status"`
			Ok     bool   `json:"ok"`
			Error  string `json:"error"`
		}{string(state.Status), false, err.Error()})
	}
}
<|endoftext|>


<commit_before>package main

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

var cmdPushAura = &Command{
	Usage: "pushAura",
	Short: "force pushAura -filename=<filepath>",
	Long: `
	force pushAura -filename <fullFilePath>

	force pushAura -f=<fullFilePath>

	`,
}

func init() {
	cmdPushAura.Run = runPushAura
	cmdPushAura.Flag.StringVar(fileName, "f", "", "fully qualified file name for entity")
	cmdPushAura.Flag.BoolVar(isBundle, "b", false, "Creating a bundle or not")
	cmdPushAura.Flag.StringVar(createType, "t", "", "Type of entity or bundle to create")
}

var (
	fileName   = cmdPushAura.Flag.String("filepath", "", "fully qualified file name for entity")
	isBundle   = cmdPushAura.Flag.Bool("isBundle", false, "Creating a bundle or not")
	createType = cmdPushAura.Flag.String("auraType", "", "Type of entity or bundle to create")
)

func runPushAura(cmd *Command, args []string) {
	force, _ := ActiveForce()

	if _, err := os.Stat(*fileName); os.IsNotExist(err) {
		ErrorAndExit("File does not exist\n" + *fileName)
	}

	// Verify that the file is in an aura bundles folder
	if !inAuraBundlesFolder() {
		ErrorAndExit("File is not in an aura bundle folder (aurabundles")
	}

	// Check for manifest file
	if _, err := os.Stat(filepath.Join(filepath.Dir(*fileName), ".manifest")); os.IsNotExist(err) {
		// No manifest, but is in aurabundle folder, assume creating a new bundle with this file
		// as the first artifact.
		createNewAuraBundleAndDefinition(*force)
	} else {
		// Got the manifest, let's update the artifact
		updateAuraDefinition(*force)
		return
	}

}

func isValidAuraExtension() bool {
	var ext = strings.Trim(strings.ToLower(filepath.Ext(*fileName)), " ")
	fmt.Printf("[%s]\n", ext)
	if ext == ".app" || ext == ".cmp" || ext == ".evt" {
		return true
	} else {
		ErrorAndExit("You need to create an application (.app) or component (.cmp) or and event (.evt) as the first item in your bundle.")
	}
	return false
}

func createNewAuraBundleAndDefinition(force Force) {
	// 	Creating a new bundle. We need
	// 		the name of the bundle (parent folder of file)
	//		the type of artifact (based on naming convention)
	// 		the contents of the file
	fmt.Println("Creating new bundle")
	if isValidAuraExtension() {
		// Need the parent folder name to name the bundle
		var bundleName = filepath.Base(filepath.Dir(*fileName))
		// Create the manifext
		var manifest BundleManifest
		manifest.Name = bundleName

		_, _ = getFormatByFileName()

		// Create a bundle defintion
		bundle, err := force.CreateAuraBundle(bundleName)
		if err != nil {
			ErrorAndExit(err.Error())
		}
		manifest.Id = bundle.Id
		component, err := createBundleEntity(manifest, force)
		if err != nil {
			ErrorAndExit(err.Error())
		}
		createManifest(manifest, component)
	}
}

func createBundleEntity(manifest BundleManifest, force Force) (component ForceCreateRecordResult, err error) {
	// create the bundle entity
	format, deftype := getFormatByFileName()
	mbody, _ := readFile(*fileName)
	component, err = force.CreateAuraComponent(map[string]string{"AuraDefinitionBundleId": manifest.Id, "DefType": deftype, "Format": format, "Source": mbody})
	return
}

func createManifest(manifest BundleManifest, component ForceCreateRecordResult) {
	cfile := ComponentFile{}
	cfile.FileName = *fileName
	cfile.ComponentId = component.Id

	manifest.Files = append(manifest.Files, cfile)
	bmBody, _ := json.Marshal(manifest)

	ioutil.WriteFile(filepath.Join(filepath.Dir(*fileName), ".manifest"), bmBody, 0644)
	return
}

func updateManifest(manifest BundleManifest, component ForceCreateRecordResult) {
	cfile := ComponentFile{}
	cfile.FileName = *fileName
	cfile.ComponentId = component.Id

	manifest.Files = append(manifest.Files, cfile)
	bmBody, _ := json.Marshal(manifest)

	ioutil.WriteFile(filepath.Join(filepath.Dir(*fileName), ".manifest"), bmBody, 0644)
	return
}

func updateAuraDefinition(force Force) {

	//Get the manifest
	mbody, _ := readFile(filepath.Join(filepath.Dir(*fileName), ".manifest"))

	var manifest BundleManifest
	json.Unmarshal([]byte(mbody), &manifest)

	for i := range manifest.Files {
		component := manifest.Files[i]
		if filepath.Base(component.FileName) == filepath.Base(*fileName) {
			//Here is where we make the call to send the update
			mbody, _ = readFile(*fileName)
			err := force.UpdateAuraComponent(map[string]string{"source": mbody}, component.ComponentId)
			if err != nil {
				ErrorAndExit(err.Error())
			}
			fmt.Printf("Aura definition updated: %s\n", filepath.Base(*fileName))
			return
		}
	}
	fmt.Println("Creating new bundle entity")
	component, err := createBundleEntity(manifest, force)
	if err != nil {
		ErrorAndExit(err.Error())
	}
	updateManifest(manifest, component)
	fmt.Println("New component in the bundle")
}

func getFormatByFileName() (format string, defType string) {
	var fname = strings.ToLower(*fileName)
	if strings.Contains(fname, "application.app") {
		format = "XML"
		defType = "APPLICATION"
	} else if strings.Contains(fname, "component.cmp") {
		format = "XML"
		defType = "COMPONENT"
	} else if strings.Contains(fname, "event.evt") {
		format = "XML"
		defType = "EVENT"
	} else if strings.Contains(fname, "controller.js") {
		format = "JS"
		defType = "CONTROLLER"
	} else if strings.Contains(fname, "model.js") {
		format = "JS"
		defType = "MODEL"
	} else if strings.Contains(fname, "helper.js") {
		format = "JS"
		defType = "HELPER"
	} else if strings.Contains(fname, "style.css") {
		format = "CSS"
		defType = "STYLE"
	} else {
		ErrorAndExit("Could not determine aura definition type.")
	}
	return
}

func getDefinitionFormat(deftype string) (result string) {
	switch strings.ToUpper(deftype) {
	case "APPLICATION", "COMPONENT", "EVENT":
		result = "XML"
	case "CONTROLLER", "MODEL", "HELPER":
		result = "JS"
	case "STYLE":
		result = "CSS"
	}
	return
}

func inAuraBundlesFolder() bool {
	var p = *fileName
	var maxLoop = 3
	for filepath.Base(p) != "aurabundles" && maxLoop != 0 {
		p = filepath.Dir(p)
		maxLoop -= 1
	}
	if filepath.Base(p) == "aurabundles" {
		return true
	} else {
		return false
	}

}
func readFile(filename string) (body string, err error) {
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return
	}
	body = string(data)
	return
}
<commit_msg>remove debug statements<commit_after>package main

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

var cmdPushAura = &Command{
	Usage: "pushAura",
	Short: "force pushAura -filename=<filepath>",
	Long: `
	force pushAura -filename <fullFilePath>

	force pushAura -f=<fullFilePath>

	`,
}

func init() {
	cmdPushAura.Run = runPushAura
	cmdPushAura.Flag.StringVar(fileName, "f", "", "fully qualified file name for entity")
	cmdPushAura.Flag.BoolVar(isBundle, "b", false, "Creating a bundle or not")
	cmdPushAura.Flag.StringVar(createType, "t", "", "Type of entity or bundle to create")
}

var (
	fileName   = cmdPushAura.Flag.String("filepath", "", "fully qualified file name for entity")
	isBundle   = cmdPushAura.Flag.Bool("isBundle", false, "Creating a bundle or not")
	createType = cmdPushAura.Flag.String("auraType", "", "Type of entity or bundle to create")
)

func runPushAura(cmd *Command, args []string) {

	if _, err := os.Stat(*fileName); os.IsNotExist(err) {
		fmt.Println(err.Error())
		ErrorAndExit("File does not exist\n" + *fileName)
	}

	// Verify that the file is in an aura bundles folder
	if !inAuraBundlesFolder(*fileName) {
		ErrorAndExit("File is not in an aura bundle folder (aurabundles")
	}

	// See if this is a directory
	info, _ := os.Stat(*fileName)
	if info.IsDir() {
		filepath.Walk(*fileName, func(path string, inf os.FileInfo, err error) error {
			info, err = os.Stat(filepath.Join(*fileName, inf.Name()))
			if err != nil {
				fmt.Println(err.Error())
			} else {
				fmt.Println(inf.Name())
				if info.IsDir() || inf.Name() == ".manifest" {
					fmt.Println("\nSkip")
				} else {
					pushAuraComponent(filepath.Join(*fileName, inf.Name()))
				}
			}
			return nil
		})
	} else {
		pushAuraComponent(*fileName)
	}
	return
}

func pushAuraComponent(fname string) {
	force, _ := ActiveForce()
	// Check for manifest file
	if _, err := os.Stat(filepath.Join(filepath.Dir(fname), ".manifest")); os.IsNotExist(err) {
		// No manifest, but is in aurabundle folder, assume creating a new bundle with this file
		// as the first artifact.
		createNewAuraBundleAndDefinition(*force, fname)
	} else {
		// Got the manifest, let's update the artifact
		updateAuraDefinition(*force, fname)
		return
	}
}

func isValidAuraExtension(fname string) bool {
	var ext = strings.Trim(strings.ToLower(filepath.Ext(fname)), " ")
	if ext == ".app" || ext == ".cmp" || ext == ".evt" {
		return true
	} else {
		ErrorAndExit("You need to create an application (.app) or component (.cmp) or and event (.evt) as the first item in your bundle.")
	}
	return false
}

func createNewAuraBundleAndDefinition(force Force, fname string) {
	// 	Creating a new bundle. We need
	// 		the name of the bundle (parent folder of file)
	//		the type of artifact (based on naming convention)
	// 		the contents of the file
	fmt.Println("Creating new bundle")
	if isValidAuraExtension(fname) {
		// Need the parent folder name to name the bundle
		var bundleName = filepath.Base(filepath.Dir(fname))
		// Create the manifext
		var manifest BundleManifest
		manifest.Name = bundleName

		_, _ = getFormatByFileName(fname)

		// Create a bundle defintion
		bundle, err := force.CreateAuraBundle(bundleName)
		if err != nil {
			ErrorAndExit(err.Error())
		}
		manifest.Id = bundle.Id
		component, err := createBundleEntity(manifest, force, fname)
		if err != nil {
			ErrorAndExit(err.Error())
		}
		createManifest(manifest, component, fname)
	}
}

func createBundleEntity(manifest BundleManifest, force Force, fname string) (component ForceCreateRecordResult, err error) {
	// create the bundle entity
	format, deftype := getFormatByFileName(fname)
	mbody, _ := readFile(fname)
	component, err = force.CreateAuraComponent(map[string]string{"AuraDefinitionBundleId": manifest.Id, "DefType": deftype, "Format": format, "Source": mbody})
	return
}

func createManifest(manifest BundleManifest, component ForceCreateRecordResult, fname string) {
	cfile := ComponentFile{}
	cfile.FileName = fname
	cfile.ComponentId = component.Id

	manifest.Files = append(manifest.Files, cfile)
	bmBody, _ := json.Marshal(manifest)

	ioutil.WriteFile(filepath.Join(filepath.Dir(fname), ".manifest"), bmBody, 0644)
	return
}

func updateManifest(manifest BundleManifest, component ForceCreateRecordResult, fname string) {
	cfile := ComponentFile{}
	cfile.FileName = fname
	cfile.ComponentId = component.Id

	manifest.Files = append(manifest.Files, cfile)
	bmBody, _ := json.Marshal(manifest)

	ioutil.WriteFile(filepath.Join(filepath.Dir(fname), ".manifest"), bmBody, 0644)
	return
}

func updateAuraDefinition(force Force, fname string) {

	//Get the manifest
	mbody, _ := readFile(filepath.Join(filepath.Dir(fname), ".manifest"))

	var manifest BundleManifest
	json.Unmarshal([]byte(mbody), &manifest)

	for i := range manifest.Files {
		component := manifest.Files[i]
		if filepath.Base(component.FileName) == filepath.Base(fname) {
			//Here is where we make the call to send the update
			mbody, _ = readFile(fname)
			err := force.UpdateAuraComponent(map[string]string{"source": mbody}, component.ComponentId)
			if err != nil {
				ErrorAndExit(err.Error())
			}
			fmt.Printf("Aura definition updated: %s\n", filepath.Base(fname))
			return
		}
	}
	fmt.Println("Creating new bundle entity")
	component, err := createBundleEntity(manifest, force, fname)
	if err != nil {
		ErrorAndExit(err.Error())
	}
	updateManifest(manifest, component, fname)
	fmt.Println("New component in the bundle")
}

func getFormatByFileName(filename string) (format string, defType string) {
	var fname = strings.ToLower(filename)
	if strings.Contains(fname, "application.app") {
		format = "XML"
		defType = "APPLICATION"
	} else if strings.Contains(fname, "component.cmp") {
		format = "XML"
		defType = "COMPONENT"
	} else if strings.Contains(fname, "event.evt") {
		format = "XML"
		defType = "EVENT"
	} else if strings.Contains(fname, "controller.js") {
		format = "JS"
		defType = "CONTROLLER"
	} else if strings.Contains(fname, "model.js") {
		format = "JS"
		defType = "MODEL"
	} else if strings.Contains(fname, "helper.js") {
		format = "JS"
		defType = "HELPER"
	} else if strings.Contains(fname, "style.css") {
		format = "CSS"
		defType = "STYLE"
	} else {
		if filepath.Ext(fname) == ".app" {
			format = "XML"
			defType = "APPLICATION"
		} else if filepath.Ext(fname) == ".cmp" {
			format = "XML"
			defType = "COMPONENT"
		} else if filepath.Ext(fname) == ".evt" {
			format = "XML"
			defType = "EVENT"
		} else if filepath.Ext(fname) == ".css" {
			format = "CSS"
			defType = "STYLE"
		} else {
			ErrorAndExit("Could not determine aura definition type.")
		}
	}
	return
}

func getDefinitionFormat(deftype string) (result string) {
	switch strings.ToUpper(deftype) {
	case "APPLICATION", "COMPONENT", "EVENT":
		result = "XML"
	case "CONTROLLER", "MODEL", "HELPER":
		result = "JS"
	case "STYLE":
		result = "CSS"
	}
	return
}

func inAuraBundlesFolder(fname string) bool {
	var p = fname
	var maxLoop = 3
	for filepath.Base(p) != "aurabundles" && maxLoop != 0 {
		p = filepath.Dir(p)
		maxLoop -= 1
	}
	if filepath.Base(p) == "aurabundles" {
		return true
	} else {
		return false
	}

}
func readFile(filename string) (body string, err error) {
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return
	}
	body = string(data)
	return
}
<|endoftext|>


<commit_before>package pwd

import (
	"context"
	"io"
	"net"

	"github.com/play-with-docker/play-with-docker/pwd/types"
	"github.com/stretchr/testify/mock"
)

type Mock struct {
	mock.Mock
}

func (m *Mock) SessionNew(ctx context.Context, config types.SessionConfig) (*types.Session, error) {
	args := m.Called(ctx, config)
	return args.Get(0).(*types.Session), args.Error(1)
}

func (m *Mock) SessionClose(session *types.Session) error {
	args := m.Called(session)
	return args.Error(0)
}

func (m *Mock) SessionGetSmallestViewPort(sessionId string) types.ViewPort {
	args := m.Called(sessionId)
	return args.Get(0).(types.ViewPort)
}

func (m *Mock) SessionDeployStack(session *types.Session) error {
	args := m.Called(session)
	return args.Error(0)
}

func (m *Mock) SessionGet(id string) *types.Session {
	args := m.Called(id)
	return args.Get(0).(*types.Session)
}

func (m *Mock) SessionSetup(session *types.Session, conf SessionSetupConf) error {
	args := m.Called(session, conf)
	return args.Error(0)
}

func (m *Mock) InstanceNew(session *types.Session, conf types.InstanceConfig) (*types.Instance, error) {
	args := m.Called(session, conf)
	return args.Get(0).(*types.Instance), args.Error(1)
}

func (m *Mock) InstanceResizeTerminal(instance *types.Instance, cols, rows uint) error {
	args := m.Called(instance, cols, rows)
	return args.Error(0)
}

func (m *Mock) InstanceGetTerminal(instance *types.Instance) (net.Conn, error) {
	args := m.Called(instance)
	return args.Get(0).(net.Conn), args.Error(1)
}

func (m *Mock) InstanceUploadFromUrl(instance *types.Instance, fileName, dest, url string) error {
	args := m.Called(instance, fileName, dest, url)
	return args.Error(0)
}

func (m *Mock) InstanceUploadFromReader(instance *types.Instance, fileName, dest string, reader io.Reader) error {
	args := m.Called(instance, fileName, dest, reader)
	return args.Error(0)
}

func (m *Mock) InstanceGet(session *types.Session, name string) *types.Instance {
	args := m.Called(session, name)
	return args.Get(0).(*types.Instance)
}
func (m *Mock) InstanceFindBySession(session *types.Session) ([]*types.Instance, error) {
	args := m.Called(session)
	return args.Get(0).([]*types.Instance), args.Error(1)
}

func (m *Mock) InstanceDelete(session *types.Session, instance *types.Instance) error {
	args := m.Called(session, instance)
	return args.Error(0)
}

func (m *Mock) InstanceExec(instance *types.Instance, cmd []string) (int, error) {
	args := m.Called(instance, cmd)
	return args.Int(0), args.Error(1)
}

func (m *Mock) ClientNew(id string, session *types.Session) *types.Client {
	args := m.Called(id, session)
	return args.Get(0).(*types.Client)
}

func (m *Mock) ClientResizeViewPort(client *types.Client, cols, rows uint) {
	m.Called(client, cols, rows)
}

func (m *Mock) ClientClose(client *types.Client) {
	m.Called(client)
}

func (m *Mock) ClientCount() int {
	args := m.Called()
	return args.Int(0)
}

func (m *Mock) UserNewLoginRequest(providerName string) (*types.LoginRequest, error) {
	args := m.Called(providerName)
	return args.Get(0).(*types.LoginRequest), args.Error(1)
}

func (m *Mock) UserGetLoginRequest(id string) (*types.LoginRequest, error) {
	args := m.Called(id)
	return args.Get(0).(*types.LoginRequest), args.Error(1)
}

func (m *Mock) UserLogin(loginRequest *types.LoginRequest, user *types.User) (*types.User, error) {
	args := m.Called(loginRequest, user)
	return args.Get(0).(*types.User), args.Error(1)
}

func (m *Mock) UserGet(id string) (*types.User, error) {
	args := m.Called(id)
	return args.Get(0).(*types.User), args.Error(1)
}

func (m *Mock) PlaygroundNew(playground types.Playground) (*types.Playground, error) {
	args := m.Called(playground)
	return args.Get(0).(*types.Playground), args.Error(1)
}

func (m *Mock) PlaygroundGet(id string) *types.Playground {
	args := m.Called(id)
	return args.Get(0).(*types.Playground)
}

func (m *Mock) PlaygroundFindByDomain(domain string) *types.Playground {
	args := m.Called(domain)
	return args.Get(0).(*types.Playground)
}
func (m *Mock) PlaygroundList() ([]*types.Playground, error) {
	args := m.Called()
	return args.Get(0).([]*types.Playground), args.Error(1)
}
<commit_msg>Fix test<commit_after>package pwd

import (
	"context"
	"io"
	"net"

	"github.com/play-with-docker/play-with-docker/pwd/types"
	"github.com/stretchr/testify/mock"
)

type Mock struct {
	mock.Mock
}

func (m *Mock) SessionNew(ctx context.Context, config types.SessionConfig) (*types.Session, error) {
	args := m.Called(ctx, config)
	return args.Get(0).(*types.Session), args.Error(1)
}

func (m *Mock) SessionClose(session *types.Session) error {
	args := m.Called(session)
	return args.Error(0)
}

func (m *Mock) SessionGetSmallestViewPort(sessionId string) types.ViewPort {
	args := m.Called(sessionId)
	return args.Get(0).(types.ViewPort)
}

func (m *Mock) SessionDeployStack(session *types.Session) error {
	args := m.Called(session)
	return args.Error(0)
}

func (m *Mock) SessionGet(id string) (*types.Session, error) {
	args := m.Called(id)
	return args.Get(0).(*types.Session), args.Error(1)
}

func (m *Mock) SessionSetup(session *types.Session, conf SessionSetupConf) error {
	args := m.Called(session, conf)
	return args.Error(0)
}

func (m *Mock) InstanceNew(session *types.Session, conf types.InstanceConfig) (*types.Instance, error) {
	args := m.Called(session, conf)
	return args.Get(0).(*types.Instance), args.Error(1)
}

func (m *Mock) InstanceResizeTerminal(instance *types.Instance, cols, rows uint) error {
	args := m.Called(instance, cols, rows)
	return args.Error(0)
}

func (m *Mock) InstanceGetTerminal(instance *types.Instance) (net.Conn, error) {
	args := m.Called(instance)
	return args.Get(0).(net.Conn), args.Error(1)
}

func (m *Mock) InstanceUploadFromUrl(instance *types.Instance, fileName, dest, url string) error {
	args := m.Called(instance, fileName, dest, url)
	return args.Error(0)
}

func (m *Mock) InstanceUploadFromReader(instance *types.Instance, fileName, dest string, reader io.Reader) error {
	args := m.Called(instance, fileName, dest, reader)
	return args.Error(0)
}

func (m *Mock) InstanceGet(session *types.Session, name string) *types.Instance {
	args := m.Called(session, name)
	return args.Get(0).(*types.Instance)
}
func (m *Mock) InstanceFindBySession(session *types.Session) ([]*types.Instance, error) {
	args := m.Called(session)
	return args.Get(0).([]*types.Instance), args.Error(1)
}

func (m *Mock) InstanceDelete(session *types.Session, instance *types.Instance) error {
	args := m.Called(session, instance)
	return args.Error(0)
}

func (m *Mock) InstanceExec(instance *types.Instance, cmd []string) (int, error) {
	args := m.Called(instance, cmd)
	return args.Int(0), args.Error(1)
}

func (m *Mock) ClientNew(id string, session *types.Session) *types.Client {
	args := m.Called(id, session)
	return args.Get(0).(*types.Client)
}

func (m *Mock) ClientResizeViewPort(client *types.Client, cols, rows uint) {
	m.Called(client, cols, rows)
}

func (m *Mock) ClientClose(client *types.Client) {
	m.Called(client)
}

func (m *Mock) ClientCount() int {
	args := m.Called()
	return args.Int(0)
}

func (m *Mock) UserNewLoginRequest(providerName string) (*types.LoginRequest, error) {
	args := m.Called(providerName)
	return args.Get(0).(*types.LoginRequest), args.Error(1)
}

func (m *Mock) UserGetLoginRequest(id string) (*types.LoginRequest, error) {
	args := m.Called(id)
	return args.Get(0).(*types.LoginRequest), args.Error(1)
}

func (m *Mock) UserLogin(loginRequest *types.LoginRequest, user *types.User) (*types.User, error) {
	args := m.Called(loginRequest, user)
	return args.Get(0).(*types.User), args.Error(1)
}

func (m *Mock) UserGet(id string) (*types.User, error) {
	args := m.Called(id)
	return args.Get(0).(*types.User), args.Error(1)
}

func (m *Mock) PlaygroundNew(playground types.Playground) (*types.Playground, error) {
	args := m.Called(playground)
	return args.Get(0).(*types.Playground), args.Error(1)
}

func (m *Mock) PlaygroundGet(id string) *types.Playground {
	args := m.Called(id)
	return args.Get(0).(*types.Playground)
}

func (m *Mock) PlaygroundFindByDomain(domain string) *types.Playground {
	args := m.Called(domain)
	return args.Get(0).(*types.Playground)
}
func (m *Mock) PlaygroundList() ([]*types.Playground, error) {
	args := m.Called()
	return args.Get(0).([]*types.Playground), args.Error(1)
}
<|endoftext|>


<commit_before>//+build linux

// Copyright 2016 Cilium Project
// Copyright 2016 Sylvain Afchain
// Copyright 2016 Kinvolk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package elf

import (
	"debug/elf"
	"fmt"
	"io/ioutil"
	"os"
	"strconv"
	"strings"
	"syscall"
)

/*
#include <unistd.h>
#include <linux/bpf.h>
#include <linux/perf_event.h>
#include <linux/unistd.h>

static int perf_event_open_tracepoint(int tracepoint_id, int pid, int cpu,
                           int group_fd, unsigned long flags)
{
	struct perf_event_attr attr = {0,};
	attr.type = PERF_TYPE_TRACEPOINT;
	attr.sample_type = PERF_SAMPLE_RAW;
	attr.sample_period = 1;
	attr.wakeup_events = 1;
	attr.config = tracepoint_id;

	return syscall(__NR_perf_event_open, &attr, pid, cpu,
                      group_fd, flags);
}
*/
import "C"

type Module struct {
	fileName string
	file     *elf.File

	log    []byte
	maps   map[string]*Map
	probes map[string]*Kprobe
}

// Kprobe represents a kprobe or kretprobe and has to be declared
// in the C file,
type Kprobe struct {
	Name  string
	insns *C.struct_bpf_insn
	fd    int
	efd   int
}

func NewModule(fileName string) *Module {
	return &Module{
		fileName: fileName,
		probes:   make(map[string]*Kprobe),
		log:      make([]byte, 65536),
	}
}

func (b *Module) EnableKprobe(secName string) error {
	var probeType, funcName string
	isKretprobe := strings.HasPrefix(secName, "kretprobe/")
	probe, ok := b.probes[secName]
	if !ok {
		return fmt.Errorf("no such kprobe %q", secName)
	}
	progFd := probe.fd
	if isKretprobe {
		probeType = "r"
		funcName = strings.TrimPrefix(secName, "kretprobe/")
	} else {
		probeType = "p"
		funcName = strings.TrimPrefix(secName, "kprobe/")
	}
	eventName := probeType + funcName

	kprobeEventsFileName := "/sys/kernel/debug/tracing/kprobe_events"
	f, err := os.OpenFile(kprobeEventsFileName, os.O_APPEND|os.O_WRONLY, 0666)
	if err != nil {
		return fmt.Errorf("cannot open kprobe_events: %v\n", err)
	}
	defer f.Close()

	cmd := fmt.Sprintf("%s:%s %s\n", probeType, eventName, funcName)
	_, err = f.WriteString(cmd)
	if err != nil {
		return fmt.Errorf("cannot write %q to kprobe_events: %v\n", cmd, err)
	}

	kprobeIdFile := fmt.Sprintf("/sys/kernel/debug/tracing/events/kprobes/%s/id", eventName)
	kprobeIdBytes, err := ioutil.ReadFile(kprobeIdFile)
	if err != nil {
		return fmt.Errorf("cannot read kprobe id: %v\n", err)
	}
	kprobeId, err := strconv.Atoi(strings.TrimSpace(string(kprobeIdBytes)))
	if err != nil {
		return fmt.Errorf("invalid kprobe id): %v\n", err)
	}

	efd := C.perf_event_open_tracepoint(C.int(kprobeId), -1 /* pid */, 0 /* cpu */, -1 /* group_fd */, C.PERF_FLAG_FD_CLOEXEC)
	if efd < 0 {
		return fmt.Errorf("perf_event_open for kprobe error")
	}

	_, _, err2 := syscall.Syscall(syscall.SYS_IOCTL, uintptr(efd), C.PERF_EVENT_IOC_ENABLE, 0)
	if err2 != 0 {
		return fmt.Errorf("error enabling perf event: %v", err2)
	}

	_, _, err2 = syscall.Syscall(syscall.SYS_IOCTL, uintptr(efd), C.PERF_EVENT_IOC_SET_BPF, uintptr(progFd))
	if err2 != 0 {
		return fmt.Errorf("error enabling perf event: %v", err2)
	}
	probe.efd = int(efd)
	return nil
}

func (b *Module) IterKprobes() <-chan *Kprobe {
	ch := make(chan *Kprobe)
	go func() {
		for name := range b.probes {
			ch <- b.probes[name]
		}
		close(ch)
	}()
	return ch
}
<commit_msg>elf: add helper `EnableKprobes()`<commit_after>//+build linux

// Copyright 2016 Cilium Project
// Copyright 2016 Sylvain Afchain
// Copyright 2016 Kinvolk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package elf

import (
	"debug/elf"
	"fmt"
	"io/ioutil"
	"os"
	"strconv"
	"strings"
	"syscall"
)

/*
#include <unistd.h>
#include <linux/bpf.h>
#include <linux/perf_event.h>
#include <linux/unistd.h>

static int perf_event_open_tracepoint(int tracepoint_id, int pid, int cpu,
                           int group_fd, unsigned long flags)
{
	struct perf_event_attr attr = {0,};
	attr.type = PERF_TYPE_TRACEPOINT;
	attr.sample_type = PERF_SAMPLE_RAW;
	attr.sample_period = 1;
	attr.wakeup_events = 1;
	attr.config = tracepoint_id;

	return syscall(__NR_perf_event_open, &attr, pid, cpu,
                      group_fd, flags);
}
*/
import "C"

type Module struct {
	fileName string
	file     *elf.File

	log    []byte
	maps   map[string]*Map
	probes map[string]*Kprobe
}

// Kprobe represents a kprobe or kretprobe and has to be declared
// in the C file,
type Kprobe struct {
	Name  string
	insns *C.struct_bpf_insn
	fd    int
	efd   int
}

func NewModule(fileName string) *Module {
	return &Module{
		fileName: fileName,
		probes:   make(map[string]*Kprobe),
		log:      make([]byte, 65536),
	}
}

func (b *Module) EnableKprobe(secName string) error {
	var probeType, funcName string
	isKretprobe := strings.HasPrefix(secName, "kretprobe/")
	probe, ok := b.probes[secName]
	if !ok {
		return fmt.Errorf("no such kprobe %q", secName)
	}
	progFd := probe.fd
	if isKretprobe {
		probeType = "r"
		funcName = strings.TrimPrefix(secName, "kretprobe/")
	} else {
		probeType = "p"
		funcName = strings.TrimPrefix(secName, "kprobe/")
	}
	eventName := probeType + funcName

	kprobeEventsFileName := "/sys/kernel/debug/tracing/kprobe_events"
	f, err := os.OpenFile(kprobeEventsFileName, os.O_APPEND|os.O_WRONLY, 0666)
	if err != nil {
		return fmt.Errorf("cannot open kprobe_events: %v\n", err)
	}
	defer f.Close()

	cmd := fmt.Sprintf("%s:%s %s\n", probeType, eventName, funcName)
	_, err = f.WriteString(cmd)
	if err != nil {
		return fmt.Errorf("cannot write %q to kprobe_events: %v\n", cmd, err)
	}

	kprobeIdFile := fmt.Sprintf("/sys/kernel/debug/tracing/events/kprobes/%s/id", eventName)
	kprobeIdBytes, err := ioutil.ReadFile(kprobeIdFile)
	if err != nil {
		return fmt.Errorf("cannot read kprobe id: %v\n", err)
	}
	kprobeId, err := strconv.Atoi(strings.TrimSpace(string(kprobeIdBytes)))
	if err != nil {
		return fmt.Errorf("invalid kprobe id): %v\n", err)
	}

	efd := C.perf_event_open_tracepoint(C.int(kprobeId), -1 /* pid */, 0 /* cpu */, -1 /* group_fd */, C.PERF_FLAG_FD_CLOEXEC)
	if efd < 0 {
		return fmt.Errorf("perf_event_open for kprobe error")
	}

	_, _, err2 := syscall.Syscall(syscall.SYS_IOCTL, uintptr(efd), C.PERF_EVENT_IOC_ENABLE, 0)
	if err2 != 0 {
		return fmt.Errorf("error enabling perf event: %v", err2)
	}

	_, _, err2 = syscall.Syscall(syscall.SYS_IOCTL, uintptr(efd), C.PERF_EVENT_IOC_SET_BPF, uintptr(progFd))
	if err2 != 0 {
		return fmt.Errorf("error enabling perf event: %v", err2)
	}
	probe.efd = int(efd)
	return nil
}

func (b *Module) IterKprobes() <-chan *Kprobe {
	ch := make(chan *Kprobe)
	go func() {
		for name := range b.probes {
			ch <- b.probes[name]
		}
		close(ch)
	}()
	return ch
}

func (b *Module) EnableKprobes() error {
	var err error
	for _, kprobe := range b.probes {
		err = b.EnableKprobe(kprobe.Name)
		if err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"log"
	"sort"
	"strings"

	"github.com/couchbaselabs/go-couchbase"
)

var ddocs = map[string]string{
	"default": `{
		"views": {
			"by_build": {
				"map": "function (doc, meta) {emit([doc.build, doc.priority, doc.os], [doc.failCount, doc.totalCount]);}"
			}
		}
	}`,
}

type DataSource struct {
	CouchbaseAddress string
}

func (ds *DataSource) GetBucket(bucket string) *couchbase.Bucket {
	uri := fmt.Sprintf("http://%s:%s@%s/", bucket, "", ds.CouchbaseAddress)

	client, _ := couchbase.Connect(uri)
	pool, _ := client.GetPool("default")

	b, err := pool.GetBucket(bucket)
	if err != nil {
		log.Fatalf("Error reading bucket:  %v", err)
	}
	return b
}

func (ds *DataSource) QueryView(b *couchbase.Bucket, ddoc, view string,
	params map[string]interface{}) []couchbase.ViewRow {
	params["stale"] = "false"
	vr, err := b.View(ddoc, view, params)
	if err != nil {
		ds.installDDoc(ddoc)
	}
	return vr.Rows
}

func (ds *DataSource) installDDoc(ddoc string) {
	b := ds.GetBucket(ddoc) // bucket name == ddoc name
	err := b.PutDDoc(ddoc, ddocs[ddoc])
	if err != nil {
		log.Fatalf("%v", err)
	}
}

func (ds *DataSource) GetTimeline(abs bool) []byte {
	b := ds.GetBucket("default")
	rows := ds.QueryView(b, "default", "by_build", map[string]interface{}{})

	failed := map[string]float64{}
	total := map[string]float64{}
	builds := []string{}
	for i := range rows {
		build := rows[i].Key.([]interface{})[0].(string)
		failCount := rows[i].Value.([]interface{})[0].(float64)
		totalCount := rows[i].Value.([]interface{})[1].(float64)
		if _, ok := failed[build]; ok {
			failed[build] += failCount
		} else {
			failed[build] = failCount
		}
		if _, ok := total[build]; ok {
			total[build] += totalCount
		} else {
			total[build] = totalCount
		}
		builds = append(builds, build)
	}

	passedValues := []interface{}{}
	failedValues := []interface{}{}
	sort.Strings(builds)
	if abs {
		for _, build := range builds {
			passedValues = append(passedValues, []interface{}{
				build,
				total[build] - failed[build],
			})
			failedValues = append(failedValues, []interface{}{
				build,
				-failed[build],
			})
		}
	} else {
		for _, build := range builds {
			passedValues = append(passedValues, []interface{}{
				build,
				100.0 * (total[build] - failed[build]) / total[build],
			})
			failedValues = append(failedValues, []interface{}{
				build,
				100.0 * failed[build] / total[build],
			})
		}
	}

	timeline := []map[string]interface{}{
		map[string]interface{}{"key": "Passed", "values": passedValues},
		map[string]interface{}{"key": "Failed", "values": failedValues},
	}
	j, _ := json.Marshal(timeline)
	return j
}

func appendIfUnique(slice []string, s string) []string {
	for i := range slice {
		if slice[i] == s {
			return slice
		}
	}
	return append(slice, s)
}

func (ds *DataSource) GetBreakdown(build string, by_platform bool) []byte {
	b := ds.GetBucket("default")
	params := map[string]interface{}{"startkey": []string{build}}
	rows := ds.QueryView(b, "default", "by_build", params)

	keys := []string{}
	failed := map[string]float64{}
	total := map[string]float64{}
	for i := range rows {
		var key string
		if by_platform {
			key = rows[i].Key.([]interface{})[2].(string)
		} else {
			key = rows[i].Key.([]interface{})[1].(string)
		}
		if key == "N/A" {
			continue
		}

		failCount := rows[i].Value.([]interface{})[0].(float64)
		totalCount := rows[i].Value.([]interface{})[1].(float64)
		if _, ok := failed[key]; ok {
			failed[key] += failCount
		} else {
			failed[key] = failCount
		}
		if _, ok := total[key]; ok {
			total[key] += totalCount
		} else {
			total[key] = totalCount
		}
		keys = appendIfUnique(keys, key)
	}

	sort.Strings(keys)
	data := map[string]interface{}{}
	for _, key := range keys {
		title := strings.Title(strings.ToLower(key))
		data[title] = []map[string]interface{}{
			{"key": "Passed", "value": total[key] - failed[key]},
			{"key": "Failed", "value": failed[key]},
		}
	}

	j, _ := json.Marshal(data)
	return j
}
<commit_msg>use bucket "jenkins"<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"log"
	"sort"
	"strings"

	"github.com/couchbaselabs/go-couchbase"
)

var ddocs = map[string]string{
	"jenkins": `{
		"views": {
			"by_build": {
				"map": "function (doc, meta) {emit([doc.build, doc.priority, doc.os], [doc.failCount, doc.totalCount]);}"
			}
		}
	}`,
}

type DataSource struct {
	CouchbaseAddress string
}

func (ds *DataSource) GetBucket(bucket string) *couchbase.Bucket {
	uri := fmt.Sprintf("http://%s:%s@%s/", bucket, "", ds.CouchbaseAddress)

	client, _ := couchbase.Connect(uri)
	pool, _ := client.GetPool("jenkins")

	b, err := pool.GetBucket(bucket)
	if err != nil {
		log.Fatalf("Error reading bucket:  %v", err)
	}
	return b
}

func (ds *DataSource) QueryView(b *couchbase.Bucket, ddoc, view string,
	params map[string]interface{}) []couchbase.ViewRow {
	params["stale"] = "false"
	vr, err := b.View(ddoc, view, params)
	if err != nil {
		ds.installDDoc(ddoc)
	}
	return vr.Rows
}

func (ds *DataSource) installDDoc(ddoc string) {
	b := ds.GetBucket(ddoc) // bucket name == ddoc name
	err := b.PutDDoc(ddoc, ddocs[ddoc])
	if err != nil {
		log.Fatalf("%v", err)
	}
}

func (ds *DataSource) GetTimeline(abs bool) []byte {
	b := ds.GetBucket("jenkins")
	rows := ds.QueryView(b, "jenkins", "by_build", map[string]interface{}{})

	failed := map[string]float64{}
	total := map[string]float64{}
	builds := []string{}
	for i := range rows {
		build := rows[i].Key.([]interface{})[0].(string)
		failCount := rows[i].Value.([]interface{})[0].(float64)
		totalCount := rows[i].Value.([]interface{})[1].(float64)
		if _, ok := failed[build]; ok {
			failed[build] += failCount
		} else {
			failed[build] = failCount
		}
		if _, ok := total[build]; ok {
			total[build] += totalCount
		} else {
			total[build] = totalCount
		}
		builds = append(builds, build)
	}

	passedValues := []interface{}{}
	failedValues := []interface{}{}
	sort.Strings(builds)
	if abs {
		for _, build := range builds {
			passedValues = append(passedValues, []interface{}{
				build,
				total[build] - failed[build],
			})
			failedValues = append(failedValues, []interface{}{
				build,
				-failed[build],
			})
		}
	} else {
		for _, build := range builds {
			passedValues = append(passedValues, []interface{}{
				build,
				100.0 * (total[build] - failed[build]) / total[build],
			})
			failedValues = append(failedValues, []interface{}{
				build,
				100.0 * failed[build] / total[build],
			})
		}
	}

	timeline := []map[string]interface{}{
		map[string]interface{}{"key": "Passed", "values": passedValues},
		map[string]interface{}{"key": "Failed", "values": failedValues},
	}
	j, _ := json.Marshal(timeline)
	return j
}

func appendIfUnique(slice []string, s string) []string {
	for i := range slice {
		if slice[i] == s {
			return slice
		}
	}
	return append(slice, s)
}

func (ds *DataSource) GetBreakdown(build string, by_platform bool) []byte {
	b := ds.GetBucket("jenkins")
	params := map[string]interface{}{"startkey": []string{build}}
	rows := ds.QueryView(b, "jenkins", "by_build", params)

	keys := []string{}
	failed := map[string]float64{}
	total := map[string]float64{}
	for i := range rows {
		var key string
		if by_platform {
			key = rows[i].Key.([]interface{})[2].(string)
		} else {
			key = rows[i].Key.([]interface{})[1].(string)
		}
		if key == "N/A" {
			continue
		}

		failCount := rows[i].Value.([]interface{})[0].(float64)
		totalCount := rows[i].Value.([]interface{})[1].(float64)
		if _, ok := failed[key]; ok {
			failed[key] += failCount
		} else {
			failed[key] = failCount
		}
		if _, ok := total[key]; ok {
			total[key] += totalCount
		} else {
			total[key] = totalCount
		}
		keys = appendIfUnique(keys, key)
	}

	sort.Strings(keys)
	data := map[string]interface{}{}
	for _, key := range keys {
		title := strings.Title(strings.ToLower(key))
		data[title] = []map[string]interface{}{
			{"key": "Passed", "value": total[key] - failed[key]},
			{"key": "Failed", "value": failed[key]},
		}
	}

	j, _ := json.Marshal(data)
	return j
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/tls"
	"fmt"
	"net"
	"strings"
	"time"

	"code.cloudfoundry.org/lager"
	"github.com/alphagov/paas-cf/tools/metrics/tlscheck"
)

func TLSValidityGauge(logger lager.Logger, certChecker tlscheck.CertChecker, addr string, interval time.Duration) MetricReadCloser {
	return NewMetricPoller(interval, func(w MetricWriter) error {
		if !strings.Contains(addr, ":") {
			addr += ":443"
		}
		host, _, err := net.SplitHostPort(addr)
		if err != nil {
			return err
		}

		daysUntilExpiry, err := certChecker.DaysUntilExpiry(addr, &tls.Config{})
		if err != nil {
			logger.Error("tls-certificates-validity-failure", err, lager.Data{
				"addr":     addr,
				"hostname": host,
			})
			return err
		}

		metric := Metric{
			Kind:  Gauge,
			Time:  time.Now(),
			Name:  "tls.certificates.validity",
			Value: daysUntilExpiry,
			Tags: []string{
				fmt.Sprintf("hostname:%s", host),
			},
			Unit: "days",
		}
		return w.WriteMetrics([]Metric{metric})
	})
}

func CDNTLSValidityGauge(logger lager.Logger, certChecker tlscheck.CertChecker, cfs *CloudFrontService, interval time.Duration) MetricReadCloser {
	return NewMetricPoller(interval, func(w MetricWriter) error {
		customDomains, err := cfs.CustomDomains()
		if err != nil {
			logger.Error("cloudfront-list-distributions-failure", err, lager.Data{})
			return err
		}

		metrics := []Metric{}
		for _, customDomain := range customDomains {
			daysUntilExpiry, err := certChecker.DaysUntilExpiry(
				customDomain.CloudFrontDomain+":443",
				&tls.Config{ServerName: customDomain.AliasDomain},
			)
			if err != nil {
				logger.Error("cdn-tls-certificates-validity-failure", err, lager.Data{
					"alias_domain":      customDomain.AliasDomain,
					"cloudfront_domain": customDomain.CloudFrontDomain,
				})
			}

			var validity int
			if err == nil {
				validity = 1
				metrics = append(metrics, Metric{
					Kind:  Gauge,
					Time:  time.Now(),
					Name:  "cdn.tls.certificates.expiry",
					Value: daysUntilExpiry,
					Tags: []string{
						fmt.Sprintf("hostname:%s", customDomain.AliasDomain),
					},
					Unit: "days",
				})
			}

			metrics = append(metrics, Metric{
				Kind:  Gauge,
				Time:  time.Now(),
				Name:  "cdn.tls.certificates.validity",
				Value: float64(validity),
				Tags: []string{
					fmt.Sprintf("hostname:%s", customDomain.AliasDomain),
				},
				Unit: "days",
			})
		}
		return w.WriteMetrics(metrics)
	})
}
<commit_msg>`cdn.tls.certificates.validity` metric is unitless<commit_after>package main

import (
	"crypto/tls"
	"fmt"
	"net"
	"strings"
	"time"

	"code.cloudfoundry.org/lager"
	"github.com/alphagov/paas-cf/tools/metrics/tlscheck"
)

func TLSValidityGauge(logger lager.Logger, certChecker tlscheck.CertChecker, addr string, interval time.Duration) MetricReadCloser {
	return NewMetricPoller(interval, func(w MetricWriter) error {
		if !strings.Contains(addr, ":") {
			addr += ":443"
		}
		host, _, err := net.SplitHostPort(addr)
		if err != nil {
			return err
		}

		daysUntilExpiry, err := certChecker.DaysUntilExpiry(addr, &tls.Config{})
		if err != nil {
			logger.Error("tls-certificates-validity-failure", err, lager.Data{
				"addr":     addr,
				"hostname": host,
			})
			return err
		}

		metric := Metric{
			Kind:  Gauge,
			Time:  time.Now(),
			Name:  "tls.certificates.validity",
			Value: daysUntilExpiry,
			Tags: []string{
				fmt.Sprintf("hostname:%s", host),
			},
			Unit: "days",
		}
		return w.WriteMetrics([]Metric{metric})
	})
}

func CDNTLSValidityGauge(logger lager.Logger, certChecker tlscheck.CertChecker, cfs *CloudFrontService, interval time.Duration) MetricReadCloser {
	return NewMetricPoller(interval, func(w MetricWriter) error {
		customDomains, err := cfs.CustomDomains()
		if err != nil {
			logger.Error("cloudfront-list-distributions-failure", err, lager.Data{})
			return err
		}

		metrics := []Metric{}
		for _, customDomain := range customDomains {
			daysUntilExpiry, err := certChecker.DaysUntilExpiry(
				customDomain.CloudFrontDomain+":443",
				&tls.Config{ServerName: customDomain.AliasDomain},
			)
			if err != nil {
				logger.Error("cdn-tls-certificates-validity-failure", err, lager.Data{
					"alias_domain":      customDomain.AliasDomain,
					"cloudfront_domain": customDomain.CloudFrontDomain,
				})
			}

			var validity int
			if err == nil {
				validity = 1
				metrics = append(metrics, Metric{
					Kind:  Gauge,
					Time:  time.Now(),
					Name:  "cdn.tls.certificates.expiry",
					Value: daysUntilExpiry,
					Tags: []string{
						fmt.Sprintf("hostname:%s", customDomain.AliasDomain),
					},
					Unit: "days",
				})
			}

			metrics = append(metrics, Metric{
				Kind:  Gauge,
				Time:  time.Now(),
				Name:  "cdn.tls.certificates.validity",
				Value: float64(validity),
				Tags: []string{
					fmt.Sprintf("hostname:%s", customDomain.AliasDomain),
				},
				Unit: "",
			})
		}
		return w.WriteMetrics(metrics)
	})
}
<|endoftext|>