<commit_before>//Copyright 2017-2019 Baidu Inc.
//
//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 logs

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/logs"
	"github.com/olivere/elastic"
	"os"
	"path"
	"rasp-cloud/es"
	"rasp-cloud/tools"
	"time"
	"rasp-cloud/conf"
)

type AggrTimeParam struct {
	AppId     string `json:"app_id"`
	StartTime int64  `json:"start_time"`
	EndTime   int64  `json:"end_time"`
	Interval  string `json:"interval"`
	TimeZone  string `json:"time_zone"`
}

type AggrFieldParam struct {
	AppId     string `json:"app_id"`
	StartTime int64  `json:"start_time"`
	EndTime   int64  `json:"end_time"`
	Size      int    `json:"size"`
}

type SearchAttackParam struct {
	Page    int `json:"page"`
	Perpage int `json:"perpage"`
	Data *struct {
		Id             string    `json:"_id,omitempty"`
		AppId          string    `json:"app_id,omitempty"`
		StartTime      int64     `json:"start_time"`
		EndTime        int64     `json:"end_time"`
		RaspId         string    `json:"rasp_id,omitempty"`
		HostName       string    `json:"server_hostname,omitempty"`
		AttackSource   string    `json:"attack_source,omitempty"`
		AttackUrl      string    `json:"url,omitempty"`
		LocalIp        string    `json:"local_ip,omitempty"`
		StackMd5       string    `json:"stack_md5,omitempty"`
		AttackType     *[]string `json:"attack_type,omitempty"`
		InterceptState *[]string `json:"intercept_state,omitempty"`
	} `json:"data"`
}

type SearchPolicyParam struct {
	Page    int `json:"page"`
	Perpage int `json:"perpage"`
	Data *struct {
		Id        string    `json:"_id,omitempty"`
		AppId     string    `json:"app_id,omitempty"`
		StartTime int64     `json:"start_time"`
		EndTime   int64     `json:"end_time"`
		RaspId    string    `json:"rasp_id,omitempty"`
		HostName  string    `json:"server_hostname,omitempty"`
		LocalIp   string    `json:"local_ip,omitempty"`
		PolicyId  *[]string `json:"policy_id,omitempty"`
	} `json:"data"`
}

type SearchErrorParam struct {
	Page    int `json:"page"`
	Perpage int `json:"perpage"`
	Data *struct {
		Id        string `json:"_id,omitempty"`
		AppId     string `json:"app_id,omitempty"`
		StartTime int64  `json:"start_time"`
		EndTime   int64  `json:"end_time"`
		RaspId    string `json:"rasp_id,omitempty"`
		HostName  string `json:"server_hostname,omitempty"`
		LocalIp   string `json:"local_ip,omitempty"`
	} `json:"data"`
}

type AlarmLogInfo struct {
	EsType       string
	EsIndex      string
	EsAliasIndex string
	TtlTime      time.Duration
	FileLogger   *logs.BeeLogger
	AlarmBuffer  chan map[string]interface{}
}

var (
	AddAlarmFunc func(string, map[string]interface{}) error
	alarmInfos   = make(map[string]*AlarmLogInfo)
)

func init() {
	if conf.AppConfig.AlarmLogMode == "file" {
		AddAlarmFunc = AddLogWithFile
	} else if conf.AppConfig.AlarmLogMode == "es" {
		startEsAlarmLogPush()
		AddAlarmFunc = AddLogWithES
	} else {
		tools.Panic(tools.ErrCodeConfigInitFailed, "Unrecognized the value of RaspLogMode config", nil)
	}
}

func registerAlarmInfo(info *AlarmLogInfo) {
	alarmInfos[info.EsType] = info
	es.RegisterTTL(info.TtlTime, info.EsAliasIndex+"-*")
}

func initAlarmFileLogger(dirName string, fileName string) *logs.BeeLogger {
	currentPath, err := tools.GetCurrentPath()
	if err != nil {
		tools.Panic(tools.ErrCodeLogInitFailed, "failed to init alarm logger", err)
	}
	dirName = currentPath + dirName
	if isExists, _ := tools.PathExists(dirName); !isExists {
		err := os.MkdirAll(dirName, os.ModePerm)
		if err != nil {
			tools.Panic(tools.ErrCodeLogInitFailed, "failed to init alarm logger", err)
		}
	}

	logger := logs.NewLogger()
	logPath := path.Join(dirName, fileName)
	err = logger.SetLogger(tools.AdapterAlarmFile,
		`{"filename":"`+logPath+`", "daily":true, "maxdays":10, "perm":"0777"}`)
	if err != nil {
		tools.Panic(tools.ErrCodeLogInitFailed, "failed to init alarm logger", err)
	}
	return logger
}

func startEsAlarmLogPush() {
	go func() {
		for {
			handleEsLogPush()
		}
	}()
}

func handleEsLogPush() {
	defer func() {
		if r := recover(); r != nil {
			beego.Error("failed to push es alarm log: ", r)
		}
	}()
	select {
	case alarm := <-AttackAlarmInfo.AlarmBuffer:
		alarms := make([]map[string]interface{}, 0, 200)
		alarms = append(alarms, alarm)
		for len(AttackAlarmInfo.AlarmBuffer) > 0 && len(alarms) < 200 {
			alarm := <-AttackAlarmInfo.AlarmBuffer
			alarms = append(alarms, alarm)
		}
		err := es.BulkInsert(AttackAlarmInfo.EsType, alarms)
		if err != nil {
			beego.Error("failed to execute es bulk insert for attack alarm: " + err.Error())
		}
	case alarm := <-PolicyAlarmInfo.AlarmBuffer:
		alarms := make([]map[string]interface{}, 0, 200)
		alarms = append(alarms, alarm)
		for len(PolicyAlarmInfo.AlarmBuffer) > 0 && len(alarms) < 200 {
			alarm := <-PolicyAlarmInfo.AlarmBuffer
			alarms = append(alarms, alarm)
		}
		err := es.BulkInsert(PolicyAlarmInfo.EsType, alarms)
		if err != nil {
			beego.Error("failed to execute es bulk insert for policy alarm: " + err.Error())
		}
	case alarm := <-ErrorAlarmInfo.AlarmBuffer:
		alarms := make([]map[string]interface{}, 0, 200)
		alarms = append(alarms, alarm)
		for len(ErrorAlarmInfo.AlarmBuffer) > 0 && len(alarms) < 200 {
			alarm := <-ErrorAlarmInfo.AlarmBuffer
			alarms = append(alarms, alarm)
		}
		err := es.BulkInsert(ErrorAlarmInfo.EsType, alarms)
		if err != nil {
			beego.Error("failed to execute es bulk insert for error alarm: " + err.Error())
		}
	}
}

func AddLogWithFile(alarmType string, alarm map[string]interface{}) error {
	if info, ok := alarmInfos[alarmType]; ok && info.FileLogger != nil {
		content, err := json.Marshal(alarm)
		if err != nil {
			return err
		}
		_, err = info.FileLogger.Write(content)
		if err != nil {
			logs.Error("failed to write rasp log: " + err.Error())
			return err
		}
	} else {
		logs.Error("failed to write rasp log, unrecognized log type: " + alarmType)
	}
	return nil
}

func AddLogWithES(alarmType string, alarm map[string]interface{}) error {
	select {
	case alarmInfos[alarmType].AlarmBuffer <- alarm:
	default:
		logs.Error("Failed to write attack alarm to ES, " +
			"the buffer is full. Consider increase AlarmBufferSize value: " + fmt.Sprintf("%+v", alarm))
	}
	return nil
}

func getVulnAggr(attackTimeTopHitName string) (*elastic.TermsAggregation) {
	attackMaxAggrName := "attack_max_aggr"
	attackTimeTopHitAggr := elastic.NewTopHitsAggregation().
		Size(1).
		Sort("event_time", false).
		DocvalueFields("event_time", "attack_type", "intercept_state", "url",
		"path", "rasp_id", "attack_source", "plugin_algorithm", "server_ip", "server_hostname")
	attackTimeMaxAggr := elastic.NewMaxAggregation().Field("event_time")
	return elastic.NewTermsAggregation().
		Field("stack_md5").
		Size(10000).
		Order(attackMaxAggrName, false).
		SubAggregation(attackMaxAggrName, attackTimeMaxAggr).
		SubAggregation(attackTimeTopHitName, attackTimeTopHitAggr)
}

func SearchLogs(startTime int64, endTime int64, isAttachAggr bool, query map[string]interface{}, sortField string,
	page int, perpage int, ascending bool, index ...string) (int64, []map[string]interface{}, error) {
	var total int64
	var attackAggrName = "attack_aggr"
	var attackTimeTopHitName = "attack_time_top_hit"
	filterQueries := make([]elastic.Query, 0, len(query)+1)
	shouldQueries := make([]elastic.Query, 0, len(query)+1)
	if query != nil {
		for key, value := range query {
			if key == "attack_type" {
				if v, ok := value.([]interface{}); ok {
					filterQueries = append(filterQueries, elastic.NewTermsQuery(key, v...))
				} else {
					filterQueries = append(filterQueries, elastic.NewTermQuery(key, value))
				}
			} else if key == "intercept_state" {
				if v, ok := value.([]interface{}); ok {
					filterQueries = append(filterQueries, elastic.NewTermsQuery(key, v...))
				} else {
					filterQueries = append(filterQueries, elastic.NewTermQuery(key, value))
				}
			} else if key == "policy_id" {
				if v, ok := value.([]interface{}); ok {
					filterQueries = append(filterQueries, elastic.NewTermsQuery(key, v...))
				} else {
					filterQueries = append(filterQueries, elastic.NewTermQuery(key, value))
				}
			} else if key == "local_ip" {
				filterQueries = append(filterQueries,
					elastic.NewNestedQuery("server_nic", elastic.NewTermQuery("server_nic.ip", value)))
			} else if key == "attack_source" {
				filterQueries = append(filterQueries, elastic.NewWildcardQuery(key, "*"+fmt.Sprint(value)+"*"))
			} else if key == "server_hostname" {
				shouldQueries = append(shouldQueries,
					elastic.NewWildcardQuery("server_hostname", "*"+fmt.Sprint(value)+"*"))
				shouldQueries = append(shouldQueries,
					elastic.NewNestedQuery("server_nic",
						elastic.NewWildcardQuery("server_nic.ip", "*"+fmt.Sprint(value)+"*")))
			} else {
				filterQueries = append(filterQueries, elastic.NewTermQuery(key, value))
			}
		}
	}
	filterQueries = append(filterQueries, elastic.NewRangeQuery("event_time").Gte(startTime).Lte(endTime))
	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(15*time.Second))
	defer cancel()
	boolQuery := elastic.NewBoolQuery().Filter(filterQueries...)
	if len(shouldQueries) > 0 {
		boolQuery.Should(shouldQueries...).MinimumNumberShouldMatch(1)
	}

	queryService := es.ElasticClient.Search(index...).Query(boolQuery)

	if isAttachAggr {
		attackAggr := getVulnAggr(attackTimeTopHitName)
		queryService.Aggregation(attackAggrName, attackAggr).Size(0)
	} else {
		queryService.From((page - 1) * perpage).Size(perpage).Sort(sortField, ascending)
	}

	queryResult, err := queryService.Do(ctx)

	if err != nil {
		if queryResult != nil && queryResult.Error != nil {
			beego.Error(queryResult.Error, index)
		}
		return 0, nil, err
	}

	result := make([]map[string]interface{}, 0)
	if !isAttachAggr {
		if queryResult != nil && queryResult.Hits != nil && queryResult.Hits.Hits != nil {
			hits := queryResult.Hits.Hits
			total = queryResult.Hits.TotalHits
			result = make([]map[string]interface{}, len(hits))
			for index, item := range hits {
				result[index] = make(map[string]interface{})
				err := json.Unmarshal(*item.Source, &result[index])
				if err != nil {
					return 0, nil, err
				}
				result[index]["id"] = item.Id
				delete(result[index], "_@timestamp")
				delete(result[index], "@timestamp")
				delete(result[index], "@version")
				delete(result[index], "tags")
				delete(result[index], "host")
			}
		}
	} else {
		if queryResult != nil && queryResult.Aggregations != nil {
			if terms, ok := queryResult.Aggregations.Terms(attackAggrName); ok && terms.Buckets != nil {
				total = int64(len(terms.Buckets))
				result = make([]map[string]interface{}, 0, perpage)
				for i := 0; i < perpage; i++ {
					index := i + (page-1)*perpage
					if index >= int(total) {
						break
					}
					value := make(map[string]interface{})
					item := terms.Buckets[index]
					if topHit, ok := item.TopHits(attackTimeTopHitName); ok &&
						topHit.Hits != nil && topHit.Hits.Hits != nil {
						hits := topHit.Hits.Hits
						if len(hits) > 0 {
							err := json.Unmarshal(*hits[0].Source, &value)
							if err != nil {
								return 0, nil, err
							}
							value["id"] = hits[0].Id
							value["attack_count"] = terms.Buckets[index].DocCount
							result = append(result, value)
						}
					}
				}
			}

		}
	}

	return total, result, nil
}

func CreateAlarmEsIndex(appId string) (err error) {
	for _, alarmInfo := range alarmInfos {
		err = es.CreateEsIndex(alarmInfo.EsIndex + "-" + appId)
		if err != nil {
			return
		}
	}
	return
}
<commit_msg>modify the rasp-cloud api<commit_after>//Copyright 2017-2019 Baidu Inc.
//
//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 logs

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/logs"
	"github.com/olivere/elastic"
	"os"
	"path"
	"rasp-cloud/es"
	"rasp-cloud/tools"
	"time"
	"rasp-cloud/conf"
)

type AggrTimeParam struct {
	AppId     string `json:"app_id"`
	StartTime int64  `json:"start_time"`
	EndTime   int64  `json:"end_time"`
	Interval  string `json:"interval"`
	TimeZone  string `json:"time_zone"`
}

type AggrFieldParam struct {
	AppId     string `json:"app_id"`
	StartTime int64  `json:"start_time"`
	EndTime   int64  `json:"end_time"`
	Size      int    `json:"size"`
}

type SearchAttackParam struct {
	Page    int `json:"page"`
	Perpage int `json:"perpage"`
	Data *struct {
		Id             string    `json:"_id,omitempty"`
		AppId          string    `json:"app_id,omitempty"`
		StartTime      int64     `json:"start_time"`
		EndTime        int64     `json:"end_time"`
		RaspId         string    `json:"rasp_id,omitempty"`
		HostName       string    `json:"server_hostname,omitempty"`
		AttackSource   string    `json:"attack_source,omitempty"`
		AttackUrl      string    `json:"url,omitempty"`
		LocalIp        string    `json:"local_ip,omitempty"`
		StackMd5       string    `json:"stack_md5,omitempty"`
		AttackType     *[]string `json:"attack_type,omitempty"`
		InterceptState *[]string `json:"intercept_state,omitempty"`
	} `json:"data"`
}

type SearchPolicyParam struct {
	Page    int `json:"page"`
	Perpage int `json:"perpage"`
	Data *struct {
		Id        string    `json:"_id,omitempty"`
		AppId     string    `json:"app_id,omitempty"`
		StartTime int64     `json:"start_time"`
		EndTime   int64     `json:"end_time"`
		RaspId    string    `json:"rasp_id,omitempty"`
		HostName  string    `json:"server_hostname,omitempty"`
		LocalIp   string    `json:"local_ip,omitempty"`
		PolicyId  *[]string `json:"policy_id,omitempty"`
	} `json:"data"`
}

type SearchErrorParam struct {
	Page    int `json:"page"`
	Perpage int `json:"perpage"`
	Data *struct {
		Id        string `json:"_id,omitempty"`
		AppId     string `json:"app_id,omitempty"`
		StartTime int64  `json:"start_time"`
		EndTime   int64  `json:"end_time"`
		RaspId    string `json:"rasp_id,omitempty"`
		HostName  string `json:"server_hostname,omitempty"`
		LocalIp   string `json:"local_ip,omitempty"`
	} `json:"data"`
}

type AlarmLogInfo struct {
	EsType       string
	EsIndex      string
	EsAliasIndex string
	TtlTime      time.Duration
	FileLogger   *logs.BeeLogger
	AlarmBuffer  chan map[string]interface{}
}

var (
	AddAlarmFunc func(string, map[string]interface{}) error
	alarmInfos   = make(map[string]*AlarmLogInfo)
)

func init() {
	if conf.AppConfig.AlarmLogMode == "file" {
		AddAlarmFunc = AddLogWithFile
	} else if conf.AppConfig.AlarmLogMode == "es" {
		startEsAlarmLogPush()
		AddAlarmFunc = AddLogWithES
	} else {
		tools.Panic(tools.ErrCodeConfigInitFailed, "Unrecognized the value of RaspLogMode config", nil)
	}
}

func registerAlarmInfo(info *AlarmLogInfo) {
	alarmInfos[info.EsType] = info
	es.RegisterTTL(info.TtlTime, info.EsAliasIndex+"-*")
}

func initAlarmFileLogger(dirName string, fileName string) *logs.BeeLogger {
	currentPath, err := tools.GetCurrentPath()
	if err != nil {
		tools.Panic(tools.ErrCodeLogInitFailed, "failed to init alarm logger", err)
	}
	dirName = currentPath + dirName
	if isExists, _ := tools.PathExists(dirName); !isExists {
		err := os.MkdirAll(dirName, os.ModePerm)
		if err != nil {
			tools.Panic(tools.ErrCodeLogInitFailed, "failed to init alarm logger", err)
		}
	}

	logger := logs.NewLogger()
	logPath := path.Join(dirName, fileName)
	err = logger.SetLogger(tools.AdapterAlarmFile,
		`{"filename":"`+logPath+`", "daily":true, "maxdays":10, "perm":"0777"}`)
	if err != nil {
		tools.Panic(tools.ErrCodeLogInitFailed, "failed to init alarm logger", err)
	}
	return logger
}

func startEsAlarmLogPush() {
	go func() {
		for {
			handleEsLogPush()
		}
	}()
}

func handleEsLogPush() {
	defer func() {
		if r := recover(); r != nil {
			beego.Error("failed to push es alarm log: ", r)
		}
	}()
	select {
	case alarm := <-AttackAlarmInfo.AlarmBuffer:
		alarms := make([]map[string]interface{}, 0, 200)
		alarms = append(alarms, alarm)
		for len(AttackAlarmInfo.AlarmBuffer) > 0 && len(alarms) < 200 {
			alarm := <-AttackAlarmInfo.AlarmBuffer
			alarms = append(alarms, alarm)
		}
		err := es.BulkInsert(AttackAlarmInfo.EsType, alarms)
		if err != nil {
			beego.Error("failed to execute es bulk insert for attack alarm: " + err.Error())
		}
	case alarm := <-PolicyAlarmInfo.AlarmBuffer:
		alarms := make([]map[string]interface{}, 0, 200)
		alarms = append(alarms, alarm)
		for len(PolicyAlarmInfo.AlarmBuffer) > 0 && len(alarms) < 200 {
			alarm := <-PolicyAlarmInfo.AlarmBuffer
			alarms = append(alarms, alarm)
		}
		err := es.BulkInsert(PolicyAlarmInfo.EsType, alarms)
		if err != nil {
			beego.Error("failed to execute es bulk insert for policy alarm: " + err.Error())
		}
	case alarm := <-ErrorAlarmInfo.AlarmBuffer:
		alarms := make([]map[string]interface{}, 0, 200)
		alarms = append(alarms, alarm)
		for len(ErrorAlarmInfo.AlarmBuffer) > 0 && len(alarms) < 200 {
			alarm := <-ErrorAlarmInfo.AlarmBuffer
			alarms = append(alarms, alarm)
		}
		err := es.BulkInsert(ErrorAlarmInfo.EsType, alarms)
		if err != nil {
			beego.Error("failed to execute es bulk insert for error alarm: " + err.Error())
		}
	}
}

func AddLogWithFile(alarmType string, alarm map[string]interface{}) error {
	if info, ok := alarmInfos[alarmType]; ok && info.FileLogger != nil {
		content, err := json.Marshal(alarm)
		if err != nil {
			return err
		}
		_, err = info.FileLogger.Write(content)
		if err != nil {
			logs.Error("failed to write rasp log: " + err.Error())
			return err
		}
	} else {
		logs.Error("failed to write rasp log, unrecognized log type: " + alarmType)
	}
	return nil
}

func AddLogWithES(alarmType string, alarm map[string]interface{}) error {
	select {
	case alarmInfos[alarmType].AlarmBuffer <- alarm:
	default:
		logs.Error("Failed to write attack alarm to ES, " +
			"the buffer is full. Consider increase AlarmBufferSize value: " + fmt.Sprintf("%+v", alarm))
	}
	return nil
}

func getVulnAggr(attackTimeTopHitName string) (*elastic.TermsAggregation) {
	attackMaxAggrName := "attack_max_aggr"
	attackTimeTopHitAggr := elastic.NewTopHitsAggregation().
		Size(1).
		Sort("event_time", false).
		DocvalueFields("event_time", "attack_type", "intercept_state", "url",
		"path", "rasp_id", "attack_source", "plugin_algorithm", "server_ip", "server_hostname")
	attackTimeMaxAggr := elastic.NewMaxAggregation().Field("event_time")
	return elastic.NewTermsAggregation().
		Field("stack_md5").
		Size(10000).
		Order(attackMaxAggrName, false).
		SubAggregation(attackMaxAggrName, attackTimeMaxAggr).
		SubAggregation(attackTimeTopHitName, attackTimeTopHitAggr)
}

func SearchLogs(startTime int64, endTime int64, isAttachAggr bool, query map[string]interface{}, sortField string,
	page int, perpage int, ascending bool, index ...string) (int64, []map[string]interface{}, error) {
	var total int64
	var attackAggrName = "attack_aggr"
	var attackTimeTopHitName = "attack_time_top_hit"
	filterQueries := make([]elastic.Query, 0, len(query)+1)
	shouldQueries := make([]elastic.Query, 0, len(query)+1)
	if query != nil {
		for key, value := range query {
			if key == "attack_type" {
				if v, ok := value.([]interface{}); ok {
					filterQueries = append(filterQueries, elastic.NewTermsQuery(key, v...))
				} else {
					filterQueries = append(filterQueries, elastic.NewTermQuery(key, value))
				}
			} else if key == "intercept_state" {
				if v, ok := value.([]interface{}); ok {
					filterQueries = append(filterQueries, elastic.NewTermsQuery(key, v...))
				} else {
					filterQueries = append(filterQueries, elastic.NewTermQuery(key, value))
				}
			} else if key == "policy_id" {
				if v, ok := value.([]interface{}); ok {
					filterQueries = append(filterQueries, elastic.NewTermsQuery(key, v...))
				} else {
					filterQueries = append(filterQueries, elastic.NewTermQuery(key, value))
				}
			} else if key == "local_ip" {
				filterQueries = append(filterQueries,
					elastic.NewNestedQuery("server_nic", elastic.NewTermQuery("server_nic.ip", value)))
			} else if key == "attack_source" {
				filterQueries = append(filterQueries, elastic.NewWildcardQuery(key, "*"+fmt.Sprint(value)+"*"))
			} else if key == "server_hostname" {
				shouldQueries = append(shouldQueries,
					elastic.NewWildcardQuery("server_hostname", "*"+fmt.Sprint(value)+"*"))
				shouldQueries = append(shouldQueries,
					elastic.NewNestedQuery("server_nic",
						elastic.NewWildcardQuery("server_nic.ip", "*"+fmt.Sprint(value)+"*")))
			} else if key == "url" {
				filterQueries = append(filterQueries,
					elastic.NewWildcardQuery("url", "*"+fmt.Sprint(value)+"*"))
			} else {
				filterQueries = append(filterQueries, elastic.NewTermQuery(key, value))
			}
		}
	}
	filterQueries = append(filterQueries, elastic.NewRangeQuery("event_time").Gte(startTime).Lte(endTime))
	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(15*time.Second))
	defer cancel()
	boolQuery := elastic.NewBoolQuery().Filter(filterQueries...)
	if len(shouldQueries) > 0 {
		boolQuery.Should(shouldQueries...).MinimumNumberShouldMatch(1)
	}

	queryService := es.ElasticClient.Search(index...).Query(boolQuery)

	if isAttachAggr {
		attackAggr := getVulnAggr(attackTimeTopHitName)
		queryService.Aggregation(attackAggrName, attackAggr).Size(0)
	} else {
		queryService.From((page - 1) * perpage).Size(perpage).Sort(sortField, ascending)
	}

	queryResult, err := queryService.Do(ctx)

	if err != nil {
		if queryResult != nil && queryResult.Error != nil {
			beego.Error(queryResult.Error, index)
		}
		return 0, nil, err
	}

	result := make([]map[string]interface{}, 0)
	if !isAttachAggr {
		if queryResult != nil && queryResult.Hits != nil && queryResult.Hits.Hits != nil {
			hits := queryResult.Hits.Hits
			total = queryResult.Hits.TotalHits
			result = make([]map[string]interface{}, len(hits))
			for index, item := range hits {
				result[index] = make(map[string]interface{})
				err := json.Unmarshal(*item.Source, &result[index])
				if err != nil {
					return 0, nil, err
				}
				result[index]["id"] = item.Id
				delete(result[index], "_@timestamp")
				delete(result[index], "@timestamp")
				delete(result[index], "@version")
				delete(result[index], "tags")
				delete(result[index], "host")
			}
		}
	} else {
		if queryResult != nil && queryResult.Aggregations != nil {
			if terms, ok := queryResult.Aggregations.Terms(attackAggrName); ok && terms.Buckets != nil {
				total = int64(len(terms.Buckets))
				result = make([]map[string]interface{}, 0, perpage)
				for i := 0; i < perpage; i++ {
					index := i + (page-1)*perpage
					if index >= int(total) {
						break
					}
					value := make(map[string]interface{})
					item := terms.Buckets[index]
					if topHit, ok := item.TopHits(attackTimeTopHitName); ok &&
						topHit.Hits != nil && topHit.Hits.Hits != nil {
						hits := topHit.Hits.Hits
						if len(hits) > 0 {
							err := json.Unmarshal(*hits[0].Source, &value)
							if err != nil {
								return 0, nil, err
							}
							value["id"] = hits[0].Id
							value["attack_count"] = terms.Buckets[index].DocCount
							result = append(result, value)
						}
					}
				}
			}

		}
	}

	return total, result, nil
}

func CreateAlarmEsIndex(appId string) (err error) {
	for _, alarmInfo := range alarmInfos {
		err = es.CreateEsIndex(alarmInfo.EsIndex + "-" + appId)
		if err != nil {
			return
		}
	}
	return
}
<|endoftext|>


<commit_before>package commands

import (
	"github.com/github/git-media/filters"
	"github.com/github/git-media/gitmedia"
	"github.com/github/git-media/metafile"
	"github.com/spf13/cobra"
	"os"
)

var (
	smudgeInfo = false
	smudgeCmd  = &cobra.Command{
		Use:   "smudge",
		Short: "Implements the Git smudge filter",
		Run:   smudgeCommand,
	}
)

func smudgeCommand(cmd *cobra.Command, args []string) {
	gitmedia.InstallHooks()

	pointer, err := metafile.Decode(os.Stdin)
	if err != nil {
		Panic(err, "Error reading git-media meta data from stdin:")
	}

	if smudgeInfo {
		localPath, err := gitmedia.LocalMediaPath(pointer.Oid)
		if err != nil {
			Exit(err.Error())
		}

		stat, err := os.Stat(localPath)
		if err != nil {
			localPath = "--"
			Print("%d --", pointer.Size)
			return
		}

		Print("%d %s", stat.Size(), localPath)
		return
	}

	err = filters.Smudge(os.Stdout, pointer.Oid)
	if err != nil {
		smudgerr := err.(*filters.SmudgeError)
		Panic(err, "Error reading file from local media dir: %s", smudgerr.Filename)
	}
}

func init() {
	smudgeCmd.Flags().BoolVarP(&smudgeInfo, "info", "i", false, "whatever")
	RootCmd.AddCommand(smudgeCmd)
}
<commit_msg>remove unnecessary var<commit_after>package commands

import (
	"github.com/github/git-media/filters"
	"github.com/github/git-media/gitmedia"
	"github.com/github/git-media/metafile"
	"github.com/spf13/cobra"
	"os"
)

var (
	smudgeInfo = false
	smudgeCmd  = &cobra.Command{
		Use:   "smudge",
		Short: "Implements the Git smudge filter",
		Run:   smudgeCommand,
	}
)

func smudgeCommand(cmd *cobra.Command, args []string) {
	gitmedia.InstallHooks()

	pointer, err := metafile.Decode(os.Stdin)
	if err != nil {
		Panic(err, "Error reading git-media meta data from stdin:")
	}

	if smudgeInfo {
		localPath, err := gitmedia.LocalMediaPath(pointer.Oid)
		if err != nil {
			Exit(err.Error())
		}

		stat, err := os.Stat(localPath)
		if err != nil {
			Print("%d --", pointer.Size)
		} else {
			Print("%d %s", stat.Size(), localPath)
		}
		return
	}

	err = filters.Smudge(os.Stdout, pointer.Oid)
	if err != nil {
		smudgerr := err.(*filters.SmudgeError)
		Panic(err, "Error reading file from local media dir: %s", smudgerr.Filename)
	}
}

func init() {
	smudgeCmd.Flags().BoolVarP(&smudgeInfo, "info", "i", false, "whatever")
	RootCmd.AddCommand(smudgeCmd)
}
<|endoftext|>


<commit_before>package controllers

import (
	"html/template"
	"log"
	"net/http"
	"strconv"
	"time"

	"github.com/gophergala2016/gophertron/models"
	"github.com/gorilla/websocket"
)

func Create(w http.ResponseWriter, r *http.Request) {
	values := r.URL.Query()
	height, err := strconv.Atoi(values.Get("height"))
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	width, err := strconv.Atoi(values.Get("width"))
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	needed, err := strconv.Atoi(values.Get("needed"))
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	if needed == 1 || needed == 0 {
		return
	}

	field, err := models.NewField(height, width, needed)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	http.Redirect(w, r, "/join?id="+field.ID, http.StatusTemporaryRedirect)
}

var upgrader = websocket.Upgrader{
	CheckOrigin: func(_ *http.Request) bool {
		return true
	},
}

func Join(w http.ResponseWriter, r *http.Request) {
	id := r.URL.Query().Get("id")
	//log.Println(id)
	_, ok := models.GetGame(id)
	if !ok {
		http.Error(w, "Couldn't find game", 404)
		return
	}

	cookie := http.Cookie{
		Name:    "game-id",
		Value:   id,
		Expires: time.Now().Add(100 * time.Second),
	}
	http.SetCookie(w, &cookie)

	http.Redirect(w, r, "/game", http.StatusTemporaryRedirect)
}

func Game(w http.ResponseWriter, r *http.Request) {
	cookie, err := r.Cookie("game-id")
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	field, ok := models.GetGame(cookie.Value)
	if !ok {
		http.Error(w, "Couldn't find game", 404)
		return
	}

	templ := template.Must(template.ParseFiles("./views/game.html"))
	templ.Execute(w, map[string]interface{}{
		//multiply by ten to get a bigger canvas
		"height": field.Height * 10,
		"width":  field.Width * 10,
	})
}

func WebSocket(w http.ResponseWriter, r *http.Request) {
	//log.Println("reached")
	cookie, err := r.Cookie("game-id")
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	//log.Println(cookie)
	field, ok := models.GetGame(cookie.Value)
	if !ok {
		http.Error(w, "Couldn't find game", 404)
		return
	}

	gopher := models.NewGopher()
	index, err := field.Add(gopher)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	log.Println("Added ", index)

	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		return
	}

	go listener(conn, index, field)
	go sendPath(conn, gopher.Paths, gopher.Close)
}
<commit_msg>Send notification when field is full<commit_after>package controllers

import (
	"html/template"
	"net/http"
	"strconv"
	"time"

	"github.com/gophergala2016/gophertron/models"
	"github.com/gorilla/websocket"
)

func Create(w http.ResponseWriter, r *http.Request) {
	values := r.URL.Query()
	height, err := strconv.Atoi(values.Get("height"))
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	width, err := strconv.Atoi(values.Get("width"))
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	needed, err := strconv.Atoi(values.Get("needed"))
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	if needed == 1 || needed == 0 {
		return
	}

	field, err := models.NewField(height, width, needed)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	http.Redirect(w, r, "/join?id="+field.ID, http.StatusTemporaryRedirect)
}

var upgrader = websocket.Upgrader{
	CheckOrigin: func(_ *http.Request) bool {
		return true
	},
}

func Join(w http.ResponseWriter, r *http.Request) {
	id := r.URL.Query().Get("id")
	//log.Println(id)
	_, ok := models.GetGame(id)
	if !ok {
		http.Error(w, "Couldn't find game", 404)
		return
	}

	cookie := http.Cookie{
		Name:    "game-id",
		Value:   id,
		Expires: time.Now().Add(100 * time.Second),
	}
	http.SetCookie(w, &cookie)

	http.Redirect(w, r, "/game", http.StatusTemporaryRedirect)
}

func Game(w http.ResponseWriter, r *http.Request) {
	cookie, err := r.Cookie("game-id")
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	field, ok := models.GetGame(cookie.Value)
	if !ok {
		http.Error(w, "Couldn't find game", 404)
		return
	}

	templ := template.Must(template.ParseFiles("./views/game.html"))
	templ.Execute(w, map[string]interface{}{
		//multiply by ten to get a bigger canvas
		"height": field.Height * 10,
		"width":  field.Width * 10,
	})
}

func WebSocket(w http.ResponseWriter, r *http.Request) {
	//log.Println("reached")
	cookie, err := r.Cookie("game-id")
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	//log.Println(cookie)
	field, ok := models.GetGame(cookie.Value)
	if !ok {
		http.Error(w, "Couldn't find game", 404)
		return
	}

	gopher := models.NewGopher()
	index, err := field.Add(gopher)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		return
	}
	if len(field.Gophers) == field.Needed {
		conn.WriteMessage(websocket.TextMessage, []byte("notification"))
	}

	go listener(conn, index, field)
	go sendPath(conn, gopher.Paths, gopher.Close, gopher.Notify)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"time"

	"github.com/nelhage/taktician/ai"
	"github.com/nelhage/taktician/cli"
	"github.com/nelhage/taktician/ptn"
	"github.com/nelhage/taktician/tak"
)

var (
	depth     = flag.Int("depth", 5, "minimax depth")
	all       = flag.Bool("all", false, "show all possible moves")
	tps       = flag.Bool("tps", false, "render position in tps")
	move      = flag.Int("move", 0, "PTN move number to analyze")
	timeLimit = flag.Duration("limit", time.Minute, "limit of how much time to use")
	black     = flag.Bool("black", false, "only analyze black's move")
	white     = flag.Bool("white", false, "only analyze white's move")
	seed      = flag.Int64("seed", 0, "specify a seed")
	debug     = flag.Int("debug", 1, "debug level")
)

func main() {
	flag.Parse()

	f, e := os.Open(flag.Arg(0))
	if e != nil {
		log.Fatal("open:", e)
	}
	parsed, e := ptn.ParsePTN(f)
	if e != nil {
		log.Fatal("parse:", e)
	}
	color := tak.NoColor
	switch {
	case *white && *black:
		log.Fatal("-white and -black are exclusive")
	case *white:
		color = tak.White
	case *black:
		color = tak.Black
	case *move != 0:
		color = tak.White
	}
	p, e := parsed.PositionAtMove(*move, color)
	if e != nil {
		log.Fatal("find move:", e)
	}

	analyze(p)
}

func analyze(p *tak.Position) {
	player := ai.NewMinimax(ai.MinimaxConfig{
		Size:  p.Size(),
		Depth: *depth,
		Seed:  *seed,
		Debug: *debug,
	})
	pv, val, _ := player.Analyze(p, *timeLimit)
	cli.RenderBoard(os.Stdout, p)
	fmt.Printf("AI analysis:\n")
	fmt.Printf(" pv=")
	for _, m := range pv {
		fmt.Printf("%s ", ptn.FormatMove(&m))
	}
	fmt.Printf("\n")
	fmt.Printf(" value=%d\n", val)
	if *tps {
		fmt.Printf("[TPS \"%s\"]\n", ptn.FormatTPS(p))
	}
	if *all {
		fmt.Printf(" all moves:")
		for _, m := range p.AllMoves() {
			fmt.Printf(" %s", ptn.FormatMove(&m))
		}
		fmt.Printf("\n")
	}
	fmt.Println()

	for _, m := range pv {
		p, _ = p.Move(&m)
	}

	fmt.Println("Resulting position:")
	cli.RenderBoard(os.Stdout, p)

	fmt.Println()
	fmt.Println()
}
<commit_msg>add analyzetak -quiet<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"time"

	"github.com/nelhage/taktician/ai"
	"github.com/nelhage/taktician/cli"
	"github.com/nelhage/taktician/ptn"
	"github.com/nelhage/taktician/tak"
)

var (
	depth     = flag.Int("depth", 5, "minimax depth")
	all       = flag.Bool("all", false, "show all possible moves")
	tps       = flag.Bool("tps", false, "render position in tps")
	move      = flag.Int("move", 0, "PTN move number to analyze")
	timeLimit = flag.Duration("limit", time.Minute, "limit of how much time to use")
	black     = flag.Bool("black", false, "only analyze black's move")
	white     = flag.Bool("white", false, "only analyze white's move")
	seed      = flag.Int64("seed", 0, "specify a seed")
	debug     = flag.Int("debug", 1, "debug level")
	quiet     = flag.Bool("quiet", false, "don't print board diagrams")
)

func main() {
	flag.Parse()

	f, e := os.Open(flag.Arg(0))
	if e != nil {
		log.Fatal("open:", e)
	}
	parsed, e := ptn.ParsePTN(f)
	if e != nil {
		log.Fatal("parse:", e)
	}
	color := tak.NoColor
	switch {
	case *white && *black:
		log.Fatal("-white and -black are exclusive")
	case *white:
		color = tak.White
	case *black:
		color = tak.Black
	case *move != 0:
		color = tak.White
	}
	p, e := parsed.PositionAtMove(*move, color)
	if e != nil {
		log.Fatal("find move:", e)
	}

	analyze(p)
}

func analyze(p *tak.Position) {
	player := ai.NewMinimax(ai.MinimaxConfig{
		Size:  p.Size(),
		Depth: *depth,
		Seed:  *seed,
		Debug: *debug,
	})
	pv, val, _ := player.Analyze(p, *timeLimit)
	if !*quiet {
		cli.RenderBoard(os.Stdout, p)
	}
	fmt.Printf("AI analysis:\n")
	fmt.Printf(" pv=")
	for _, m := range pv {
		fmt.Printf("%s ", ptn.FormatMove(&m))
	}
	fmt.Printf("\n")
	fmt.Printf(" value=%d\n", val)
	if *tps {
		fmt.Printf("[TPS \"%s\"]\n", ptn.FormatTPS(p))
	}
	if *all {
		fmt.Printf(" all moves:")
		for _, m := range p.AllMoves() {
			fmt.Printf(" %s", ptn.FormatMove(&m))
		}
		fmt.Printf("\n")
	}
	fmt.Println()

	for _, m := range pv {
		p, _ = p.Move(&m)
	}

	if !*quiet {
		fmt.Println("Resulting position:")
		cli.RenderBoard(os.Stdout, p)
	}

	fmt.Println()
	fmt.Println()
}
<|endoftext|>


<commit_before>package commands

import (
	"crypto/sha256"
	"fmt"
	"io"
	"os"
	"regexp"
	"strings"

	"github.com/git-lfs/git-lfs/git"
	"github.com/git-lfs/git-lfs/lfs"
	"github.com/spf13/cobra"
)

var (
	porcelain = false
)

func statusCommand(cmd *cobra.Command, args []string) {
	requireInRepo()

	// tolerate errors getting ref so this works before first commit
	ref, _ := git.CurrentRef()

	scanIndexAt := "HEAD"
	if ref == nil {
		scanIndexAt = git.RefBeforeFirstCommit
	}

	if porcelain {
		porcelainStagedPointers(scanIndexAt)
		return
	}

	statusScanRefRange(ref)

	staged, unstaged, err := scanIndex(scanIndexAt)
	if err != nil {
		ExitWithError(err)
	}

	Print("\nGit LFS objects to be committed:\n")
	for _, entry := range staged {
		switch entry.Status {
		case lfs.StatusRename, lfs.StatusCopy:
			Print("\t%s -> %s", entry.SrcName, entry.DstName)
		default:
			Print("\t%s", entry.SrcName)
		}
	}

	Print("\nGit LFS objects not staged for commit:\n")
	for _, entry := range unstaged {
		Print("\t%s", entry.SrcName)
	}

	Print("")
}

var z40 = regexp.MustCompile(`\^?0{40}`)

func blobInfoFrom(s *lfs.CatFileBatchScanner, entry *lfs.DiffIndexEntry) (sha, from string, err error) {
	var blobSha string = entry.SrcSha
	if z40.MatchString(blobSha) {
		blobSha = entry.DstSha
	}

	return blobInfo(s, blobSha, entry.SrcName)
}

func blobInfoTo(s *lfs.CatFileBatchScanner, entry *lfs.DiffIndexEntry) (sha, from string, err error) {
	var name string = entry.DstName
	if len(name) == 0 {
		name = entry.SrcName
	}

	return blobInfo(s, entry.DstSha, name)
}

func blobInfo(s *lfs.CatFileBatchScanner, blobSha, name string) (sha, from string, err error) {
	if !z40.MatchString(blobSha) {
		s.Scan([]byte(blobSha))
		if err := s.Err(); err != nil {
			return "", "", err
		}

		var from string
		if s.Pointer() != nil {
			from = "LFS"
		} else {
			from = "Git"
		}

		return s.ContentsSha(), from, nil
	}

	f, err := os.Open(name)
	if err != nil {
		return "", "", err
	}
	defer f.Close()

	shasum := sha256.New()
	if _, err = io.Copy(shasum, f); err != nil {
		return "", "", err
	}

	return fmt.Sprintf("%x", shasum.Sum(nil)), "Git", nil
}

func scanIndex(ref string) (staged, unstaged []*lfs.DiffIndexEntry, err error) {
	uncached, err := lfs.NewDiffIndexScanner(ref, false)
	if err != nil {
		return nil, nil, err
	}

	cached, err := lfs.NewDiffIndexScanner(ref, true)
	if err != nil {
		return nil, nil, err
	}

	seenNames := make(map[string]struct{}, 0)

	staged, err = drainScanner(seenNames, cached)
	if err != nil {
		return nil, nil, err
	}

	unstaged, err = drainScanner(seenNames, uncached)
	if err != nil {
		return nil, nil, err
	}

	return
}

func drainScanner(cache map[string]struct{}, scanner *lfs.DiffIndexScanner) ([]*lfs.DiffIndexEntry, error) {
	var to []*lfs.DiffIndexEntry

	for scanner.Scan() {
		entry := scanner.Entry()

		key := keyFromEntry(entry)
		if _, seen := cache[key]; !seen {
			to = append(to, entry)

			cache[key] = struct{}{}
		}
	}

	if err := scanner.Err(); err != nil {
		return nil, err
	}
	return to, nil
}

func keyFromEntry(e *lfs.DiffIndexEntry) string {
	var name string = e.DstName
	if len(name) == 0 {
		name = e.SrcName
	}

	return strings.Join([]string{e.SrcSha, e.DstSha, name}, ":")
}

func statusScanRefRange(ref *git.Ref) {
	if ref == nil {
		return
	}

	Print("On branch %s", ref.Name)

	remoteRef, err := git.CurrentRemoteRef()
	if err != nil {
		return
	}

	gitscanner := lfs.NewGitScanner(func(p *lfs.WrappedPointer, err error) {
		if err != nil {
			Panic(err, "Could not scan for Git LFS objects")
			return
		}

		Print("\t%s (%s)", p.Name)
	})
	defer gitscanner.Close()

	Print("Git LFS objects to be pushed to %s:\n", remoteRef.Name)
	if err := gitscanner.ScanRefRange(ref.Sha, "^"+remoteRef.Sha, nil); err != nil {
		Panic(err, "Could not scan for Git LFS objects")
	}

}

func porcelainStagedPointers(ref string) {
	staged, unstaged, err := scanIndex(ref)
	if err != nil {
		ExitWithError(err)
	}

	seenNames := make(map[string]struct{})

	for _, entry := range append(unstaged, staged...) {
		name := entry.DstName
		if len(name) == 0 {
			name = entry.SrcName
		}

		if _, seen := seenNames[name]; !seen {
			Print(porcelainStatusLine(entry))

			seenNames[name] = struct{}{}
		}
	}
}

func porcelainStatusLine(entry *lfs.DiffIndexEntry) string {
	switch entry.Status {
	case lfs.StatusRename, lfs.StatusCopy:
		return fmt.Sprintf("%s  %s -> %s", entry.Status, entry.SrcName, entry.DstName)
	case lfs.StatusModification:
		return fmt.Sprintf(" %s %s", entry.Status, entry.SrcName)
	}

	return fmt.Sprintf("%s  %s", entry.Status, entry.SrcName)
}

func init() {
	RegisterCommand("status", statusCommand, func(cmd *cobra.Command) {
		cmd.Flags().BoolVarP(&porcelain, "porcelain", "p", false, "Give the output in an easy-to-parse format for scripts.")
	})
}
<commit_msg>commands/status: implement formatBlobInfo to format blob info<commit_after>package commands

import (
	"crypto/sha256"
	"fmt"
	"io"
	"os"
	"regexp"
	"strings"

	"github.com/git-lfs/git-lfs/git"
	"github.com/git-lfs/git-lfs/lfs"
	"github.com/spf13/cobra"
)

var (
	porcelain = false
)

func statusCommand(cmd *cobra.Command, args []string) {
	requireInRepo()

	// tolerate errors getting ref so this works before first commit
	ref, _ := git.CurrentRef()

	scanIndexAt := "HEAD"
	if ref == nil {
		scanIndexAt = git.RefBeforeFirstCommit
	}

	if porcelain {
		porcelainStagedPointers(scanIndexAt)
		return
	}

	statusScanRefRange(ref)

	staged, unstaged, err := scanIndex(scanIndexAt)
	if err != nil {
		ExitWithError(err)
	}

	Print("\nGit LFS objects to be committed:\n")
	for _, entry := range staged {
		switch entry.Status {
		case lfs.StatusRename, lfs.StatusCopy:
			Print("\t%s -> %s", entry.SrcName, entry.DstName)
		default:
			Print("\t%s", entry.SrcName)
		}
	}

	Print("\nGit LFS objects not staged for commit:\n")
	for _, entry := range unstaged {
		Print("\t%s", entry.SrcName)
	}

	Print("")
}

var z40 = regexp.MustCompile(`\^?0{40}`)

func formatBlobInfo(s *lfs.CatFileBatchScanner, entry *lfs.DiffIndexEntry) string {
	fromSha, fromSrc, err := blobInfoFrom(s, entry)
	if err != nil {
		ExitWithError(err)
	}

	from := fmt.Sprintf("%s: %s", fromSrc, fromSha[:7])
	if entry.Status == lfs.StatusAddition {
		return from
	}

	toSha, toSrc, err := blobInfoTo(s, entry)
	if err != nil {
		ExitWithError(err)
	}
	to := fmt.Sprintf("%s: %s", toSrc, toSha[:7])

	return fmt.Sprintf("%s -> %s", from, to)
}

func blobInfoFrom(s *lfs.CatFileBatchScanner, entry *lfs.DiffIndexEntry) (sha, from string, err error) {
	var blobSha string = entry.SrcSha
	if z40.MatchString(blobSha) {
		blobSha = entry.DstSha
	}

	return blobInfo(s, blobSha, entry.SrcName)
}

func blobInfoTo(s *lfs.CatFileBatchScanner, entry *lfs.DiffIndexEntry) (sha, from string, err error) {
	var name string = entry.DstName
	if len(name) == 0 {
		name = entry.SrcName
	}

	return blobInfo(s, entry.DstSha, name)
}

func blobInfo(s *lfs.CatFileBatchScanner, blobSha, name string) (sha, from string, err error) {
	if !z40.MatchString(blobSha) {
		s.Scan([]byte(blobSha))
		if err := s.Err(); err != nil {
			return "", "", err
		}

		var from string
		if s.Pointer() != nil {
			from = "LFS"
		} else {
			from = "Git"
		}

		return s.ContentsSha(), from, nil
	}

	f, err := os.Open(name)
	if err != nil {
		return "", "", err
	}
	defer f.Close()

	shasum := sha256.New()
	if _, err = io.Copy(shasum, f); err != nil {
		return "", "", err
	}

	return fmt.Sprintf("%x", shasum.Sum(nil)), "Git", nil
}

func scanIndex(ref string) (staged, unstaged []*lfs.DiffIndexEntry, err error) {
	uncached, err := lfs.NewDiffIndexScanner(ref, false)
	if err != nil {
		return nil, nil, err
	}

	cached, err := lfs.NewDiffIndexScanner(ref, true)
	if err != nil {
		return nil, nil, err
	}

	seenNames := make(map[string]struct{}, 0)

	staged, err = drainScanner(seenNames, cached)
	if err != nil {
		return nil, nil, err
	}

	unstaged, err = drainScanner(seenNames, uncached)
	if err != nil {
		return nil, nil, err
	}

	return
}

func drainScanner(cache map[string]struct{}, scanner *lfs.DiffIndexScanner) ([]*lfs.DiffIndexEntry, error) {
	var to []*lfs.DiffIndexEntry

	for scanner.Scan() {
		entry := scanner.Entry()

		key := keyFromEntry(entry)
		if _, seen := cache[key]; !seen {
			to = append(to, entry)

			cache[key] = struct{}{}
		}
	}

	if err := scanner.Err(); err != nil {
		return nil, err
	}
	return to, nil
}

func keyFromEntry(e *lfs.DiffIndexEntry) string {
	var name string = e.DstName
	if len(name) == 0 {
		name = e.SrcName
	}

	return strings.Join([]string{e.SrcSha, e.DstSha, name}, ":")
}

func statusScanRefRange(ref *git.Ref) {
	if ref == nil {
		return
	}

	Print("On branch %s", ref.Name)

	remoteRef, err := git.CurrentRemoteRef()
	if err != nil {
		return
	}

	gitscanner := lfs.NewGitScanner(func(p *lfs.WrappedPointer, err error) {
		if err != nil {
			Panic(err, "Could not scan for Git LFS objects")
			return
		}

		Print("\t%s (%s)", p.Name)
	})
	defer gitscanner.Close()

	Print("Git LFS objects to be pushed to %s:\n", remoteRef.Name)
	if err := gitscanner.ScanRefRange(ref.Sha, "^"+remoteRef.Sha, nil); err != nil {
		Panic(err, "Could not scan for Git LFS objects")
	}

}

func porcelainStagedPointers(ref string) {
	staged, unstaged, err := scanIndex(ref)
	if err != nil {
		ExitWithError(err)
	}

	seenNames := make(map[string]struct{})

	for _, entry := range append(unstaged, staged...) {
		name := entry.DstName
		if len(name) == 0 {
			name = entry.SrcName
		}

		if _, seen := seenNames[name]; !seen {
			Print(porcelainStatusLine(entry))

			seenNames[name] = struct{}{}
		}
	}
}

func porcelainStatusLine(entry *lfs.DiffIndexEntry) string {
	switch entry.Status {
	case lfs.StatusRename, lfs.StatusCopy:
		return fmt.Sprintf("%s  %s -> %s", entry.Status, entry.SrcName, entry.DstName)
	case lfs.StatusModification:
		return fmt.Sprintf(" %s %s", entry.Status, entry.SrcName)
	}

	return fmt.Sprintf("%s  %s", entry.Status, entry.SrcName)
}

func init() {
	RegisterCommand("status", statusCommand, func(cmd *cobra.Command) {
		cmd.Flags().BoolVarP(&porcelain, "porcelain", "p", false, "Give the output in an easy-to-parse format for scripts.")
	})
}
<|endoftext|>


<commit_before>package controllers

import (
	"fmt"
	"github.com/Luncher/go-rest/forms"
	"github.com/Luncher/go-rest/models"
	"github.com/gin-gonic/gin"
)

var movieModel = new(models.MovieModel)

type UserController struct{}

func (user *UserController) Create(c *gin.Context) {
	var data forms.CreateMovieCommand
	if c.BindJSON(&data) != nil {
		c.JSON(406, gin.H{"message": "Invalid form", "form": data})
		c.Abort()
		return
	}

	err := movieModel.Create(data)
	if err != nil {
		c.JSON(406, gin.H{"message": "Movie could not be created", "error": err.Error()})
		c.Abort()
		return
	}

	c.JSON(200, gin.H{"message": "Movie created"})
}

func (user *UserController) Get(c *gin.Context) {
	id := c.Param("id")
	profile, err := movieModel.Get(id)
	if err != nil {
		c.JSON(404, gin.H{"message": "Movie not found", "error": err.Error()})
		c.Abort()
	} else {
		c.JSON(200, gin.H{"data": profile})
	}
}

func (user *UserController) Find(c *gin.Context) {
	list, err := movieModel.Find()
	if err != nil {
		c.JSON(404, gin.H{"message": "Find Error", "error": err.Error()})
		c.Abort()
	} else {
		c.JSON(200, gin.H{"data": list})
	}
}

func (user *UserController) Update(c *gin.Context) {
	id := c.Param("id")
	data := forms.UpdateMovieCommand{}

	if c.BindJSON(&data) != nil {
		c.JSON(406, gin.H{"message": "Invalid Parameters"})
		c.Abort()
		return
	}
	err := movieModel.Update(id, data)
	if err != nil {
		c.JSON(406, gin.H{"message": "movie count not be updated", "error": err.Error()})
		c.Abort()
		return
	}
	c.JSON(200, gin.H{"message": "Movie updated"})
}

func (user *UserController) Delete(c *gin.Context) {
	id := c.Param("id")
	err := movieModel.Delete(id)
	if err != nil {
		c.JSON(406, gin.H{"message": "Movie could not be deleted", "error": err.Error()})
		c.Abort()
		return
	}
	c.JSON(200, gin.H{"message": "Movie deleted"})
}
<commit_msg>sync latest code<commit_after>package controllers

import (
	"github.com/Luncher/go-rest/forms"
	"github.com/Luncher/go-rest/models"
	"github.com/gin-gonic/gin"
)

var movieModel = new(models.MovieModel)

type UserController struct{}

func (user *UserController) Create(c *gin.Context) {
	var data forms.CreateMovieCommand
	if c.BindJSON(&data) != nil {
		c.JSON(406, gin.H{"message": "Invalid form", "form": data})
		c.Abort()
		return
	}

	err := movieModel.Create(data)
	if err != nil {
		c.JSON(406, gin.H{"message": "Movie could not be created", "error": err.Error()})
		c.Abort()
		return
	}

	c.JSON(200, gin.H{"message": "Movie created"})
}

func (user *UserController) Get(c *gin.Context) {
	id := c.Param("id")
	profile, err := movieModel.Get(id)
	if err != nil {
		c.JSON(404, gin.H{"message": "Movie not found", "error": err.Error()})
		c.Abort()
	} else {
		c.JSON(200, gin.H{"data": profile})
	}
}

func (user *UserController) Find(c *gin.Context) {
	list, err := movieModel.Find()
	if err != nil {
		c.JSON(404, gin.H{"message": "Find Error", "error": err.Error()})
		c.Abort()
	} else {
		c.JSON(200, gin.H{"data": list})
	}
}

func (user *UserController) Update(c *gin.Context) {
	id := c.Param("id")
	data := forms.UpdateMovieCommand{}

	if c.BindJSON(&data) != nil {
		c.JSON(406, gin.H{"message": "Invalid Parameters"})
		c.Abort()
		return
	}
	err := movieModel.Update(id, data)
	if err != nil {
		c.JSON(406, gin.H{"message": "movie count not be updated", "error": err.Error()})
		c.Abort()
		return
	}
	c.JSON(200, gin.H{"message": "Movie updated"})
}

func (user *UserController) Delete(c *gin.Context) {
	id := c.Param("id")
	err := movieModel.Delete(id)
	if err != nil {
		c.JSON(406, gin.H{"message": "Movie could not be deleted", "error": err.Error()})
		c.Abort()
		return
	}
	c.JSON(200, gin.H{"message": "Movie deleted"})
}
<|endoftext|>


<commit_before>// File: ./blockfreight/cmd/bftnode/bftnode.go
// Summary: Application code for Blockfreight™ | The blockchain of global freight.
// License: MIT License
// Company: Blockfreight, Inc.
// Author: Julian Nunez, Neil Tran, Julian Smith, Gian Felipe & contributors
// Site: https://blockfreight.com
// Support: <support@blockfreight.com>

// Copyright © 2017 Blockfreight, Inc. All Rights Reserved.

// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

// =================================================================================================================================================
// =================================================================================================================================================
//
// BBBBBBBBBBBb     lll                                kkk             ffff                         iii                  hhh            ttt
// BBBB``````BBBB   lll                                kkk            fff                           ```                  hhh            ttt
// BBBB      BBBB   lll      oooooo        ccccccc     kkk    kkkk  fffffff  rrr  rrr    eeeee      iii     gggggg ggg   hhh  hhhhh   tttttttt
// BBBBBBBBBBBB     lll    ooo    oooo    ccc    ccc   kkk   kkk    fffffff  rrrrrrrr eee    eeee   iii   gggg   ggggg   hhhh   hhhh  tttttttt
// BBBBBBBBBBBBBB   lll   ooo      ooo   ccc           kkkkkkk        fff    rrrr    eeeeeeeeeeeee  iii  gggg      ggg   hhh     hhh    ttt
// BBBB       BBB   lll   ooo      ooo   ccc           kkkk kkkk      fff    rrr     eeeeeeeeeeeee  iii   ggg      ggg   hhh     hhh    ttt
// BBBB      BBBB   lll   oooo    oooo   cccc    ccc   kkk   kkkk     fff    rrr      eee      eee  iii    ggg    gggg   hhh     hhh    tttt    ....
// BBBBBBBBBBBBB    lll     oooooooo       ccccccc     kkk     kkkk   fff    rrr       eeeeeeeee    iii     gggggg ggg   hhh     hhh     ttttt  ....
//                                                                                ggg      ggg
//   Blockfreight™ | The blockchain of global freight.                                                      ggggggggg
//
// =================================================================================================================================================
// =================================================================================================================================================

// Starts the Blockfreight™ Node to listen to all requests in the Blockfreight Network.
package main

import (
	// =======================
	// Golang Standard library
	// =======================
	// Implements command-line flag parsing.
	"fmt" // Implements formatted I/O with functions analogous to C's printf and scanf.
	"os"

	// ===============
	// Tendermint Core
	// ===============

	tmConfig "github.com/tendermint/tendermint/config"
	tmNode "github.com/tendermint/tendermint/node"
	"github.com/tendermint/tendermint/privval"
	"github.com/tendermint/tendermint/proxy"
	"github.com/tendermint/tmlibs/log"
	// ======================
	// Blockfreight™ packages
	// ======================
	"github.com/blockfreight/go-bftx/api/api"
	"github.com/blockfreight/go-bftx/lib/app/bft"
	// Implements the main functions to work with the Blockfreight™ Network.
)

var homeDir = os.Getenv("HOME")
var logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout))

func BlockfreightAppClientCreator(addr, transport, dbDir string) proxy.ClientCreator {
	return proxy.NewLocalClientCreator(bft.NewBftApplication())
}

func main() {

	fmt.Println("Blockfreight™ Node")

	index := &tmConfig.TxIndexConfig{
		Indexer:      "kv",
		IndexTags:    "bftx.id",
		IndexAllTags: false,
	}

	config := tmConfig.DefaultConfig()

	config.P2P.Seeds = "0ce024c57fc1137bfbee70a1e520fba4c9163fbe@bftx0.blockfreight.net:8888,0537b4c4800b810858dc554e65f85b76217ff900@bftx1.blockfreight.net:8888,5a4833829cc5cec95a6194fb16e3ad75b605968b@bftx2.blockfreight.net:8888,5fe8f8847e4b87c6eea350bcd55269d3c492ffcb@bftx3.blockfreight.net:8888"
	config.Consensus.CreateEmptyBlocks = false

	config.TxIndex = index
	config.DBPath = homeDir + "/.blockfreight/config/bft-db"
	config.Genesis = homeDir + "/.blockfreight/config/genesis.json"
	config.PrivValidator = homeDir + "/.blockfreight/config/priv_validator.json"
	config.NodeKey = homeDir + "/.blockfreight/config/node_key.json"

	logger.Info("Setting up config", "nodeInfo", config)

	node, err := tmNode.NewNode(config,
		privval.LoadOrGenFilePV(config.PrivValidatorFile()),
		BlockfreightAppClientCreator(config.ProxyApp, config.ABCI, config.DBDir()),
		tmNode.DefaultGenesisDocProviderFunc(config),
		tmNode.DefaultDBProvider,
		logger,
	)

	if err != nil {
		fmt.Errorf("Failed to create a node: %v", err)
	}

	if err = node.Start(); err != nil {
		fmt.Errorf("Failed to start node: %v", err)
	}

	logger.Info("Started node", "nodeInfo", node.Switch().NodeInfo())

	err = api.Start()
	if err != nil {
		logger.Error(err.Error())
	}

	// Trap signal, run forever.
	node.RunForever()

}

// =================================================
// Blockfreight™ | The blockchain of global freight.
// =================================================

// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
// BBBBBBB                    BBBBBBBBBBBBBBBBBBB
// BBBBBBB                       BBBBBBBBBBBBBBBB
// BBBBBBB                        BBBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBB        BBBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBB        BBBBBBBBBBBBBBB
// BBBBBBB       BBBBBBB         BBBBBBBBBBBBBBBB
// BBBBBBB                     BBBBBBBBBBBBBBBBBB
// BBBBBBB                        BBBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBBB        BBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBBBB       BBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBBB        BBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBB        BBB       BBBBB
// BBBBBBB                       BBBB       BBBBB
// BBBBBBB                    BBBBBBB       BBBBB
// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB

// ==================================================
// Blockfreight™ | The blockchain for global freight.
// ==================================================
<commit_msg>Added right listening server<commit_after>// File: ./blockfreight/cmd/bftnode/bftnode.go
// Summary: Application code for Blockfreight™ | The blockchain of global freight.
// License: MIT License
// Company: Blockfreight, Inc.
// Author: Julian Nunez, Neil Tran, Julian Smith, Gian Felipe & contributors
// Site: https://blockfreight.com
// Support: <support@blockfreight.com>

// Copyright © 2017 Blockfreight, Inc. All Rights Reserved.

// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

// =================================================================================================================================================
// =================================================================================================================================================
//
// BBBBBBBBBBBb     lll                                kkk             ffff                         iii                  hhh            ttt
// BBBB``````BBBB   lll                                kkk            fff                           ```                  hhh            ttt
// BBBB      BBBB   lll      oooooo        ccccccc     kkk    kkkk  fffffff  rrr  rrr    eeeee      iii     gggggg ggg   hhh  hhhhh   tttttttt
// BBBBBBBBBBBB     lll    ooo    oooo    ccc    ccc   kkk   kkk    fffffff  rrrrrrrr eee    eeee   iii   gggg   ggggg   hhhh   hhhh  tttttttt
// BBBBBBBBBBBBBB   lll   ooo      ooo   ccc           kkkkkkk        fff    rrrr    eeeeeeeeeeeee  iii  gggg      ggg   hhh     hhh    ttt
// BBBB       BBB   lll   ooo      ooo   ccc           kkkk kkkk      fff    rrr     eeeeeeeeeeeee  iii   ggg      ggg   hhh     hhh    ttt
// BBBB      BBBB   lll   oooo    oooo   cccc    ccc   kkk   kkkk     fff    rrr      eee      eee  iii    ggg    gggg   hhh     hhh    tttt    ....
// BBBBBBBBBBBBB    lll     oooooooo       ccccccc     kkk     kkkk   fff    rrr       eeeeeeeee    iii     gggggg ggg   hhh     hhh     ttttt  ....
//                                                                                ggg      ggg
//   Blockfreight™ | The blockchain of global freight.                                                      ggggggggg
//
// =================================================================================================================================================
// =================================================================================================================================================

// Starts the Blockfreight™ Node to listen to all requests in the Blockfreight Network.
package main

import (
	// =======================
	// Golang Standard library
	// =======================
	// Implements command-line flag parsing.
	"fmt" // Implements formatted I/O with functions analogous to C's printf and scanf.
	"os"

	// ===============
	// Tendermint Core
	// ===============

	tmConfig "github.com/tendermint/tendermint/config"
	tmNode "github.com/tendermint/tendermint/node"
	"github.com/tendermint/tendermint/privval"
	"github.com/tendermint/tendermint/proxy"
	"github.com/tendermint/tmlibs/log"
	// ======================
	// Blockfreight™ packages
	// ======================
	"github.com/blockfreight/go-bftx/api/api"
	"github.com/blockfreight/go-bftx/lib/app/bft"
	// Implements the main functions to work with the Blockfreight™ Network.
)

var homeDir = os.Getenv("HOME")
var logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout))

func BlockfreightAppClientCreator(addr, transport, dbDir string) proxy.ClientCreator {
	return proxy.NewLocalClientCreator(bft.NewBftApplication())
}

func main() {

	fmt.Println("Blockfreight™ Node")

	index := &tmConfig.TxIndexConfig{
		Indexer:      "kv",
		IndexTags:    "bftx.id",
		IndexAllTags: false,
	}

	config := tmConfig.DefaultConfig()

	config.P2P.Seeds = "0ce024c57fc1137bfbee70a1e520fba4c9163fbe@bftx0.blockfreight.net:8888,0537b4c4800b810858dc554e65f85b76217ff900@bftx1.blockfreight.net:8888,5a4833829cc5cec95a6194fb16e3ad75b605968b@bftx2.blockfreight.net:8888,5fe8f8847e4b87c6eea350bcd55269d3c492ffcb@bftx3.blockfreight.net:8888"
	config.Consensus.CreateEmptyBlocks = false

	config.TxIndex = index
	config.DBPath = homeDir + "/.blockfreight/config/bft-db"
	config.Genesis = homeDir + "/.blockfreight/config/genesis.json"
	config.PrivValidator = homeDir + "/.blockfreight/config/priv_validator.json"
	config.NodeKey = homeDir + "/.blockfreight/config/node_key.json"
	config.P2P.ListenAddress = "tcp://0.0.0.0:8888"

	logger.Info("Setting up config", "nodeInfo", config)

	node, err := tmNode.NewNode(config,
		privval.LoadOrGenFilePV(config.PrivValidatorFile()),
		BlockfreightAppClientCreator(config.ProxyApp, config.ABCI, config.DBDir()),
		tmNode.DefaultGenesisDocProviderFunc(config),
		tmNode.DefaultDBProvider,
		logger,
	)

	if err != nil {
		fmt.Errorf("Failed to create a node: %v", err)
	}

	if err = node.Start(); err != nil {
		fmt.Errorf("Failed to start node: %v", err)
	}

	logger.Info("Started node", "nodeInfo", node.Switch().NodeInfo())

	err = api.Start()
	if err != nil {
		logger.Error(err.Error())
	}

	// Trap signal, run forever.
	node.RunForever()

}

// =================================================
// Blockfreight™ | The blockchain of global freight.
// =================================================

// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
// BBBBBBB                    BBBBBBBBBBBBBBBBBBB
// BBBBBBB                       BBBBBBBBBBBBBBBB
// BBBBBBB                        BBBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBB        BBBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBB        BBBBBBBBBBBBBBB
// BBBBBBB       BBBBBBB         BBBBBBBBBBBBBBBB
// BBBBBBB                     BBBBBBBBBBBBBBBBBB
// BBBBBBB                        BBBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBBB        BBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBBBB       BBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBBB        BBBBBBBBBBBBBB
// BBBBBBB       BBBBBBBBB        BBB       BBBBB
// BBBBBBB                       BBBB       BBBBB
// BBBBBBB                    BBBBBBB       BBBBB
// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB

// ==================================================
// Blockfreight™ | The blockchain for global freight.
// ==================================================
<|endoftext|>


<commit_before>package control

import (
	"fmt"
	"os"
	"path/filepath"

	"github.com/codegangsta/cli"
	machineUtil "github.com/docker/machine/utils"
)

func tlsConfCommands() []cli.Command {
	return []cli.Command{
		{
			Name:   "create",
			Usage:  "use it to create a new set of tls configuration certs and keys or upload existing ones",
			Action: tlsConfCreate,
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "cakey",
					Usage: "path to existing certificate authority key (only use with --generate)",
				},
				cli.StringFlag{
					Name:  "ca",
					Usage: "path to existing certificate authority (only use with --genreate)",
				},
				cli.BoolFlag{
					Name:  "generate, g",
					Usage: "generate the client key and client cert from existing ca and cakey",
				},
				cli.StringFlag{
					Name:  "outDir, o",
					Usage: "the output directory to save the generated certs or keys",
				},
			},
		},
	}
}

func tlsConfCreate(c *cli.Context) {
	name := "rancher"
	bits := 2048

	caCertPath := "ca.pem"
	caKeyPath := "ca-key.pem"
	outDir := "/etc/docker/tls/"
	generateCaCerts := true

	inputCaKey := ""
	inputCaCert := ""

	if val := c.String("outDir"); val != "" {
		outDir = val
	}

	if c.Bool("generate") {
		generateCaCerts = false
	}

	if val := c.String("cakey"); val != "" {
		inputCaKey = val
	}

	if val := c.String("ca"); val != "" {
		inputCaCert = val
	}

	caCertPath = filepath.Join(outDir, caCertPath)
	caKeyPath = filepath.Join(outDir, caKeyPath)

	serverCertPath := "server-cert.pem"
	serverKeyPath := "server-key.pem"

	if generateCaCerts {
		if err := machineUtil.GenerateCACertificate(caCertPath, caKeyPath, name, bits); err != nil {
			fmt.Println(err.Error())
			return
		}
	} else {
		if inputCaKey == "" || inputCaCert == "" {
			fmt.Println("Please specify caKey and CaCert along with -g")
			return
		}

		if _, err := os.Stat(inputCaKey); err != nil {

			fmt.Printf("ERROR: %s does not exist\n", inputCaKey)
			return
		} else {
			caKeyPath = inputCaKey
		}

		if _, err := os.Stat(inputCaCert); err != nil {
			fmt.Printf("ERROR: %s does not exist\n", inputCaCert)
			return
		} else {
			caCertPath = inputCaCert
		}
		serverCertPath = "client-cert.pem"
		serverKeyPath = "client-key.pem"
	}

	serverCertPath = filepath.Join(outDir, serverCertPath)
	serverKeyPath = filepath.Join(outDir, serverKeyPath)

	if err := machineUtil.GenerateCert([]string{""}, serverCertPath, serverKeyPath, caCertPath, caKeyPath, name, bits); err != nil {
		fmt.Println(err.Error())
		return
	}
}
<commit_msg>Refactor tls command<commit_after>package control

import (
	"io/ioutil"
	"os"
	"path/filepath"

	log "github.com/Sirupsen/logrus"

	"github.com/codegangsta/cli"
	machineUtil "github.com/docker/machine/utils"
	"github.com/rancherio/os/config"
)

const (
	NAME string = "rancher"
	BITS int    = 2048
)

func tlsConfCommands() []cli.Command {
	return []cli.Command{
		{
			Name:   "generate",
			Usage:  "generates new set of TLS configuration certs",
			Action: tlsConfCreate,
			Flags: []cli.Flag{
				cli.StringSliceFlag{
					Name:  "hostname",
					Usage: "the hostname for which you want to generate the certificate",
					Value: &cli.StringSlice{"localhost"},
				},
				cli.BoolFlag{
					Name:  "server, s",
					Usage: "generate the server keys instead of client keys",
				},
				cli.StringFlag{
					Name:  "dir, d",
					Usage: "the directory to save/read the certs to/from",
					Value: "${HOME}/.docker",
				},
			},
		},
	}
}

func writeCerts(generateServer bool, hostname []string, cfg *config.Config, certPath, keyPath, caCertPath, caKeyPath string) error {
	if !generateServer {
		return machineUtil.GenerateCert([]string{""}, certPath, keyPath, caCertPath, caKeyPath, NAME, BITS)
	}

	if cfg.UserDocker.ServerKey == "" || cfg.UserDocker.ServerCert == "" {
		err := machineUtil.GenerateCert(hostname, certPath, keyPath, caCertPath, caKeyPath, NAME, BITS)
		if err != nil {
			return err
		}

		cert, err := ioutil.ReadFile(certPath)
		if err != nil {
			return err
		}

		key, err := ioutil.ReadFile(keyPath)
		if err != nil {
			return err
		}

		return cfg.SetConfig(&config.Config{
			UserDocker: config.DockerConfig{
				CAKey:      cfg.UserDocker.CAKey,
				CACert:     cfg.UserDocker.CACert,
				ServerCert: string(cert),
				ServerKey:  string(key),
			},
		})
	}

	if err := ioutil.WriteFile(certPath, []byte(cfg.UserDocker.ServerCert), 0400); err != nil {
		return err
	}

	return ioutil.WriteFile(keyPath, []byte(cfg.UserDocker.ServerKey), 0400)

}

func writeCaCerts(cfg *config.Config, caCertPath, caKeyPath string) error {
	if cfg.UserDocker.CACert == "" {
		if err := machineUtil.GenerateCACertificate(caCertPath, caKeyPath, NAME, BITS); err != nil {
			return err
		}

		caCert, err := ioutil.ReadFile(caCertPath)
		if err != nil {
			return err
		}

		caKey, err := ioutil.ReadFile(caKeyPath)
		if err != nil {
			return err
		}

		err = cfg.SetConfig(&config.Config{
			UserDocker: config.DockerConfig{
				CAKey:  string(caKey),
				CACert: string(caCert),
			},
		})
		if err != nil {
			return err
		}

		return nil
	}

	if err := ioutil.WriteFile(caCertPath, []byte(cfg.UserDocker.CACert), 0400); err != nil {
		return err
	}

	return ioutil.WriteFile(caKeyPath, []byte(cfg.UserDocker.CAKey), 0400)
}

func tlsConfCreate(c *cli.Context) {
	err := generate(c)
	if err != nil {
		log.Fatal(err)
	}
}

func generate(c *cli.Context) error {
	cfg, err := config.LoadConfig()
	if err != nil {
		return err
	}

	generateServer := c.Bool("server")
	outDir := os.ExpandEnv(c.String("dir"))
	caCertPath := filepath.Join(outDir, "ca.pem")
	caKeyPath := filepath.Join(outDir, "ca-key.pem")
	certPath := filepath.Join(outDir, "cert.pem")
	keyPath := filepath.Join(outDir, "key.pem")

	if generateServer {
		certPath = filepath.Join(outDir, "server-cert.pem")
		keyPath = filepath.Join(outDir, "server-key.pem")
	}

	if _, err := os.Stat(outDir); os.IsNotExist(err) {
		if err := os.MkdirAll(outDir, 0700); err != nil {
			return err
		}
	}

	if err := writeCaCerts(cfg, caCertPath, caKeyPath); err != nil {
		return err
	}

	hostnames := c.StringSlice("hostname")
	return writeCerts(generateServer, hostnames, cfg, certPath, keyPath, caCertPath, caKeyPath)
}
<|endoftext|>


<commit_before>package buf

import (
	"io"
	"net"

	"v2ray.com/core/common"
	"v2ray.com/core/common/errors"
)

type MultiBufferWriter interface {
	WriteMultiBuffer(MultiBuffer) error
}

type MultiBufferReader interface {
	ReadMultiBuffer() (MultiBuffer, error)
}

func ReadAllToMultiBuffer(reader io.Reader) (MultiBuffer, error) {
	mb := NewMultiBuffer()

	for {
		b := New()
		err := b.AppendSupplier(ReadFrom(reader))
		if !b.IsEmpty() {
			mb.Append(b)
		}
		if err != nil {
			if errors.Cause(err) == io.EOF {
				return mb, nil
			}
			mb.Release()
			return nil, err
		}
	}
}

// ReadAllToBytes reads all content from the reader into a byte array, until EOF.
func ReadAllToBytes(reader io.Reader) ([]byte, error) {
	mb, err := ReadAllToMultiBuffer(reader)
	if err != nil {
		return nil, err
	}
	b := make([]byte, mb.Len())
	common.Must2(mb.Read(b))
	mb.Release()
	return b, nil
}

// MultiBuffer is a list of Buffers. The order of Buffer matters.
type MultiBuffer []*Buffer

// NewMultiBuffer creates a new MultiBuffer instance.
func NewMultiBuffer() MultiBuffer {
	return MultiBuffer(make([]*Buffer, 0, 128))
}

// NewMultiBufferValue wraps a list of Buffers into MultiBuffer.
func NewMultiBufferValue(b ...*Buffer) MultiBuffer {
	return MultiBuffer(b)
}

func (mb *MultiBuffer) Append(buf *Buffer) {
	*mb = append(*mb, buf)
}

func (mb *MultiBuffer) AppendMulti(buf MultiBuffer) {
	*mb = append(*mb, buf...)
}

func (mb MultiBuffer) Copy(b []byte) int {
	total := 0
	for _, bb := range mb {
		nBytes := copy(b[total:], bb.Bytes())
		total += nBytes
		if nBytes < bb.Len() {
			break
		}
	}
	return total
}

func (mb *MultiBuffer) Read(b []byte) (int, error) {
	endIndex := len(*mb)
	totalBytes := 0
	for i, bb := range *mb {
		nBytes, _ := bb.Read(b)
		totalBytes += nBytes
		b = b[nBytes:]
		if bb.IsEmpty() {
			bb.Release()
		} else {
			endIndex = i
			break
		}
	}
	*mb = (*mb)[endIndex:]
	return totalBytes, nil
}

func (mb *MultiBuffer) Write(b []byte) {
	n := len(*mb)
	if n > 0 && !(*mb)[n-1].IsFull() {
		nBytes, _ := (*mb)[n-1].Write(b)
		b = b[nBytes:]
	}

	for len(b) > 0 {
		bb := New()
		nBytes, _ := bb.Write(b)
		b = b[nBytes:]
		mb.Append(bb)
	}
}

// Len returns the total number of bytes in the MultiBuffer.
func (mb MultiBuffer) Len() int {
	size := 0
	for _, b := range mb {
		size += b.Len()
	}
	return size
}

// IsEmpty return true if the MultiBuffer has no content.
func (mb MultiBuffer) IsEmpty() bool {
	for _, b := range mb {
		if !b.IsEmpty() {
			return false
		}
	}
	return true
}

// Release releases all Buffers in the MultiBuffer.
func (mb *MultiBuffer) Release() {
	for i, b := range *mb {
		b.Release()
		(*mb)[i] = nil
	}
	*mb = (*mb)[:0]
}

// ToNetBuffers converts this MultiBuffer to net.Buffers. The return net.Buffers points to the same content of the MultiBuffer.
func (mb MultiBuffer) ToNetBuffers() net.Buffers {
	bs := make([][]byte, len(mb))
	for i, b := range mb {
		bs[i] = b.Bytes()
	}
	return bs
}

func (mb *MultiBuffer) SliceBySize(size int) MultiBuffer {
	slice := NewMultiBuffer()
	sliceSize := 0
	endIndex := len(*mb)
	for i, b := range *mb {
		if b.Len()+sliceSize > size {
			endIndex = i
			break
		}
		sliceSize += b.Len()
		slice.Append(b)
		(*mb)[i] = nil
	}
	*mb = (*mb)[endIndex:]
	return slice
}

func (mb *MultiBuffer) SplitFirst() *Buffer {
	if len(*mb) == 0 {
		return nil
	}
	b := (*mb)[0]
	(*mb)[0] = nil
	*mb = (*mb)[1:]
	return b
}
<commit_msg>comments<commit_after>package buf

import (
	"io"
	"net"

	"v2ray.com/core/common"
	"v2ray.com/core/common/errors"
)

// MultiBufferWriter is a writer that writes MultiBuffer.
type MultiBufferWriter interface {
	WriteMultiBuffer(MultiBuffer) error
}

// MultiBufferReader is a reader that reader payload as MultiBuffer.
type MultiBufferReader interface {
	ReadMultiBuffer() (MultiBuffer, error)
}

func ReadAllToMultiBuffer(reader io.Reader) (MultiBuffer, error) {
	mb := NewMultiBuffer()

	for {
		b := New()
		err := b.AppendSupplier(ReadFrom(reader))
		if !b.IsEmpty() {
			mb.Append(b)
		}
		if err != nil {
			if errors.Cause(err) == io.EOF {
				return mb, nil
			}
			mb.Release()
			return nil, err
		}
	}
}

// ReadAllToBytes reads all content from the reader into a byte array, until EOF.
func ReadAllToBytes(reader io.Reader) ([]byte, error) {
	mb, err := ReadAllToMultiBuffer(reader)
	if err != nil {
		return nil, err
	}
	b := make([]byte, mb.Len())
	common.Must2(mb.Read(b))
	mb.Release()
	return b, nil
}

// MultiBuffer is a list of Buffers. The order of Buffer matters.
type MultiBuffer []*Buffer

// NewMultiBuffer creates a new MultiBuffer instance.
func NewMultiBuffer() MultiBuffer {
	return MultiBuffer(make([]*Buffer, 0, 128))
}

// NewMultiBufferValue wraps a list of Buffers into MultiBuffer.
func NewMultiBufferValue(b ...*Buffer) MultiBuffer {
	return MultiBuffer(b)
}

// Append appends buffer to the end of this MultiBuffer
func (mb *MultiBuffer) Append(buf *Buffer) {
	*mb = append(*mb, buf)
}

// AppendMulti appends a MultiBuffer to the end of this one.
func (mb *MultiBuffer) AppendMulti(buf MultiBuffer) {
	*mb = append(*mb, buf...)
}

// Copy copied the begining part of the MultiBuffer into the given byte array.
func (mb MultiBuffer) Copy(b []byte) int {
	total := 0
	for _, bb := range mb {
		nBytes := copy(b[total:], bb.Bytes())
		total += nBytes
		if nBytes < bb.Len() {
			break
		}
	}
	return total
}

// Read implements io.Reader.
func (mb *MultiBuffer) Read(b []byte) (int, error) {
	endIndex := len(*mb)
	totalBytes := 0
	for i, bb := range *mb {
		nBytes, _ := bb.Read(b)
		totalBytes += nBytes
		b = b[nBytes:]
		if bb.IsEmpty() {
			bb.Release()
		} else {
			endIndex = i
			break
		}
	}
	*mb = (*mb)[endIndex:]
	return totalBytes, nil
}

// Write implements io.Writer.
func (mb *MultiBuffer) Write(b []byte) {
	n := len(*mb)
	if n > 0 && !(*mb)[n-1].IsFull() {
		nBytes, _ := (*mb)[n-1].Write(b)
		b = b[nBytes:]
	}

	for len(b) > 0 {
		bb := New()
		nBytes, _ := bb.Write(b)
		b = b[nBytes:]
		mb.Append(bb)
	}
}

// Len returns the total number of bytes in the MultiBuffer.
func (mb MultiBuffer) Len() int {
	size := 0
	for _, b := range mb {
		size += b.Len()
	}
	return size
}

// IsEmpty return true if the MultiBuffer has no content.
func (mb MultiBuffer) IsEmpty() bool {
	for _, b := range mb {
		if !b.IsEmpty() {
			return false
		}
	}
	return true
}

// Release releases all Buffers in the MultiBuffer.
func (mb *MultiBuffer) Release() {
	for i, b := range *mb {
		b.Release()
		(*mb)[i] = nil
	}
	*mb = (*mb)[:0]
}

// ToNetBuffers converts this MultiBuffer to net.Buffers. The return net.Buffers points to the same content of the MultiBuffer.
func (mb MultiBuffer) ToNetBuffers() net.Buffers {
	bs := make([][]byte, len(mb))
	for i, b := range mb {
		bs[i] = b.Bytes()
	}
	return bs
}

func (mb *MultiBuffer) SliceBySize(size int) MultiBuffer {
	slice := NewMultiBuffer()
	sliceSize := 0
	endIndex := len(*mb)
	for i, b := range *mb {
		if b.Len()+sliceSize > size {
			endIndex = i
			break
		}
		sliceSize += b.Len()
		slice.Append(b)
		(*mb)[i] = nil
	}
	*mb = (*mb)[endIndex:]
	return slice
}

func (mb *MultiBuffer) SplitFirst() *Buffer {
	if len(*mb) == 0 {
		return nil
	}
	b := (*mb)[0]
	(*mb)[0] = nil
	*mb = (*mb)[1:]
	return b
}
<|endoftext|>


<commit_before>package resource

import (
	"crypto/rand"
	"encoding/base32"
	"fmt"
	"strings"
)

const UniqueIdPrefix = `terraform-`

// Helper for a resource to generate a unique identifier
//
// This uses a simple RFC 4122 v4 UUID with some basic cosmetic filters
// applied (remove padding, downcase) to help distinguishing visually between
// identifiers.
func UniqueId() string {
	var uuid [16]byte
	rand.Read(uuid[:])
	return fmt.Sprintf("%s%s", UniqueIdPrefix,
		strings.ToLower(
			strings.Replace(
				base32.StdEncoding.EncodeToString(uuid[:]),
				"=", "", -1)))
}
<commit_msg>helper/resource: ok let's actually use RFC4122<commit_after>package resource

import (
	"crypto/rand"
	"encoding/base32"
	"fmt"
	"strings"
)

const UniqueIdPrefix = `terraform-`

// Helper for a resource to generate a unique identifier
//
// This uses a simple RFC 4122 v4 UUID with some basic cosmetic filters
// applied (base32, remove padding, downcase) to make visually distinguishing
// identifiers easier.
func UniqueId() string {
	return fmt.Sprintf("%s%s", UniqueIdPrefix,
		strings.ToLower(
			strings.Replace(
				base32.StdEncoding.EncodeToString(uuidV4()),
				"=", "", -1)))
}

func uuidV4() []byte {
	var uuid [16]byte

	// Set all the other bits to randomly (or pseudo-randomly) chosen
	// values.
	rand.Read(uuid[:])

	// Set the two most significant bits (bits 6 and 7) of the
	// clock_seq_hi_and_reserved to zero and one, respectively.
	uuid[8] = (uuid[8] | 0x80) & 0x8f

	// Set the four most significant bits (bits 12 through 15) of the
	// time_hi_and_version field to the 4-bit version number from Section 4.1.3.
	uuid[6] = (uuid[6] | 0x40) & 0x4f

	return uuid[:]
}
<|endoftext|>


<commit_before>package controllers

import (
	"bytes"
	"github.com/aphistic/gomol"
	"github.com/quakkels/goshipit/images"
	"github.com/quakkels/goshipit/slack"
	"net/http"
	"strconv"
)

func slash(w http.ResponseWriter, req *http.Request) {
	if req.Method == "POST" {
		slashCommand := slack.NewSlashCommandModel(req)
		gomol.Infof("slash command received: %f", slashCommand)

		w.Header().Add("Content Type", "text/plain")

		if slashCommand.Text == "categories" {
			cats := images.Images.GetCategories()
			var catBuffer bytes.Buffer
			for key, count := range cats {
				catBuffer.WriteString(key +
					" has " +
					strconv.Itoa(count) +
					" shipit squirrels.\n")
			}

			catBuffer.WriteTo(w)
		} else if slashCommand.Text == "" {
			image, err := images.Images.Take()
			if err != nil {
				gomol.Err("Failed to .Take() image. " + err.Error())
			}

			incomingWebhook := slack.IncomingWebhook{}
			incomingWebhook.Username = slashCommand.UserName
			incomingWebhook.Channel = slashCommand.ChannelName
			incomingWebhook.Text = slack.GetImageMarkup(image)

			slack.SendIncomingWebhook(incomingWebhook)
		} else {
			b := bytes.NewBufferString("Command not recognized.")
			b.WriteTo(w)
		}
	}
}
<commit_msg>added logging<commit_after>package controllers

import (
	"bytes"
	"github.com/aphistic/gomol"
	"github.com/quakkels/goshipit/images"
	"github.com/quakkels/goshipit/slack"
	"net/http"
	"strconv"
)

func slash(w http.ResponseWriter, req *http.Request) {
	if req.Method == "POST" {
		slashCommand := slack.NewSlashCommandModel(req)
		gomol.Infof("slash command received: %f", slashCommand)

		w.Header().Add("Content Type", "text/plain")

		if slashCommand.Text == "categories" {
			cats := images.Images.GetCategories()
			var catBuffer bytes.Buffer
			for key, count := range cats {
				catBuffer.WriteString(key +
					" has " +
					strconv.Itoa(count) +
					" shipit squirrels.\n")
			}

			catBuffer.WriteTo(w)
		} else if slashCommand.Text == "" {
			image, err := images.Images.Take()
			if err != nil {
				gomol.Err("Failed to .Take() image. " + err.Error())
			}

			incomingWebhook := slack.IncomingWebhook{}
			incomingWebhook.Username = slashCommand.UserName
			incomingWebhook.Channel = slashCommand.ChannelName
			incomingWebhook.Text = slack.GetImageMarkup(image)
			gomol.Info("image: " + image)

			slack.SendIncomingWebhook(incomingWebhook)
		} else {
			b := bytes.NewBufferString("Command not recognized.")
			b.WriteTo(w)
		}
	}
}
<|endoftext|>