<commit_before>package main

import (
	"bytes"
	"code.google.com/p/goprotobuf/proto"
	"encoding/json"
	"fmt"
	"github.com/getgauge/common"
	"io/ioutil"
	"log"
	"net"
	"os"
	"path"
	"path/filepath"
	"strings"
	"time"
)

const (
	reportTemplateDir           = "report-template"
	defaultReportsDir           = "reports"
	gaugeReportsDirEnvName      = "gauge_reports_dir" // directory where reports are generated by plugins
	overwriteReportsEnvProperty = "overwrite_reports"
	SETUP_ACTION                = "setup"
	EXECUTION_ACTION            = "execution"
	GAUGE_HOST                  = "localhost"
	GAUGE_PORT_ENV              = "plugin_connection_port"
	PLUGIN_ACTION_ENV           = "html-report_action"
)

var pluginProperties map[string]interface{}
var pluginInstallationDir string
var projectRoot string

func main() {
	pluginInstallationDir = os.Getenv("plugin_root")
	if pluginInstallationDir == "" {
		fmt.Println("environment variable plugin_root is not set")
		os.Exit(1)
	}
	projectRoot = os.Getenv("project_root")
	if projectRoot == "" {
		fmt.Println("environment variable project_root is not set")
		os.Exit(1)
	}

	pluginPropertiesJson, err := ioutil.ReadFile(filepath.Join(pluginInstallationDir, "plugin.json"))
	if err != nil {
		fmt.Printf("Could not read plugin.json: %s\n", err)
		os.Exit(1)
	}
	var pluginJson interface{}
	if err = json.Unmarshal([]byte(pluginPropertiesJson), &pluginJson); err != nil {
		fmt.Printf("Could not read plugin.json: %s\n", err)
		os.Exit(1)
	}
	pluginProperties = pluginJson.(map[string]interface{})

	action := os.Getenv(PLUGIN_ACTION_ENV)
	if action == SETUP_ACTION {
		addDefaultPropertiesToProject()
	} else if action == EXECUTION_ACTION {
		listener, err := NewGaugeListener(GAUGE_HOST, os.Getenv(GAUGE_PORT_ENV))
		if err != nil {
			fmt.Println("Could not create the gauge listener")
			os.Exit(1)
		}
		listener.OnSuiteResult(createReport)
		listener.Start()
	}
}

func addDefaultPropertiesToProject() {
	defaultPropertiesFile, err := common.GetDefaultPropertiesFile()
	reportsDirProperty := &(common.Property{
		Comment:      "The path to the gauge reports directory. Should be either relative to the project directory or an absolute path",
		Name:         gaugeReportsDirEnvName,
		DefaultValue: defaultReportsDir})
	overwriteReportProperty := &(common.Property{
		Comment:      "Set as false if gauge reports should not be overwritten on each execution. A new time-stamped directory will be created on each execution.",
		Name:         overwriteReportsEnvProperty,
		DefaultValue: "true"})

	if err != nil {
		fmt.Printf("Failed to setup html report plugin in project: %s", err)
	}
	if err := common.AppendProperties(defaultPropertiesFile, reportsDirProperty, overwriteReportProperty); err != nil {
		fmt.Printf("Failed to setup html report plugin in project: %s", err)
	}
	fmt.Println("Succesfully added configurations for html-report to env/default/default.properties")
}

type GaugeResultHandlerFn func(*SuiteExecutionResult)

type GaugeListener struct {
	connection      net.Conn
	onResultHandler GaugeResultHandlerFn
}

func NewGaugeListener(host string, port string) (*GaugeListener, error) {
	conn, err := net.Dial("tcp", fmt.Sprintf("%s:%s", host, port))
	if err == nil {
		return &GaugeListener{connection: conn}, nil
	} else {
		return nil, err
	}
}

func (gaugeListener *GaugeListener) OnSuiteResult(resultHandler GaugeResultHandlerFn) {
	gaugeListener.onResultHandler = resultHandler
}

func (gaugeListener *GaugeListener) Start() {
	buffer := new(bytes.Buffer)
	data := make([]byte, 8192)
	for {
		n, err := gaugeListener.connection.Read(data)
		if err != nil {
			return
		}
		buffer.Write(data[0:n])
		gaugeListener.processMessages(buffer)
	}
}

func (gaugeListener *GaugeListener) processMessages(buffer *bytes.Buffer) {
	for {
		messageLength, bytesRead := proto.DecodeVarint(buffer.Bytes())
		if messageLength > 0 && messageLength < uint64(buffer.Len()) {
			message := &Message{}
			messageBoundary := int(messageLength) + bytesRead
			err := proto.Unmarshal(buffer.Bytes()[bytesRead:messageBoundary], message)
			if err != nil {
				log.Printf("Failed to read proto message: %s\n", err.Error())
			} else {
				if *message.MessageType == Message_SuiteExecutionResult {
					result := message.GetSuiteExecutionResult()
					gaugeListener.onResultHandler(result)
					gaugeListener.connection.Close()
				}
				buffer.Next(messageBoundary)
				if buffer.Len() == 0 {
					return
				}
			}
		} else {
			return
		}
	}
}

func createReport(suiteResult *SuiteExecutionResult) {
	contents := generateJsFileContents(suiteResult)
	reportsDir, err := filepath.Abs(os.Getenv(gaugeReportsDirEnvName))
	if reportsDir == "" || err != nil {
		createDirectory(defaultReportsDir)
		reportsDir = defaultReportsDir
	} else {
		createDirectory(reportsDir)
	}

	var currentReportDir string
	if shouldOverwriteReports() {
		currentReportDir = path.Join(reportsDir, "html-report")
	} else {
		currentReportDir = path.Join(reportsDir, "html-report", time.Now().Format("2006-01-02 15:04:05"))
	}
	createDirectory(currentReportDir)
	copyReportTemplateFiles(currentReportDir)

	resultJsPath := path.Join(currentReportDir, "js", "result.js")
	err = ioutil.WriteFile(resultJsPath, contents, common.NewFilePermissions)
	if err != nil {
		fmt.Printf("Error writing file %s :%s\n", resultJsPath, err)
	}
	fmt.Printf("Sucessfully generated html reports to => %s\n", currentReportDir)
}

func copyReportTemplateFiles(reportDir string) {
	pluginsDir, err := common.GetPluginsInstallDir()
	if err != nil {
		fmt.Printf("Error finding plugins directory :%s\n", err)
		os.Exit(1)
	}
	reportTemplateDir := path.Join(pluginsDir, pluginProperties["id"].(string), pluginProperties["version"].(string), reportTemplateDir)
	err = common.MirrorDir(reportTemplateDir, reportDir)
	if err != nil {
		fmt.Printf("Error copying template directory :%s\n", err)
		os.Exit(1)
	}

}

func shouldOverwriteReports() bool {
	envValue := os.Getenv(overwriteReportsEnvProperty)
	if strings.ToLower(envValue) == "true" {
		return true
	}
	return false
}

func generateJsFileContents(suiteResult *SuiteExecutionResult) []byte {
	var buffer bytes.Buffer
	executionResultJson := marshal(suiteResult)
	itemsTypeJson := marshal(convertKeysToString(ProtoItem_ItemType_name))
	parameterTypeJson := marshal(convertKeysToString(Parameter_ParameterType_name))
	fragmentTypeJson := marshal(convertKeysToString(Fragment_FragmentType_name))

	buffer.WriteString("var gaugeExecutionResult = ")
	buffer.Write(executionResultJson)
	buffer.WriteString(";")
	buffer.WriteString("\n var itemTypesMap = ")
	buffer.Write(itemsTypeJson)
	buffer.WriteString(";")
	buffer.WriteString("\n var parameterTypesMap = ")
	buffer.Write(parameterTypeJson)
	buffer.WriteString(";")
	buffer.WriteString("\n var fragmentTypesMap = ")
	buffer.Write(fragmentTypeJson)
	buffer.WriteString(";")

	return buffer.Bytes()
}

func convertKeysToString(intKeyMap map[int32]string) map[string]string {
	stringKeyMap := make(map[string]string, 0)
	for key, val := range intKeyMap {
		stringKeyMap[fmt.Sprintf("%d", key)] = val
	}
	return stringKeyMap
}

func marshal(item interface{}) []byte {
	marshalledResult, err := json.Marshal(item)
	if err != nil {
		fmt.Printf("Failed to convert to json :%s\n", err)
		os.Exit(1)
	}
	return marshalledResult
}

func createDirectory(dir string) {
	if common.DirExists(dir) {
		return
	}
	if err := os.MkdirAll(dir, common.NewDirectoryPermissions); err != nil {
		fmt.Printf("Failed to create directory %s: %s\n", defaultReportsDir, err)
		os.Exit(1)
	}
}
<commit_msg>Modifying html plugin with changes for working directory set to plugin install directory<commit_after>package main

import (
	"bytes"
	"code.google.com/p/goprotobuf/proto"
	"encoding/json"
	"fmt"
	"github.com/getgauge/common"
	"io/ioutil"
	"log"
	"net"
	"os"
	"path"
	"path/filepath"
	"strings"
	"time"
)

const (
	reportTemplateDir           = "report-template"
	defaultReportsDir           = "reports"
	gaugeReportsDirEnvName      = "gauge_reports_dir" // directory where reports are generated by plugins
	overwriteReportsEnvProperty = "overwrite_reports"
	SETUP_ACTION                = "setup"
	EXECUTION_ACTION            = "execution"
	GAUGE_HOST                  = "localhost"
	GAUGE_PORT_ENV              = "plugin_connection_port"
	PLUGIN_ACTION_ENV           = "html-report_action"
)

var pluginProperties map[string]interface{}
var projectRoot string
var pluginDir string

func main() {
	projectRoot = os.Getenv(common.GaugeProjectRootEnv)
	if projectRoot == "" {
		fmt.Printf("Environment variable '%s' is not set. \n", common.GaugeProjectRootEnv)
		os.Exit(1)
	}

	var err error
	pluginDir, err = os.Getwd()
	if err != nil {
		fmt.Printf("Error finding current working directory: %s \n", err)
		os.Exit(1)
	}

	pluginPropertiesJson, readErr := ioutil.ReadFile("plugin.json")
	if readErr != nil {
		fmt.Printf("Could not read plugin.json: %s\n", readErr)
		os.Exit(1)
	}

	var pluginJson interface{}
	if err = json.Unmarshal([]byte(pluginPropertiesJson), &pluginJson); err != nil {
		fmt.Printf("Could not read plugin.json: %s\n", err)
		os.Exit(1)
	}
	pluginProperties = pluginJson.(map[string]interface{})

	action := os.Getenv(PLUGIN_ACTION_ENV)
	if action == SETUP_ACTION {
		addDefaultPropertiesToProject()
	} else if action == EXECUTION_ACTION {
		listener, err := NewGaugeListener(GAUGE_HOST, os.Getenv(GAUGE_PORT_ENV))
		if err != nil {
			fmt.Println("Could not create the gauge listener")
			os.Exit(1)
		}
		listener.OnSuiteResult(createReport)
		listener.Start()
	}
}

func addDefaultPropertiesToProject() {
	defaultPropertiesFile := getDefaultPropertiesFile()
	reportsDirProperty := &(common.Property{
		Comment:      "The path to the gauge reports directory. Should be either relative to the project directory or an absolute path",
		Name:         gaugeReportsDirEnvName,
		DefaultValue: defaultReportsDir})
	overwriteReportProperty := &(common.Property{
		Comment:      "Set as false if gauge reports should not be overwritten on each execution. A new time-stamped directory will be created on each execution.",
		Name:         overwriteReportsEnvProperty,
		DefaultValue: "true"})

	if !common.FileExists(defaultPropertiesFile) {
		fmt.Printf("Failed to setup html report plugin in project. Default properties file does not exist at %s. \n", defaultPropertiesFile)
		return
	}
	if err := common.AppendProperties(defaultPropertiesFile, reportsDirProperty, overwriteReportProperty); err != nil {
		fmt.Printf("Failed to setup html report plugin in project: %s \n", err)
		return
	}
	fmt.Println("Succesfully added configurations for html-report to env/default/default.properties")
}

func getDefaultPropertiesFile() string {
	return filepath.Join(projectRoot, "env", "default", "default.properties")
}

type GaugeResultHandlerFn func(*SuiteExecutionResult)

type GaugeListener struct {
	connection      net.Conn
	onResultHandler GaugeResultHandlerFn
}

func NewGaugeListener(host string, port string) (*GaugeListener, error) {
	conn, err := net.Dial("tcp", fmt.Sprintf("%s:%s", host, port))
	if err == nil {
		return &GaugeListener{connection: conn}, nil
	} else {
		return nil, err
	}
}

func (gaugeListener *GaugeListener) OnSuiteResult(resultHandler GaugeResultHandlerFn) {
	gaugeListener.onResultHandler = resultHandler
}

func (gaugeListener *GaugeListener) Start() {
	buffer := new(bytes.Buffer)
	data := make([]byte, 8192)
	for {
		n, err := gaugeListener.connection.Read(data)
		if err != nil {
			return
		}
		buffer.Write(data[0:n])
		gaugeListener.processMessages(buffer)
	}
}

func (gaugeListener *GaugeListener) processMessages(buffer *bytes.Buffer) {
	for {
		messageLength, bytesRead := proto.DecodeVarint(buffer.Bytes())
		if messageLength > 0 && messageLength < uint64(buffer.Len()) {
			message := &Message{}
			messageBoundary := int(messageLength) + bytesRead
			err := proto.Unmarshal(buffer.Bytes()[bytesRead:messageBoundary], message)
			if err != nil {
				log.Printf("Failed to read proto message: %s\n", err.Error())
			} else {
				if *message.MessageType == Message_SuiteExecutionResult {
					result := message.GetSuiteExecutionResult()
					gaugeListener.onResultHandler(result)
					gaugeListener.connection.Close()
				}
				buffer.Next(messageBoundary)
				if buffer.Len() == 0 {
					return
				}
			}
		} else {
			return
		}
	}
}

func createReport(suiteResult *SuiteExecutionResult) {
	os.Chdir(projectRoot)
	contents := generateJsFileContents(suiteResult)
	reportsDir, err := filepath.Abs(os.Getenv(gaugeReportsDirEnvName))
	if reportsDir == "" || err != nil {
		createDirectory(defaultReportsDir)
		reportsDir = defaultReportsDir
	} else {
		createDirectory(reportsDir)
	}

	var currentReportDir string
	if shouldOverwriteReports() {
		currentReportDir = path.Join(reportsDir, "html-report")
	} else {
		currentReportDir = path.Join(reportsDir, "html-report", time.Now().Format("2006-01-02 15:04:05"))
	}
	createDirectory(currentReportDir)
	copyReportTemplateFiles(currentReportDir)

	resultJsPath := path.Join(currentReportDir, "js", "result.js")
	err = ioutil.WriteFile(resultJsPath, contents, common.NewFilePermissions)
	if err != nil {
		fmt.Printf("Error writing file %s :%s\n", resultJsPath, err)
	}
	fmt.Printf("Sucessfully generated html reports to => %s\n", currentReportDir)
}

func copyReportTemplateFiles(reportDir string) {
	reportTemplateDir := path.Join(pluginDir, reportTemplateDir)
	err := common.MirrorDir(reportTemplateDir, reportDir)
	if err != nil {
		fmt.Printf("Error copying template directory :%s\n", err)
		os.Exit(1)
	}
}

func shouldOverwriteReports() bool {
	envValue := os.Getenv(overwriteReportsEnvProperty)
	if strings.ToLower(envValue) == "true" {
		return true
	}
	return false
}

func generateJsFileContents(suiteResult *SuiteExecutionResult) []byte {
	var buffer bytes.Buffer
	executionResultJson := marshal(suiteResult)
	itemsTypeJson := marshal(convertKeysToString(ProtoItem_ItemType_name))
	parameterTypeJson := marshal(convertKeysToString(Parameter_ParameterType_name))
	fragmentTypeJson := marshal(convertKeysToString(Fragment_FragmentType_name))

	buffer.WriteString("var gaugeExecutionResult = ")
	buffer.Write(executionResultJson)
	buffer.WriteString(";")
	buffer.WriteString("\n var itemTypesMap = ")
	buffer.Write(itemsTypeJson)
	buffer.WriteString(";")
	buffer.WriteString("\n var parameterTypesMap = ")
	buffer.Write(parameterTypeJson)
	buffer.WriteString(";")
	buffer.WriteString("\n var fragmentTypesMap = ")
	buffer.Write(fragmentTypeJson)
	buffer.WriteString(";")

	return buffer.Bytes()
}

func convertKeysToString(intKeyMap map[int32]string) map[string]string {
	stringKeyMap := make(map[string]string, 0)
	for key, val := range intKeyMap {
		stringKeyMap[fmt.Sprintf("%d", key)] = val
	}
	return stringKeyMap
}

func marshal(item interface{}) []byte {
	marshalledResult, err := json.Marshal(item)
	if err != nil {
		fmt.Printf("Failed to convert to json :%s\n", err)
		os.Exit(1)
	}
	return marshalledResult
}

func createDirectory(dir string) {
	if common.DirExists(dir) {
		return
	}
	if err := os.MkdirAll(dir, common.NewDirectoryPermissions); err != nil {
		fmt.Printf("Failed to create directory %s: %s\n", defaultReportsDir, err)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package apparmor

import (
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"os"

	"github.com/opencontainers/runc/libcontainer/utils"
)

// IsEnabled returns true if apparmor is enabled for the host.
func IsEnabled() bool {
	if _, err := os.Stat("/sys/kernel/security/apparmor"); err == nil {
		buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled")
		return err == nil && bytes.HasPrefix(buf, []byte("Y"))
	}
	return false
}

func setProcAttr(attr, value string) error {
	// Under AppArmor you can only change your own attr, so use /proc/self/
	// instead of /proc/<tid>/ like libapparmor does
	attrPath := "/proc/self/attr/apparmor/" + attr
	if _, err := os.Stat(attrPath); errors.Is(err, os.ErrNotExist) {
		// fall back to the old convention
		attrPath = "/proc/self/attr/" + attr
	}

	f, err := os.OpenFile(attrPath, os.O_WRONLY, 0)
	if err != nil {
		return err
	}
	defer f.Close()

	if err := utils.EnsureProcHandle(f); err != nil {
		return err
	}

	_, err = f.WriteString(value)
	return err
}

// changeOnExec reimplements aa_change_onexec from libapparmor in Go
func changeOnExec(name string) error {
	if err := setProcAttr("exec", "exec "+name); err != nil {
		return fmt.Errorf("apparmor failed to apply profile: %s", err)
	}
	return nil
}

// ApplyProfile will apply the profile with the specified name to the process after
// the next exec.
func ApplyProfile(name string) error {
	if name == "" {
		return nil
	}

	return changeOnExec(name)
}
<commit_msg>libcontainer/apparmor: use sync.Once for AppArmor detection<commit_after>package apparmor

import (
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"sync"

	"github.com/opencontainers/runc/libcontainer/utils"
)

var (
	appArmorEnabled bool
	checkAppArmor   sync.Once
)

// IsEnabled returns true if apparmor is enabled for the host.
func IsEnabled() bool {
	checkAppArmor.Do(func() {
		if _, err := os.Stat("/sys/kernel/security/apparmor"); err == nil {
			buf, err := ioutil.ReadFile("/sys/module/apparmor/parameters/enabled")
			appArmorEnabled = err == nil && len(buf) > 1 && buf[0] == 'Y'
		}
	})
	return appArmorEnabled
}

func setProcAttr(attr, value string) error {
	// Under AppArmor you can only change your own attr, so use /proc/self/
	// instead of /proc/<tid>/ like libapparmor does
	attrPath := "/proc/self/attr/apparmor/" + attr
	if _, err := os.Stat(attrPath); errors.Is(err, os.ErrNotExist) {
		// fall back to the old convention
		attrPath = "/proc/self/attr/" + attr
	}

	f, err := os.OpenFile(attrPath, os.O_WRONLY, 0)
	if err != nil {
		return err
	}
	defer f.Close()

	if err := utils.EnsureProcHandle(f); err != nil {
		return err
	}

	_, err = f.WriteString(value)
	return err
}

// changeOnExec reimplements aa_change_onexec from libapparmor in Go
func changeOnExec(name string) error {
	if err := setProcAttr("exec", "exec "+name); err != nil {
		return fmt.Errorf("apparmor failed to apply profile: %s", err)
	}
	return nil
}

// ApplyProfile will apply the profile with the specified name to the process after
// the next exec.
func ApplyProfile(name string) error {
	if name == "" {
		return nil
	}

	return changeOnExec(name)
}
<|endoftext|>


<commit_before>package kontainerdrivermetadata

import (
	"fmt"
	"strings"

	mVersion "github.com/mcuadros/go-version"
	"github.com/rancher/rancher/pkg/namespace"
	"github.com/rancher/rancher/pkg/settings"
	"github.com/rancher/rke/util"
	v3 "github.com/rancher/types/apis/management.cattle.io/v3"
	"github.com/sirupsen/logrus"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func GetCisConfigParams(
	name string,
	cisConfigLister v3.CisConfigLister,
	cisConfig v3.CisConfigInterface,
) (v3.CisConfigParams, error) {
	c, err := cisConfigLister.Get(namespace.GlobalNamespace, name)
	if err != nil {
		if !errors.IsNotFound(err) {
			return v3.CisConfigParams{}, err
		}
		c, err = cisConfig.GetNamespaced(namespace.GlobalNamespace, name, metav1.GetOptions{})
		if err != nil {
			return v3.CisConfigParams{}, err
		}
	}
	return c.Params, nil
}

func GetRKESystemImages(k8sVersion string, sysImageLister v3.RKEK8sSystemImageLister, sysImages v3.RKEK8sSystemImageInterface) (v3.RKESystemImages, error) {
	name := k8sVersion
	sysImage, err := sysImageLister.Get(namespace.GlobalNamespace, name)
	if err != nil {
		if !errors.IsNotFound(err) {
			return v3.RKESystemImages{}, err
		}
		sysImage, err = sysImages.GetNamespaced(namespace.GlobalNamespace, name, metav1.GetOptions{})
		if err != nil {
			return v3.RKESystemImages{}, err
		}
	}
	return sysImage.SystemImages, err
}

func GetRKEAddonTemplate(addonName string, addonLister v3.RKEAddonLister, addons v3.RKEAddonInterface) (string, error) {
	addon, err := addonLister.Get(namespace.GlobalNamespace, addonName)
	if err != nil {
		if !errors.IsNotFound(err) {
			return "", err
		}
		addon, err = addons.GetNamespaced(namespace.GlobalNamespace, addonName, metav1.GetOptions{})
		if err != nil {
			return "", err
		}
	}
	if addon.Labels[sendRKELabel] == "false" {
		return "", nil
	}
	return addon.Template, err
}

func getRKEServiceOption(name string, svcOptionLister v3.RKEK8sServiceOptionLister, svcOptions v3.RKEK8sServiceOptionInterface) (*v3.KubernetesServicesOptions, error) {
	var k8sSvcOption *v3.KubernetesServicesOptions
	svcOption, err := svcOptionLister.Get(namespace.GlobalNamespace, name)
	if err != nil {
		if !errors.IsNotFound(err) {
			return k8sSvcOption, err
		}
		svcOption, err = svcOptions.GetNamespaced(namespace.GlobalNamespace, name, metav1.GetOptions{})
		if err != nil {
			if !errors.IsNotFound(err) {
				return k8sSvcOption, err
			}
		}
	}
	if svcOption.Labels[sendRKELabel] == "false" {
		return k8sSvcOption, nil
	}
	logrus.Debugf("getRKEServiceOption: sending svcOption %s", name)
	return &svcOption.ServiceOptions, nil
}

func GetRKEK8sServiceOptions(k8sVersion string, svcOptionLister v3.RKEK8sServiceOptionLister,
	svcOptions v3.RKEK8sServiceOptionInterface, sysImageLister v3.RKEK8sSystemImageLister,
	sysImages v3.RKEK8sSystemImageInterface, osType OSType) (*v3.KubernetesServicesOptions, error) {

	var k8sSvcOption *v3.KubernetesServicesOptions
	sysImage, err := sysImageLister.Get(namespace.GlobalNamespace, k8sVersion)
	if err != nil {
		if !errors.IsNotFound(err) {
			logrus.Errorf("getSvcOptions: error finding system image for %s %v", k8sVersion, err)
			return k8sSvcOption, err
		}
		sysImage, err = sysImages.GetNamespaced(namespace.GlobalNamespace, k8sVersion, metav1.GetOptions{})
		if err != nil {
			logrus.Errorf("getSvcOptions: error finding system image for %s %v", k8sVersion, err)
			return k8sSvcOption, err
		}
	}
	key := svcOptionLinuxKey
	if osType == Windows {
		key = svcOptionWindowsKey
	}
	val, ok := sysImage.Labels[key]
	// It's possible that we have a k8s version with no windows svcOptions. In this case, we just warn and return nil.
	// if we have in fact windows nodes trying to use that version, the error will show in reknodeconfig server.
	if !ok && osType == Windows {
		logrus.Debugf("getSvcOptions: no service-option key present for %s", k8sVersion)
		return k8sSvcOption, nil
	} else if !ok {
		return k8sSvcOption, fmt.Errorf("getSvcOptions: no service-option key present for %s", k8sVersion)
	}
	return getRKEServiceOption(val, svcOptionLister, svcOptions)
}

func GetK8sVersionInfo(
	rancherVersion string,
	rkeSysImages map[string]v3.RKESystemImages,
	linuxSvcOptions map[string]v3.KubernetesServicesOptions,
	windowsSvcOptions map[string]v3.KubernetesServicesOptions,
	rancherVersions map[string]v3.K8sVersionInfo,
) (linuxInfo, windowsInfo *VersionInfo) {

	linuxInfo = newVersionInfo()
	windowsInfo = newVersionInfo()

	maxVersionForMajorK8sVersion := map[string]string{}
	for k8sVersion := range rkeSysImages {
		if rancherVersionInfo, ok := rancherVersions[k8sVersion]; ok && toIgnoreForAllK8s(rancherVersionInfo, rancherVersion) {
			continue
		}
		majorVersion := util.GetTagMajorVersion(k8sVersion)
		if majorVersionInfo, ok := rancherVersions[majorVersion]; ok && toIgnoreForK8sCurrent(majorVersionInfo, rancherVersion) {
			continue
		}
		if curr, ok := maxVersionForMajorK8sVersion[majorVersion]; !ok || mVersion.Compare(k8sVersion, curr, ">") {
			maxVersionForMajorK8sVersion[majorVersion] = k8sVersion
		}
	}
	for majorVersion, k8sVersion := range maxVersionForMajorK8sVersion {
		sysImgs, exist := rkeSysImages[k8sVersion]
		if !exist {
			continue
		}
		// windows has been supported since v1.14,
		// the following logic would not find `< v1.14` service options
		if svcOptions, exist := windowsSvcOptions[majorVersion]; exist {
			// only keep the related images for windows
			windowsSysImgs := v3.RKESystemImages{
				NginxProxy:                sysImgs.NginxProxy,
				CertDownloader:            sysImgs.CertDownloader,
				KubernetesServicesSidecar: sysImgs.KubernetesServicesSidecar,
				Kubernetes:                sysImgs.Kubernetes,
				WindowsPodInfraContainer:  sysImgs.WindowsPodInfraContainer,
			}

			windowsInfo.RKESystemImages[k8sVersion] = windowsSysImgs
			windowsInfo.KubernetesServicesOptions[k8sVersion] = svcOptions
		}
		if svcOptions, exist := linuxSvcOptions[majorVersion]; exist {
			// clean the unrelated images for linux
			sysImgs.WindowsPodInfraContainer = ""

			linuxInfo.RKESystemImages[k8sVersion] = sysImgs
			linuxInfo.KubernetesServicesOptions[k8sVersion] = svcOptions
		}
	}

	return linuxInfo, windowsInfo
}

type VersionInfo struct {
	RKESystemImages           map[string]v3.RKESystemImages
	KubernetesServicesOptions map[string]v3.KubernetesServicesOptions
}

func newVersionInfo() *VersionInfo {
	return &VersionInfo{
		RKESystemImages:           map[string]v3.RKESystemImages{},
		KubernetesServicesOptions: map[string]v3.KubernetesServicesOptions{},
	}
}

func GetRancherVersion() string {
	rancherVersion := settings.ServerVersion.Get()
	if strings.HasPrefix(rancherVersion, "dev") || strings.HasPrefix(rancherVersion, "master") {
		return RancherVersionDev
	}
	if strings.HasPrefix(rancherVersion, "v") {
		return rancherVersion[1:]
	}
	return rancherVersion
}
<commit_msg>return error if service option not found<commit_after>package kontainerdrivermetadata

import (
	"fmt"
	"strings"

	mVersion "github.com/mcuadros/go-version"
	"github.com/rancher/rancher/pkg/namespace"
	"github.com/rancher/rancher/pkg/settings"
	"github.com/rancher/rke/util"
	v3 "github.com/rancher/types/apis/management.cattle.io/v3"
	"github.com/sirupsen/logrus"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func GetCisConfigParams(
	name string,
	cisConfigLister v3.CisConfigLister,
	cisConfig v3.CisConfigInterface,
) (v3.CisConfigParams, error) {
	c, err := cisConfigLister.Get(namespace.GlobalNamespace, name)
	if err != nil {
		if !errors.IsNotFound(err) {
			return v3.CisConfigParams{}, err
		}
		c, err = cisConfig.GetNamespaced(namespace.GlobalNamespace, name, metav1.GetOptions{})
		if err != nil {
			return v3.CisConfigParams{}, err
		}
	}
	return c.Params, nil
}

func GetRKESystemImages(k8sVersion string, sysImageLister v3.RKEK8sSystemImageLister, sysImages v3.RKEK8sSystemImageInterface) (v3.RKESystemImages, error) {
	name := k8sVersion
	sysImage, err := sysImageLister.Get(namespace.GlobalNamespace, name)
	if err != nil {
		if !errors.IsNotFound(err) {
			return v3.RKESystemImages{}, err
		}
		sysImage, err = sysImages.GetNamespaced(namespace.GlobalNamespace, name, metav1.GetOptions{})
		if err != nil {
			return v3.RKESystemImages{}, err
		}
	}
	return sysImage.SystemImages, err
}

func GetRKEAddonTemplate(addonName string, addonLister v3.RKEAddonLister, addons v3.RKEAddonInterface) (string, error) {
	addon, err := addonLister.Get(namespace.GlobalNamespace, addonName)
	if err != nil {
		if !errors.IsNotFound(err) {
			return "", err
		}
		addon, err = addons.GetNamespaced(namespace.GlobalNamespace, addonName, metav1.GetOptions{})
		if err != nil {
			return "", err
		}
	}
	if addon.Labels[sendRKELabel] == "false" {
		return "", nil
	}
	return addon.Template, err
}

func getRKEServiceOption(name string, svcOptionLister v3.RKEK8sServiceOptionLister, svcOptions v3.RKEK8sServiceOptionInterface) (*v3.KubernetesServicesOptions, error) {
	var k8sSvcOption *v3.KubernetesServicesOptions
	svcOption, err := svcOptionLister.Get(namespace.GlobalNamespace, name)
	if err != nil {
		if !errors.IsNotFound(err) {
			return k8sSvcOption, err
		}
		svcOption, err = svcOptions.GetNamespaced(namespace.GlobalNamespace, name, metav1.GetOptions{})
		if err != nil {
			return k8sSvcOption, err
		}
	}
	if svcOption.Labels[sendRKELabel] == "false" {
		return k8sSvcOption, nil
	}
	logrus.Debugf("getRKEServiceOption: sending svcOption %s", name)
	return &svcOption.ServiceOptions, nil
}

func GetRKEK8sServiceOptions(k8sVersion string, svcOptionLister v3.RKEK8sServiceOptionLister,
	svcOptions v3.RKEK8sServiceOptionInterface, sysImageLister v3.RKEK8sSystemImageLister,
	sysImages v3.RKEK8sSystemImageInterface, osType OSType) (*v3.KubernetesServicesOptions, error) {

	var k8sSvcOption *v3.KubernetesServicesOptions
	sysImage, err := sysImageLister.Get(namespace.GlobalNamespace, k8sVersion)
	if err != nil {
		if !errors.IsNotFound(err) {
			logrus.Errorf("getSvcOptions: error finding system image for %s %v", k8sVersion, err)
			return k8sSvcOption, err
		}
		sysImage, err = sysImages.GetNamespaced(namespace.GlobalNamespace, k8sVersion, metav1.GetOptions{})
		if err != nil {
			logrus.Errorf("getSvcOptions: error finding system image for %s %v", k8sVersion, err)
			return k8sSvcOption, err
		}
	}
	key := svcOptionLinuxKey
	if osType == Windows {
		key = svcOptionWindowsKey
	}
	val, ok := sysImage.Labels[key]
	// It's possible that we have a k8s version with no windows svcOptions. In this case, we just warn and return nil.
	// if we have in fact windows nodes trying to use that version, the error will show in reknodeconfig server.
	if !ok && osType == Windows {
		logrus.Debugf("getSvcOptions: no service-option key present for %s", k8sVersion)
		return k8sSvcOption, nil
	} else if !ok {
		return k8sSvcOption, fmt.Errorf("getSvcOptions: no service-option key present for %s", k8sVersion)
	}
	return getRKEServiceOption(val, svcOptionLister, svcOptions)
}

func GetK8sVersionInfo(
	rancherVersion string,
	rkeSysImages map[string]v3.RKESystemImages,
	linuxSvcOptions map[string]v3.KubernetesServicesOptions,
	windowsSvcOptions map[string]v3.KubernetesServicesOptions,
	rancherVersions map[string]v3.K8sVersionInfo,
) (linuxInfo, windowsInfo *VersionInfo) {

	linuxInfo = newVersionInfo()
	windowsInfo = newVersionInfo()

	maxVersionForMajorK8sVersion := map[string]string{}
	for k8sVersion := range rkeSysImages {
		if rancherVersionInfo, ok := rancherVersions[k8sVersion]; ok && toIgnoreForAllK8s(rancherVersionInfo, rancherVersion) {
			continue
		}
		majorVersion := util.GetTagMajorVersion(k8sVersion)
		if majorVersionInfo, ok := rancherVersions[majorVersion]; ok && toIgnoreForK8sCurrent(majorVersionInfo, rancherVersion) {
			continue
		}
		if curr, ok := maxVersionForMajorK8sVersion[majorVersion]; !ok || mVersion.Compare(k8sVersion, curr, ">") {
			maxVersionForMajorK8sVersion[majorVersion] = k8sVersion
		}
	}
	for majorVersion, k8sVersion := range maxVersionForMajorK8sVersion {
		sysImgs, exist := rkeSysImages[k8sVersion]
		if !exist {
			continue
		}
		// windows has been supported since v1.14,
		// the following logic would not find `< v1.14` service options
		if svcOptions, exist := windowsSvcOptions[majorVersion]; exist {
			// only keep the related images for windows
			windowsSysImgs := v3.RKESystemImages{
				NginxProxy:                sysImgs.NginxProxy,
				CertDownloader:            sysImgs.CertDownloader,
				KubernetesServicesSidecar: sysImgs.KubernetesServicesSidecar,
				Kubernetes:                sysImgs.Kubernetes,
				WindowsPodInfraContainer:  sysImgs.WindowsPodInfraContainer,
			}

			windowsInfo.RKESystemImages[k8sVersion] = windowsSysImgs
			windowsInfo.KubernetesServicesOptions[k8sVersion] = svcOptions
		}
		if svcOptions, exist := linuxSvcOptions[majorVersion]; exist {
			// clean the unrelated images for linux
			sysImgs.WindowsPodInfraContainer = ""

			linuxInfo.RKESystemImages[k8sVersion] = sysImgs
			linuxInfo.KubernetesServicesOptions[k8sVersion] = svcOptions
		}
	}

	return linuxInfo, windowsInfo
}

type VersionInfo struct {
	RKESystemImages           map[string]v3.RKESystemImages
	KubernetesServicesOptions map[string]v3.KubernetesServicesOptions
}

func newVersionInfo() *VersionInfo {
	return &VersionInfo{
		RKESystemImages:           map[string]v3.RKESystemImages{},
		KubernetesServicesOptions: map[string]v3.KubernetesServicesOptions{},
	}
}

func GetRancherVersion() string {
	rancherVersion := settings.ServerVersion.Get()
	if strings.HasPrefix(rancherVersion, "dev") || strings.HasPrefix(rancherVersion, "master") {
		return RancherVersionDev
	}
	if strings.HasPrefix(rancherVersion, "v") {
		return rancherVersion[1:]
	}
	return rancherVersion
}
<|endoftext|>


<commit_before>/*
 *    Copyright (C) 2017 Christian Muehlhaeuser
 *
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU Affero General Public License as published
 *    by the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *    Authors:
 *      Christian Muehlhaeuser <muesli@gmail.com>
 */

package hives

import (
	"github.com/muesli/beehive/bees"

	"github.com/emicklei/go-restful"
	"github.com/muesli/smolder"
)

// GetAuthRequired returns true because all requests need authentication
func (r *HiveResource) GetAuthRequired() bool {
	return false
}

// GetByIDsAuthRequired returns true because all requests need authentication
func (r *HiveResource) GetByIDsAuthRequired() bool {
	return false
}

// GetDoc returns the description of this API endpoint
func (r *HiveResource) GetDoc() string {
	return "retrieve hives"
}

// GetParams returns the parameters supported by this API endpoint
func (r *HiveResource) GetParams() []*restful.Parameter {
	params := []*restful.Parameter{}
	// params = append(params, restful.QueryParameter("user_id", "id of a user").DataType("int64"))

	return params
}

// GetByIDs sends out all items matching a set of IDs
func (r *HiveResource) GetByIDs(ctx smolder.APIContext, request *restful.Request, response *restful.Response, ids []string) {
	resp := HiveResponse{}
	resp.Init(ctx)

	for _, id := range ids {
		hive := bees.GetBeeFactory(id)
		if hive == nil {
			r.NotFound(request, response)
			return
		}

		resp.AddHive(hive)
	}

	resp.Send(response)
}

// Get sends out items matching the query parameters
func (r *HiveResource) Get(ctx smolder.APIContext, request *restful.Request, response *restful.Response, params map[string][]string) {
	//	ctxapi := ctx.(*context.APIContext)
	hives := bees.GetBeeFactories()
	if len(hives) == 0 { // err != nil {
		r.NotFound(request, response)
		return
	}

	resp := HiveResponse{}
	resp.Init(ctx)

	for _, hive := range hives {
		resp.AddHive(hive)
	}

	resp.Send(response)
}
<commit_msg>Adapted HiveResource to new Beehive API<commit_after>/*
 *    Copyright (C) 2017 Christian Muehlhaeuser
 *
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU Affero General Public License as published
 *    by the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *    Authors:
 *      Christian Muehlhaeuser <muesli@gmail.com>
 */

package hives

import (
	"github.com/muesli/beehive/bees"

	"github.com/emicklei/go-restful"
	"github.com/muesli/smolder"
)

// GetAuthRequired returns true because all requests need authentication
func (r *HiveResource) GetAuthRequired() bool {
	return false
}

// GetByIDsAuthRequired returns true because all requests need authentication
func (r *HiveResource) GetByIDsAuthRequired() bool {
	return false
}

// GetDoc returns the description of this API endpoint
func (r *HiveResource) GetDoc() string {
	return "retrieve hives"
}

// GetParams returns the parameters supported by this API endpoint
func (r *HiveResource) GetParams() []*restful.Parameter {
	params := []*restful.Parameter{}
	// params = append(params, restful.QueryParameter("user_id", "id of a user").DataType("int64"))

	return params
}

// GetByIDs sends out all items matching a set of IDs
func (r *HiveResource) GetByIDs(ctx smolder.APIContext, request *restful.Request, response *restful.Response, ids []string) {
	resp := HiveResponse{}
	resp.Init(ctx)

	for _, id := range ids {
		hive := bees.GetFactory(id)
		if hive == nil {
			r.NotFound(request, response)
			return
		}

		resp.AddHive(hive)
	}

	resp.Send(response)
}

// Get sends out items matching the query parameters
func (r *HiveResource) Get(ctx smolder.APIContext, request *restful.Request, response *restful.Response, params map[string][]string) {
	//	ctxapi := ctx.(*context.APIContext)
	hives := bees.GetFactories()
	if len(hives) == 0 { // err != nil {
		r.NotFound(request, response)
		return
	}

	resp := HiveResponse{}
	resp.Init(ctx)

	for _, hive := range hives {
		resp.AddHive(hive)
	}

	resp.Send(response)
}
<|endoftext|>


<commit_before>// +build !windows

package clipboard

import "errors"

// Clear removes all data from the clipboard.
func Clear() error {
	return NoData{notImplemented: true}
}

// Read gets data from the clipboard. If multiple clipboard formats are
// supported, Read selects the first format that matches one of the given
// media types.
//
// Each argument is a media type (e.g. "text/plain").
//
// If an error is returned, then f will be less than 0. If no data was found,
// then the error will contain NoDataError. If no formats were given, then f
// will be less than 0, and err will be nil.
func Read(formats ...string) (f int, b []byte, err error) {
	return 0, nil, NoData{notImplemented: true}
}

// Write sets data to the clipboard. If multiple formats are supported, then
// each given format is written according to the specified media type.
// Otherwise, which format is selected is implementation-defined.
//
// If no formats are given, then the clipboard is cleared with no other action.
func Write(formats []Format) (err error) {
	return NoData{notImplemented: true}
}
<commit_msg>Fix non-windows build.<commit_after>// +build !windows

package clipboard

// Clear removes all data from the clipboard.
func Clear() error {
	return NoDataError{notImplemented: true}
}

// Read gets data from the clipboard. If multiple clipboard formats are
// supported, Read selects the first format that matches one of the given
// media types.
//
// Each argument is a media type (e.g. "text/plain").
//
// If an error is returned, then f will be less than 0. If no data was found,
// then the error will contain NoDataError. If no formats were given, then f
// will be less than 0, and err will be nil.
func Read(formats ...string) (f int, b []byte, err error) {
	return 0, nil, NoDataError{notImplemented: true}
}

// Write sets data to the clipboard. If multiple formats are supported, then
// each given format is written according to the specified media type.
// Otherwise, which format is selected is implementation-defined.
//
// If no formats are given, then the clipboard is cleared with no other action.
func Write(formats []Format) (err error) {
	return NoDataError{notImplemented: true}
}
<|endoftext|>


<commit_before>package http

import (
	"fmt"
	"github.com/Cepave/alarm/g"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"github.com/toolkits/file"
	"log"

	// "sort"
	"strings"
	"time"

	"github.com/astaxie/beego"
	"github.com/open-falcon/alarm/g"
	"github.com/toolkits/file"
)

type MainController struct {
	beego.Controller
}

func (this *MainController) Version() {
	this.Ctx.WriteString(g.VERSION)
}

func (this *MainController) Health() {
	this.Ctx.WriteString("ok")
}

func (this *MainController) Workdir() {
	this.Ctx.WriteString(fmt.Sprintf("%s", file.SelfDir()))
}

func (this *MainController) ConfigReload() {
	remoteAddr := this.Ctx.Input.Context.Request.RemoteAddr
	if strings.HasPrefix(remoteAddr, "127.0.0.1") {
		g.ParseConfig(g.ConfigFile)
		this.Data["json"] = g.Config()
		this.ServeJSON()
	} else {
		this.Ctx.WriteString("no privilege")
	}
}

func SelectSessionBySig(sig string) *Session {
	if sig == "" {
		return nil
	}

	obj := Session{Sig: sig}
	err := orm.NewOrm().Read(&obj, "Sig")
	if err != nil {
		if err != orm.ErrNoRows {
			log.Println(err.Error())
		}
		return nil
	}
	return &obj
}

func DeleteSessionById(id int64) (int64, error) {
	r, err := orm.NewOrm().Raw("DELETE FROM `session` WHERE `id` = ?", id).Exec()
	if err != nil {
		return 0, err
	}
	return r.RowsAffected()
}

func SelectUserById(id int64) *User {
	if id <= 0 {
		return nil
	}

	obj := User{Id: id}
	err := orm.NewOrm().Read(&obj, "Id")
	if err != nil {
		if err != orm.ErrNoRows {
			log.Println(err.Error())
		}
		return nil
	}
	return &obj
}

/**
 * @function name:	func CheckLoginStatusByCookie(sig) bool
 * @description:	This function checks user's login status by value of "sig" cookie.
 * @related issues:	OWL-127
 * @param:			sig string
 * @return:			bool
 * @author:			Don Hsieh
 * @since:			10/15/2015
 * @last modified: 	10/30/2015
 * @called by:		func (this *MainController) Index()
 *					 in http/controller.go
 */
func CheckLoginStatusByCookie(sig string) bool {
	if sig == "" {
		return false
	}

	sessionObj := SelectSessionBySig(sig)
	if sessionObj == nil {
		log.Println("no such sig")
		return false
	}

	if int64(sessionObj.Expired) < time.Now().Unix() {
		log.Println("session expired")
		DeleteSessionById(sessionObj.Id)
		return false
	}

	user := SelectUserById(sessionObj.Uid)
	if user == nil {
		log.Println("no such user")
		return false
	}

	if len(user.Name) > 0 {
		return true
	} else {
		return false
	}
}

func (this *MainController) Index() {
	// Only check the Login status in Prodution env.
	if g.Config().Debug == false {
		checkLogin(this)
	}
	defer func() {
		this.Data["Now"] = time.Now().Unix()
		this.TplName = "index.html"
		this.Data["FalconPortal"] = g.Config().Shortcut.FalconPortal
		this.Data["FalconDashboard"] = g.Config().Shortcut.FalconDashboard
		this.Data["GrafanaDashboard"] = g.Config().Shortcut.GrafanaDashboard
		this.Data["FalconAlarm"] = g.Config().Shortcut.FalconAlarm
		this.Data["FalconUIC"] = g.Config().Shortcut.FalconUIC
	}()

	this.Data["Events"] = g.Events.CloneToOrderedEvents()
}

func (this *MainController) Event() {
	// Only check the Login status in Prodution env.
	if g.Config().Debug == false {
		checkLogin(this)
	}

	this.Data["json"] = g.Events.CloneToOrderedEvents()
	this.ServeJSON()
}

func (this *MainController) Solve() {
	ids := this.GetString("ids")
	if ids == "" {
		this.Ctx.WriteString("")
		return
	}

	idArr := strings.Split(ids, ",,")
	for i := 0; i < len(idArr); i++ {
		g.Events.Delete(idArr[i])
	}

	this.Ctx.WriteString("")
}

func checkLogin(m *MainController) {
	sig := m.Ctx.GetCookie("sig")
	isLoggedIn := CheckLoginStatusByCookie(sig)
	if !isLoggedIn {
		RedirectUrl := g.Config().RedirectUrl
		m.Redirect(RedirectUrl, 302)
	}
}

// func getOrderedEventsClone() []*g.EventDto {
// 	events := g.Events.Clone()
// 	count := len(events)
// 	if count == 0 {
// 		return []*g.EventDto{}
// 	}

// 	sortedEvent := make([]*g.EventDto, count)
// 	i := 0
// 	for _, event := range events {
// 		sortedEvent[i] = event
// 		i++
// 	}
//     // Sorted by Timestamp of EventDto
// 	sort.Sort(g.OrderedEvents(sortedEvent))
// 	return sortedEvent
// }
<commit_msg>Fix /event API bug of response when not logged in.<commit_after>package http

import (
	"fmt"
	"github.com/Cepave/alarm/g"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"github.com/toolkits/file"
	"log"
	"strings"
	"time"

	"github.com/astaxie/beego"
	"github.com/open-falcon/alarm/g"
	"github.com/toolkits/file"
)

type MainController struct {
	beego.Controller
}

func (this *MainController) Version() {
	this.Ctx.WriteString(g.VERSION)
}

func (this *MainController) Health() {
	this.Ctx.WriteString("ok")
}

func (this *MainController) Workdir() {
	this.Ctx.WriteString(fmt.Sprintf("%s", file.SelfDir()))
}

func (this *MainController) ConfigReload() {
	remoteAddr := this.Ctx.Input.Context.Request.RemoteAddr
	if strings.HasPrefix(remoteAddr, "127.0.0.1") {
		g.ParseConfig(g.ConfigFile)
		this.Data["json"] = g.Config()
		this.ServeJSON()
	} else {
		this.Ctx.WriteString("no privilege")
	}
}

func SelectSessionBySig(sig string) *Session {
	if sig == "" {
		return nil
	}

	obj := Session{Sig: sig}
	err := orm.NewOrm().Read(&obj, "Sig")
	if err != nil {
		if err != orm.ErrNoRows {
			log.Println(err.Error())
		}
		return nil
	}
	return &obj
}

func DeleteSessionById(id int64) (int64, error) {
	r, err := orm.NewOrm().Raw("DELETE FROM `session` WHERE `id` = ?", id).Exec()
	if err != nil {
		return 0, err
	}
	return r.RowsAffected()
}

func SelectUserById(id int64) *User {
	if id <= 0 {
		return nil
	}

	obj := User{Id: id}
	err := orm.NewOrm().Read(&obj, "Id")
	if err != nil {
		if err != orm.ErrNoRows {
			log.Println(err.Error())
		}
		return nil
	}
	return &obj
}

/**
 * @function name:	func CheckLoginStatusByCookie(sig) bool
 * @description:	This function checks user's login status by value of "sig" cookie.
 * @related issues:	OWL-127
 * @param:			sig string
 * @return:			bool
 * @author:			Don Hsieh
 * @since:			10/15/2015
 * @last modified: 	10/30/2015
 * @called by:		func (this *MainController) Index()
 *					 in http/controller.go
 */
func CheckLoginStatusByCookie(sig string) bool {
	if sig == "" {
		return false
	}

	sessionObj := SelectSessionBySig(sig)
	if sessionObj == nil {
		log.Println("no such sig")
		return false
	}

	if int64(sessionObj.Expired) < time.Now().Unix() {
		log.Println("session expired")
		DeleteSessionById(sessionObj.Id)
		return false
	}

	user := SelectUserById(sessionObj.Uid)
	if user == nil {
		log.Println("no such user")
		return false
	}

	if len(user.Name) > 0 {
		return true
	} else {
		return false
	}
}

func (this *MainController) Index() {
	if checkLogin(this) == false {
		return
	}
	defer func() {
		this.Data["Now"] = time.Now().Unix()
		this.TplName = "index.html"
		this.Data["FalconPortal"] = g.Config().Shortcut.FalconPortal
		this.Data["FalconDashboard"] = g.Config().Shortcut.FalconDashboard
		this.Data["GrafanaDashboard"] = g.Config().Shortcut.GrafanaDashboard
		this.Data["FalconAlarm"] = g.Config().Shortcut.FalconAlarm
		this.Data["FalconUIC"] = g.Config().Shortcut.FalconUIC
	}()

	this.Data["Events"] = g.Events.CloneToOrderedEvents()
}

func (this *MainController) Event() {
	if checkLogin(this) == false {
		return
	}
	this.Data["json"] = g.Events.CloneToOrderedEvents()
	this.ServeJSON()
}

func (this *MainController) Solve() {
	ids := this.GetString("ids")
	if ids == "" {
		this.Ctx.WriteString("")
		return
	}

	idArr := strings.Split(ids, ",,")
	for i := 0; i < len(idArr); i++ {
		g.Events.Delete(idArr[i])
	}

	this.Ctx.WriteString("")
}

func checkLogin(m *MainController) bool {
	// Skip the login check in debug mode.
	if g.Config().Debug {
		return true
	}

	sig := m.Ctx.GetCookie("sig")
	isLoggedIn := CheckLoginStatusByCookie(sig)
	if !isLoggedIn {
		RedirectUrl := g.Config().RedirectUrl
		m.Redirect(RedirectUrl, 302)
		return false
	}
	return true
}
<|endoftext|>


<commit_before>package http

import (
	"encoding/json"
	"errors"
	"log"
	"net/http"
	"strings"

	cmodel "github.com/Cepave/common/model"
	"github.com/Cepave/query/graph"
	"github.com/Cepave/query/proc"
)

type GraphHistoryParam struct {
	Start            int                     `json:"start"`
	End              int                     `json:"end"`
	CF               string                  `json:"cf"`
	EndpointCounters []cmodel.GraphInfoParam `json:"endpoint_counters"`
}

func configGraphRoutes() {

	// method:post
	http.HandleFunc("/graph/history", func(w http.ResponseWriter, r *http.Request) {
		// statistics
		proc.HistoryRequestCnt.Incr()

		var body GraphHistoryParam
		decoder := json.NewDecoder(r.Body)
		err := decoder.Decode(&body)
		if err != nil {
			StdRender(w, "", err)
			return
		}

		if len(body.EndpointCounters) == 0 {
			StdRender(w, "", errors.New("empty_payload"))
			return
		}

		data := []*cmodel.GraphQueryResponse{}
		isPacketLossRate := false
		for _, ec := range body.EndpointCounters {
			if strings.Contains(ec.Counter,"packet-loss-rate") {
				isPacketLossRate = true
				break
			}
		}
		isAverage := false
		for _, ec := range body.EndpointCounters {
			if strings.Contains(ec.Counter,"average") {
				isAverage = true
				break
			}
		}
		if isPacketLossRate {
			//var result *cmodel.GraphQueryResponse
			/**result = cmodel.GraphQueryResponse{
				Endpoint:    "all-endpoints",
				Counter:     "packet-loss-rate",
				DsType:      "GAUGE",
				Step:        60,
				Values:      []*cmodel.RRDData{},
			}*/

			/**
			 * 下面這段，只是想先製造一個跟 packets-sent 的 response 一樣的 struct
			 */
			var result *cmodel.GraphQueryResponse
			var packetSentCount []cmodel.JsonFloat
			for _, ec := range body.EndpointCounters {
				if strings.Contains(ec.Counter,"packets-sent") {
					request := cmodel.GraphQueryParam{
						Start:     int64(body.Start),
						End:       int64(body.End),
						ConsolFun: body.CF,
						Endpoint:  ec.Endpoint,
						Counter:   ec.Counter,
					}
					result, err = graph.QueryOne(request)
					for i := range result.Values {
						result.Values[i].Value = cmodel.JsonFloat(0.0)
						packetSentCount = append(packetSentCount, cmodel.JsonFloat(0.0))
					}
					if err != nil {
						log.Printf("graph.queryOne fail, %v", err)
					}
					break
				}
			}

			for _, ec := range body.EndpointCounters {

				if strings.Contains(ec.Counter,"packets-sent") {

					requestPacketsSent := cmodel.GraphQueryParam{
						Start:     int64(body.Start),
						End:       int64(body.End),
						ConsolFun: body.CF,
						Endpoint:  ec.Endpoint,
						Counter:   ec.Counter, //strings.Replace(ec.Counter, "packet-loss-rate", "packets-sent", 1),
					}
					resultPacketsSent, err := graph.QueryOne(requestPacketsSent)
					if err != nil {
						log.Printf("graph.queryOne fail, %v", err)
					}
					if resultPacketsSent == nil {
						continue
					}
					data = append(data, resultPacketsSent)

					requestPacketReceived := cmodel.GraphQueryParam{
						Start:     int64(body.Start),
						End:       int64(body.End),
						ConsolFun: body.CF,
						Endpoint:  ec.Endpoint,
						Counter:   strings.Replace(ec.Counter, "packets-sent", "packets-received", 1),
					}
					resultPacketReceived, err := graph.QueryOne(requestPacketReceived)
					if err != nil {
						log.Printf("graph.queryOne fail, %v", err)
					}
					if resultPacketReceived == nil {
						continue
					}
					data = append(data, resultPacketReceived)
					for i := range resultPacketsSent.Values {
						/**
						 * 下面這行會讓 resultValues 的 Timestamp 取到最後一個 endpoint-counter pair 的 Timestamp
						 */
						// 上面有了 result 後這邊就不需要了 //result.Values[i].Timestamp = resultPacketsSent.Values[i].Timestamp

						packetLossCount := (resultPacketsSent.Values[i].Value		-
											resultPacketReceived.Values[i].Value)
						result.Values[i].Value += packetLossCount
						packetSentCount[i] += resultPacketsSent.Values[i].Value
						log.Printf("sentCnt = %f, rcvCnt = %f, totalLossCnt = %f, totalSentCnt = %f",float64(resultPacketsSent.Values[i].Value), float64(resultPacketReceived.Values[i].Value), float64(result.Values[i].Value), float64(packetSentCount[i]))
					}
				}

			}

			result.Endpoint = "all-endpoints"
			result.Counter = "packet-loss-rate"
			for i := range result.Values {
				//log.Printf("diff = %f, sentCnt = %f",float64(result.Values[i].Value), float64(packetSentCount))
				result.Values[i].Value = result.Values[i].Value/packetSentCount[i]
			}
			result.Values = result.Values
			data = append(data, result)

		} else if isAverage {
			/**
			 * 下面這段，只是想先製造一個跟 transmission-time 的 response 一樣的 struct
			 */
			var result *cmodel.GraphQueryResponse
			var packetSentCount []cmodel.JsonFloat
			for _, ec := range body.EndpointCounters {
				if strings.Contains(ec.Counter,"transmission-time") {
					request := cmodel.GraphQueryParam{
						Start:     int64(body.Start),
						End:       int64(body.End),
						ConsolFun: body.CF,
						Endpoint:  ec.Endpoint,
						Counter:   ec.Counter,
					}
					result, err = graph.QueryOne(request)
					for i := range result.Values {
						result.Values[i].Value = cmodel.JsonFloat(0.0)
						packetSentCount = append(packetSentCount, cmodel.JsonFloat(0.0))
					}
					if err != nil {
						log.Printf("graph.queryOne fail, %v", err)
					}
					break
				}
			}
			for _, ec := range body.EndpointCounters {

				if strings.Contains(ec.Counter,"transmission-time") {

					requestTransmissionTime := cmodel.GraphQueryParam{
						Start:     int64(body.Start),
						End:       int64(body.End),
						ConsolFun: body.CF,
						Endpoint:  ec.Endpoint,
						Counter:   ec.Counter,
					}
					resultTransmissionTime, err := graph.QueryOne(requestTransmissionTime)
					if err != nil {
						log.Printf("graph.queryOne fail, %v", err)
					}
					if resultTransmissionTime == nil {
						continue
					}
					data = append(data, resultTransmissionTime)

					requestPacketsSent := cmodel.GraphQueryParam{
						Start:     int64(body.Start),
						End:       int64(body.End),
						ConsolFun: body.CF,
						Endpoint:  ec.Endpoint,
						Counter:   strings.Replace(ec.Counter, "transmission-time", "packets-sent", 1),
					}
					resultPacketsSent, err := graph.QueryOne(requestPacketsSent)
					if err != nil {
						log.Printf("graph.queryOne fail, %v", err)
					}
					if resultPacketsSent == nil {
						continue
					}
					data = append(data, resultPacketsSent)

					for i := range resultTransmissionTime.Values {
						result.Values[i].Value += resultTransmissionTime.Values[i].Value * resultPacketsSent.Values[i].Value
						packetSentCount[i] += resultPacketsSent.Values[i].Value
						//log.Printf("sentCnt = %f, rcvCnt = %f, totalLossCnt = %f, totalSentCnt = %f",float64(resultPacketsSent.Values[i].Value), float64(resultPacketReceived.Values[i].Value), float64(result.Values[i].Value), float64(packetSentCount[i]))
					}
				}

			}

			result.Endpoint = "all-endpoints"
			result.Counter = "average"
			for i := range result.Values {
				//log.Printf("diff = %f, sentCnt = %f",float64(result.Values[i].Value), float64(packetSentCount))
				result.Values[i].Value = result.Values[i].Value/packetSentCount[i]
			}
			result.Values = result.Values
			data = append(data, result)

		} else {
			for _, ec := range body.EndpointCounters {
				request := cmodel.GraphQueryParam{
					Start:     int64(body.Start),
					End:       int64(body.End),
					ConsolFun: body.CF,
					Endpoint:  ec.Endpoint,
					Counter:   ec.Counter,
				}
				result, err := graph.QueryOne(request)
				if err != nil {
					log.Printf("graph.queryOne fail, %v", err)
				}
				if result == nil {
					continue
				}
				data = append(data, result)
			}
		}

		// statistics
		proc.HistoryResponseCounterCnt.IncrBy(int64(len(data)))
		for _, item := range data {
			proc.HistoryResponseItemCnt.IncrBy(int64(len(item.Values)))
		}

		StdRender(w, data, nil)
	})

	// post, info
	http.HandleFunc("/graph/info", func(w http.ResponseWriter, r *http.Request) {
		// statistics
		proc.InfoRequestCnt.Incr()

		var body []*cmodel.GraphInfoParam
		decoder := json.NewDecoder(r.Body)
		err := decoder.Decode(&body)
		if err != nil {
			StdRender(w, "", err)
			return
		}

		if len(body) == 0 {
			StdRender(w, "", errors.New("empty"))
			return
		}

		data := []*cmodel.GraphFullyInfo{}
		for _, param := range body {
			if param == nil {
				continue
			}
			info, err := graph.Info(*param)
			if err != nil {
				log.Printf("graph.info fail, resp: %v, err: %v", info, err)
			}
			if info == nil {
				continue
			}
			data = append(data, info)
		}

		StdRender(w, data, nil)
	})

	// post, last
	http.HandleFunc("/graph/last", func(w http.ResponseWriter, r *http.Request) {
		// statistics
		proc.LastRequestCnt.Incr()

		var body []*cmodel.GraphLastParam
		decoder := json.NewDecoder(r.Body)
		err := decoder.Decode(&body)
		if err != nil {
			StdRender(w, "", err)
			return
		}

		if len(body) == 0 {
			StdRender(w, "", errors.New("empty"))
			return
		}

		data := []*cmodel.GraphLastResp{}
		for _, param := range body {
			if param == nil {
				continue
			}
			last, err := graph.Last(*param)
			if err != nil {
				log.Printf("graph.last fail, resp: %v, err: %v", last, err)
			}
			if last == nil {
				continue
			}
			data = append(data, last)
		}

		// statistics
		proc.LastRequestItemCnt.IncrBy(int64(len(data)))

		StdRender(w, data, nil)
	})

	// post, last/raw
	http.HandleFunc("/graph/last/raw", func(w http.ResponseWriter, r *http.Request) {
		// statistics
		proc.LastRawRequestCnt.Incr()

		var body []*cmodel.GraphLastParam
		decoder := json.NewDecoder(r.Body)
		err := decoder.Decode(&body)
		if err != nil {
			StdRender(w, "", err)
			return
		}

		if len(body) == 0 {
			StdRender(w, "", errors.New("empty"))
			return
		}

		data := []*cmodel.GraphLastResp{}
		for _, param := range body {
			if param == nil {
				continue
			}
			last, err := graph.LastRaw(*param)
			if err != nil {
				log.Printf("graph.last.raw fail, resp: %v, err: %v", last, err)
			}
			if last == nil {
				continue
			}
			data = append(data, last)
		}
		// statistics
		proc.LastRawRequestItemCnt.IncrBy(int64(len(data)))
		StdRender(w, data, nil)
	})

}
<commit_msg>Just sort out some comments<commit_after>package http

import (
	"encoding/json"
	"errors"
	"log"
	"net/http"
	"strings"

	cmodel "github.com/Cepave/common/model"
	"github.com/Cepave/query/graph"
	"github.com/Cepave/query/proc"
)

type GraphHistoryParam struct {
	Start            int                     `json:"start"`
	End              int                     `json:"end"`
	CF               string                  `json:"cf"`
	EndpointCounters []cmodel.GraphInfoParam `json:"endpoint_counters"`
}

func configGraphRoutes() {

	// method:post
	http.HandleFunc("/graph/history", func(w http.ResponseWriter, r *http.Request) {
		// statistics
		proc.HistoryRequestCnt.Incr()

		var body GraphHistoryParam
		decoder := json.NewDecoder(r.Body)
		err := decoder.Decode(&body)
		if err != nil {
			StdRender(w, "", err)
			return
		}

		if len(body.EndpointCounters) == 0 {
			StdRender(w, "", errors.New("empty_payload"))
			return
		}

		data := []*cmodel.GraphQueryResponse{}
		var result *cmodel.GraphQueryResponse
		isPacketLossRate := false
		for _, ec := range body.EndpointCounters {
			if strings.Contains(ec.Counter,"packet-loss-rate") {
				isPacketLossRate = true
				break
			}
		}
		isAverage := false
		for _, ec := range body.EndpointCounters {
			if strings.Contains(ec.Counter,"average") {
				isAverage = true
				break
			}
		}
		if isPacketLossRate {
			/**
			 * 下面這段，只是想先做一個跟 packets-sent 的 response 一樣的 struct
			 */
			var packetSentCount []cmodel.JsonFloat
			for _, ec := range body.EndpointCounters {
				if strings.Contains(ec.Counter,"packets-sent") {
					request := cmodel.GraphQueryParam{
						Start:     int64(body.Start),
						End:       int64(body.End),
						ConsolFun: body.CF,
						Endpoint:  ec.Endpoint,
						Counter:   ec.Counter,
					}
					result, err = graph.QueryOne(request)
					for i := range result.Values {
						result.Values[i].Value = cmodel.JsonFloat(0.0)
						packetSentCount = append(packetSentCount, cmodel.JsonFloat(0.0))
					}
					if err != nil {
						log.Printf("graph.queryOne fail, %v", err)
					}
					break
				}
			}

			for _, ec := range body.EndpointCounters {
				/**
				 * 此版本中，在 dashboard 查詢 packet-loss-rate 的時候，
				 * dashboard 會以 packets-sent 這個 metric 來呈現搜尋到的結果。
				 */
				if strings.Contains(ec.Counter,"packets-sent") {
					/**
					 * 此版本中，packet-loss-rate 的 data，
					 * 必須跟 packets-sent & packets-eceived 一起看。
					 */
					requestPacketsSent := cmodel.GraphQueryParam{
						Start:     int64(body.Start),
						End:       int64(body.End),
						ConsolFun: body.CF,
						Endpoint:  ec.Endpoint,
						Counter:   ec.Counter,
					}
					resultPacketsSent, err := graph.QueryOne(requestPacketsSent)
					if err != nil {
						log.Printf("graph.queryOne fail, %v", err)
					}
					if resultPacketsSent == nil {
						continue
					}
					data = append(data, resultPacketsSent)

					requestPacketReceived := cmodel.GraphQueryParam{
						Start:     int64(body.Start),
						End:       int64(body.End),
						ConsolFun: body.CF,
						Endpoint:  ec.Endpoint,
						Counter:   strings.Replace(ec.Counter, "packets-sent", "packets-received", 1),
					}
					resultPacketReceived, err := graph.QueryOne(requestPacketReceived)
					if err != nil {
						log.Printf("graph.queryOne fail, %v", err)
					}
					if resultPacketReceived == nil {
						continue
					}
					data = append(data, resultPacketReceived)
					for i := range resultPacketsSent.Values {
						packetLossCount := (resultPacketsSent.Values[i].Value		-
											resultPacketReceived.Values[i].Value)
						result.Values[i].Value += packetLossCount
						packetSentCount[i] += resultPacketsSent.Values[i].Value
					}
				}

			}

			result.Endpoint = "all-endpoints"
			result.Counter = "packet-loss-rate"
			for i := range result.Values {
				result.Values[i].Value = result.Values[i].Value/packetSentCount[i]
			}
			result.Values = result.Values
			data = append(data, result)

		} else if isAverage {
			/**
			 * 下面這段，只是想先製造一個跟 transmission-time 的 response 一樣的 struct
			 */
			var packetSentCount []cmodel.JsonFloat
			for _, ec := range body.EndpointCounters {
				if strings.Contains(ec.Counter,"transmission-time") {
					request := cmodel.GraphQueryParam{
						Start:     int64(body.Start),
						End:       int64(body.End),
						ConsolFun: body.CF,
						Endpoint:  ec.Endpoint,
						Counter:   ec.Counter,
					}
					result, err = graph.QueryOne(request)
					for i := range result.Values {
						result.Values[i].Value = cmodel.JsonFloat(0.0)
						packetSentCount = append(packetSentCount, cmodel.JsonFloat(0.0))
					}
					if err != nil {
						log.Printf("graph.queryOne fail, %v", err)
					}
					break
				}
			}
			for _, ec := range body.EndpointCounters {
				/**
				 * 此版本中，在 dashboard 查詢 average 的時候，
				 * dashboard 會以 transmission-time 這個 metric 來呈現搜尋到的結果。
				 */
				if strings.Contains(ec.Counter,"transmission-time") {
					/**
					 * 此版本中，average 的 data，
					 * 必須跟 transmission-time & packets-sent 一起看。
					 */
					requestTransmissionTime := cmodel.GraphQueryParam{
						Start:     int64(body.Start),
						End:       int64(body.End),
						ConsolFun: body.CF,
						Endpoint:  ec.Endpoint,
						Counter:   ec.Counter,
					}
					resultTransmissionTime, err := graph.QueryOne(requestTransmissionTime)
					if err != nil {
						log.Printf("graph.queryOne fail, %v", err)
					}
					if resultTransmissionTime == nil {
						continue
					}
					data = append(data, resultTransmissionTime)

					requestPacketsSent := cmodel.GraphQueryParam{
						Start:     int64(body.Start),
						End:       int64(body.End),
						ConsolFun: body.CF,
						Endpoint:  ec.Endpoint,
						Counter:   strings.Replace(ec.Counter, "transmission-time", "packets-sent", 1),
					}
					resultPacketsSent, err := graph.QueryOne(requestPacketsSent)
					if err != nil {
						log.Printf("graph.queryOne fail, %v", err)
					}
					if resultPacketsSent == nil {
						continue
					}
					data = append(data, resultPacketsSent)
					for i := range resultTransmissionTime.Values {
						result.Values[i].Value += resultTransmissionTime.Values[i].Value * resultPacketsSent.Values[i].Value
						packetSentCount[i] += resultPacketsSent.Values[i].Value
					}
				}

			}

			result.Endpoint = "all-endpoints"
			result.Counter = "average"
			for i := range result.Values {
				result.Values[i].Value = result.Values[i].Value/packetSentCount[i]
			}
			result.Values = result.Values
			data = append(data, result)

		} else {
			for _, ec := range body.EndpointCounters {
				request := cmodel.GraphQueryParam{
					Start:     int64(body.Start),
					End:       int64(body.End),
					ConsolFun: body.CF,
					Endpoint:  ec.Endpoint,
					Counter:   ec.Counter,
				}
				result, err := graph.QueryOne(request)
				if err != nil {
					log.Printf("graph.queryOne fail, %v", err)
				}
				if result == nil {
					continue
				}
				data = append(data, result)
			}
		}

		// statistics
		proc.HistoryResponseCounterCnt.IncrBy(int64(len(data)))
		for _, item := range data {
			proc.HistoryResponseItemCnt.IncrBy(int64(len(item.Values)))
		}

		StdRender(w, data, nil)
	})

	// post, info
	http.HandleFunc("/graph/info", func(w http.ResponseWriter, r *http.Request) {
		// statistics
		proc.InfoRequestCnt.Incr()

		var body []*cmodel.GraphInfoParam
		decoder := json.NewDecoder(r.Body)
		err := decoder.Decode(&body)
		if err != nil {
			StdRender(w, "", err)
			return
		}

		if len(body) == 0 {
			StdRender(w, "", errors.New("empty"))
			return
		}

		data := []*cmodel.GraphFullyInfo{}
		for _, param := range body {
			if param == nil {
				continue
			}
			info, err := graph.Info(*param)
			if err != nil {
				log.Printf("graph.info fail, resp: %v, err: %v", info, err)
			}
			if info == nil {
				continue
			}
			data = append(data, info)
		}

		StdRender(w, data, nil)
	})

	// post, last
	http.HandleFunc("/graph/last", func(w http.ResponseWriter, r *http.Request) {
		// statistics
		proc.LastRequestCnt.Incr()

		var body []*cmodel.GraphLastParam
		decoder := json.NewDecoder(r.Body)
		err := decoder.Decode(&body)
		if err != nil {
			StdRender(w, "", err)
			return
		}

		if len(body) == 0 {
			StdRender(w, "", errors.New("empty"))
			return
		}

		data := []*cmodel.GraphLastResp{}
		for _, param := range body {
			if param == nil {
				continue
			}
			last, err := graph.Last(*param)
			if err != nil {
				log.Printf("graph.last fail, resp: %v, err: %v", last, err)
			}
			if last == nil {
				continue
			}
			data = append(data, last)
		}

		// statistics
		proc.LastRequestItemCnt.IncrBy(int64(len(data)))

		StdRender(w, data, nil)
	})

	// post, last/raw
	http.HandleFunc("/graph/last/raw", func(w http.ResponseWriter, r *http.Request) {
		// statistics
		proc.LastRawRequestCnt.Incr()

		var body []*cmodel.GraphLastParam
		decoder := json.NewDecoder(r.Body)
		err := decoder.Decode(&body)
		if err != nil {
			StdRender(w, "", err)
			return
		}

		if len(body) == 0 {
			StdRender(w, "", errors.New("empty"))
			return
		}

		data := []*cmodel.GraphLastResp{}
		for _, param := range body {
			if param == nil {
				continue
			}
			last, err := graph.LastRaw(*param)
			if err != nil {
				log.Printf("graph.last.raw fail, resp: %v, err: %v", last, err)
			}
			if last == nil {
				continue
			}
			data = append(data, last)
		}
		// statistics
		proc.LastRawRequestItemCnt.IncrBy(int64(len(data)))
		StdRender(w, data, nil)
	})

}
<|endoftext|>


<commit_before>package aws

import (
	"bytes"
	"fmt"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/pinpoint"
	"github.com/hashicorp/terraform/helper/hashcode"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/validation"
	"log"
)

func resourceAwsPinpointApp() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsPinpointAppCreate,
		Read:   resourceAwsPinpointAppRead,
		Update: resourceAwsPinpointAppUpdate,
		Delete: resourceAwsPinpointAppDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"name": {
				Type:          schema.TypeString,
				Optional:      true,
				Computed:      true,
				ForceNew:      true,
				ConflictsWith: []string{"name_prefix"},
			},
			"name_prefix": {
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
			},
			"application_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			//"cloudwatch_metrics_enabled": {
			//	Type:     schema.TypeBool,
			//	Optional: true,
			//	Default:  false,
			//},
			"campaign_hook": {
				Type:     schema.TypeSet,
				Optional: true,
				Set:      campaignHookHash,
				MaxItems: 1,
				MinItems: 0,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"lambda_function_name": {
							Type:     schema.TypeString,
							Optional: true,
						},
						"mode": {
							Type:     schema.TypeString,
							Optional: true,
							ValidateFunc: validation.StringInSlice([]string{
								pinpoint.ModeDelivery,
								pinpoint.ModeFilter,
							}, false),
						},
						"web_url": {
							Type:     schema.TypeString,
							Optional: true,
						},
					},
				},
			},
			"limits": {
				Type:     schema.TypeSet,
				Optional: true,
				Set:      campaignLimitsHash,
				MaxItems: 1,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"daily": {
							Type:     schema.TypeInt,
							Optional: true,
						},
						"maximum_duration": {
							Type:     schema.TypeInt,
							Optional: true,
						},
						"messages_per_second": {
							Type:     schema.TypeInt,
							Optional: true,
						},
						"total": {
							Type:     schema.TypeInt,
							Optional: true,
						},
					},
				},
			},
			"quiet_time": {
				Type:     schema.TypeSet,
				Optional: true,
				Set:      quietTimeHash,
				MaxItems: 1,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"end": {
							Type:     schema.TypeString,
							Optional: true,
						},
						"start": {
							Type:     schema.TypeString,
							Optional: true,
						},
					},
				},
			},
		},
	}
}

func resourceAwsPinpointAppCreate(d *schema.ResourceData, meta interface{}) error {
	pinpointconn := meta.(*AWSClient).pinpointconn

	var name string
	if v, ok := d.GetOk("name"); ok {
		name = v.(string)
	} else if v, ok := d.GetOk("name_prefix"); ok {
		name = resource.PrefixedUniqueId(v.(string))
	} else {
		name = resource.UniqueId()
	}

	log.Printf("[DEBUG] Pinpoint create app: %s", name)

	req := &pinpoint.CreateAppInput{
		CreateApplicationRequest: &pinpoint.CreateApplicationRequest{
			Name: aws.String(name),
		},
	}

	output, err := pinpointconn.CreateApp(req)
	if err != nil {
		return fmt.Errorf("[ERROR] creating Pinpoint app: %s", err)
	}

	d.SetId(*output.ApplicationResponse.Id)

	return resourceAwsPinpointAppUpdate(d, meta)
}

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

	appSettings := &pinpoint.WriteApplicationSettingsRequest{}

	//if d.HasChange("cloudwatch_metrics_enabled") {
	//	appSettings.CloudWatchMetricsEnabled = aws.Bool(d.Get("cloudwatch_metrics_enabled").(bool));
	//}

	if d.HasChange("campaign_hook") {
		appSettings.CampaignHook = expandCampaignHook(d)
	}

	if d.HasChange("limits") {
		appSettings.Limits = expandCampaignLimits(d.Get("limits").(*schema.Set))
	}

	if d.HasChange("quiet_time") {
		appSettings.QuietTime = expandQuietTime(d.Get("quiet_time").(*schema.Set))
	}

	req := pinpoint.UpdateApplicationSettingsInput{
		ApplicationId:                   aws.String(d.Id()),
		WriteApplicationSettingsRequest: appSettings,
	}

	_, err := conn.UpdateApplicationSettings(&req)
	if err != nil {
		return err
	}

	return resourceAwsPinpointAppRead(d, meta)
}

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

	log.Printf("[INFO] Reading Pinpoint App Attributes for %s", d.Id())

	app, err := conn.GetApp(&pinpoint.GetAppInput{
		ApplicationId: aws.String(d.Id()),
	})
	if err != nil {
		if isAWSErr(err, pinpoint.ErrCodeNotFoundException, "") {
			log.Printf("[WARN] Pinpoint App (%s) not found, error code (404)", d.Id())
			d.SetId("")
			return nil
		}

		return err
	}

	settings, err := conn.GetApplicationSettings(&pinpoint.GetApplicationSettingsInput{
		ApplicationId: aws.String(d.Id()),
	})
	if err != nil {
		if isAWSErr(err, pinpoint.ErrCodeNotFoundException, "") {
			log.Printf("[WARN] Pinpoint App (%s) not found, error code (404)", d.Id())
			d.SetId("")
			return nil
		}

		return err
	}

	d.Set("name", app.ApplicationResponse.Name)
	d.Set("application_id", app.ApplicationResponse.Id)

	d.Set("campaign_hook", flattenCampaignHook(settings.ApplicationSettingsResource.CampaignHook))
	d.Set("limits", flattenCampaignLimits(settings.ApplicationSettingsResource.Limits))
	d.Set("quiet_time", flattenQuietTime(settings.ApplicationSettingsResource.QuietTime))

	return nil
}

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

	log.Printf("[DEBUG] Pinpoint Delete App: %s", d.Id())
	_, err := conn.DeleteApp(&pinpoint.DeleteAppInput{
		ApplicationId: aws.String(d.Id()),
	})
	if err != nil {
		return err
	}
	return nil
}

func expandCampaignHook(d *schema.ResourceData) *pinpoint.CampaignHook {
	configs := d.Get("campaign_hook").(*schema.Set).List()
	if configs == nil || len(configs) == 0 {
		return nil
	}

	m := configs[0].(map[string]interface{})

	ch := &pinpoint.CampaignHook{}

	if m["lambda_function_name"] != nil {
		ch.LambdaFunctionName = aws.String(m["lambda_function_name"].(string))
	}

	if m["mode"] != nil {
		ch.Mode = aws.String(m["mode"].(string))
	}

	if m["web_url"] != nil {
		ch.WebUrl = aws.String(m["web_url"].(string))
	}

	return ch
}

func flattenCampaignHook(ch *pinpoint.CampaignHook) []interface{} {
	l := make([]interface{}, 0)

	m := map[string]interface{}{}

	if ch.LambdaFunctionName != nil {
		m["lambda_function_name"] = *ch.LambdaFunctionName
	}

	if ch.Mode != nil && *ch.Mode != "" {
		m["mode"] = *ch.Mode
	}

	if ch.WebUrl != nil {
		m["web_url"] = *ch.WebUrl
	}

	if len(m) <= 0 {
		return nil
	}

	l = append(l, m)

	return l
}

func expandCampaignLimits(s *schema.Set) *pinpoint.CampaignLimits {
	if s == nil || s.Len() == 0 {
		return nil
	}
	m := s.List()[0].(map[string]interface{})

	cl := pinpoint.CampaignLimits{}

	if m["daily"] != nil {
		cl.Daily = aws.Int64(int64(m["daily"].(int)))
	}

	if m["maximum_duration"] != nil {
		cl.MaximumDuration = aws.Int64(int64(m["maximum_duration"].(int)))
	}

	if m["messages_per_second"] != nil {
		cl.MessagesPerSecond = aws.Int64(int64(m["messages_per_second"].(int)))
	}
	if m["total"] != nil {
		cl.Total = aws.Int64(int64(m["total"].(int)))
	}

	return &cl
}

func flattenCampaignLimits(cl *pinpoint.CampaignLimits) []interface{} {
	l := make([]interface{}, 0)

	m := map[string]interface{}{}

	if cl.Daily != nil {
		m["daily"] = *cl.Daily
	}
	if cl.MaximumDuration != nil {
		m["maximum_duration"] = *cl.MaximumDuration
	}
	if cl.MessagesPerSecond != nil {
		m["messages_per_second"] = *cl.MessagesPerSecond
	}

	if cl.Total != nil {
		m["total"] = *cl.Total
	}

	if len(m) <= 0 {
		return nil
	}

	l = append(l, m)

	return l
}

func expandQuietTime(s *schema.Set) *pinpoint.QuietTime {
	if s == nil || s.Len() == 0 {
		return nil
	}

	m := s.List()[0].(map[string]interface{})

	qt := pinpoint.QuietTime{}

	if m["end"] != nil {
		qt.End = aws.String(m["end"].(string))
	}

	if m["start"] != nil {
		qt.Start = aws.String(m["start"].(string))
	}

	return &qt
}

func flattenQuietTime(qt *pinpoint.QuietTime) []interface{} {
	l := make([]interface{}, 0)

	m := map[string]interface{}{}

	if qt.End != nil {
		m["end"] = qt.End
	}
	if qt.Start != nil {
		m["start"] = qt.Start
	}

	if len(m) <= 0 {
		return nil
	}

	l = append(l, m)

	return l
}

// Assemble the hash for the aws_pinpoint_app campaignHook
// TypeSet attribute.
func campaignHookHash(v interface{}) int {
	var buf bytes.Buffer
	m := v.(map[string]interface{})
	if v, ok := m["lambda_function_name"]; ok {
		buf.WriteString(fmt.Sprintf("%s-", v.(string)))
	}
	if v, ok := m["mode"]; ok {
		buf.WriteString(fmt.Sprintf("%s-", v.(string)))
	}
	if v, ok := m["web_url"]; ok {
		buf.WriteString(fmt.Sprintf("%s-", v.(string)))
	}
	return hashcode.String(buf.String())
}

// Assemble the hash for the aws_pinpoint_app campaignLimits
// TypeSet attribute.
func campaignLimitsHash(v interface{}) int {
	var buf bytes.Buffer
	m := v.(map[string]interface{})
	if v, ok := m["daily"]; ok {
		buf.WriteString(fmt.Sprintf("%d-", v.(int)))
	}
	if v, ok := m["maximum_duration"]; ok {
		buf.WriteString(fmt.Sprintf("%d-", v.(int)))
	}
	if v, ok := m["messages_per_second"]; ok {
		buf.WriteString(fmt.Sprintf("%d-", v.(int)))
	}
	if v, ok := m["total"]; ok {
		buf.WriteString(fmt.Sprintf("%d-", v.(int)))
	}
	return hashcode.String(buf.String())
}

// Assemble the hash for the aws_pinpoint_app quietTime
// TypeSet attribute.
func quietTimeHash(v interface{}) int {
	var buf bytes.Buffer
	m := v.(map[string]interface{})
	if v, ok := m["end"]; ok {
		buf.WriteString(fmt.Sprintf("%s-", v.(string)))
	}
	if v, ok := m["start"]; ok {
		buf.WriteString(fmt.Sprintf("%s-", v.(string)))
	}
	return hashcode.String(buf.String())
}
<commit_msg>goimports<commit_after>package aws

import (
	"fmt"
	"log"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/pinpoint"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/validation"
)

func resourceAwsPinpointApp() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsPinpointAppCreate,
		Read:   resourceAwsPinpointAppRead,
		Update: resourceAwsPinpointAppUpdate,
		Delete: resourceAwsPinpointAppDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"name": {
				Type:          schema.TypeString,
				Optional:      true,
				Computed:      true,
				ForceNew:      true,
				ConflictsWith: []string{"name_prefix"},
			},
			"name_prefix": {
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
			},
			"application_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			//"cloudwatch_metrics_enabled": {
			//	Type:     schema.TypeBool,
			//	Optional: true,
			//	Default:  false,
			//},
			"campaign_hook": {
				Type:     schema.TypeSet,
				Optional: true,
				Set:      campaignHookHash,
				MaxItems: 1,
				MinItems: 0,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"lambda_function_name": {
							Type:     schema.TypeString,
							Optional: true,
						},
						"mode": {
							Type:     schema.TypeString,
							Optional: true,
							ValidateFunc: validation.StringInSlice([]string{
								pinpoint.ModeDelivery,
								pinpoint.ModeFilter,
							}, false),
						},
						"web_url": {
							Type:     schema.TypeString,
							Optional: true,
						},
					},
				},
			},
			"limits": {
				Type:     schema.TypeSet,
				Optional: true,
				Set:      campaignLimitsHash,
				MaxItems: 1,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"daily": {
							Type:     schema.TypeInt,
							Optional: true,
						},
						"maximum_duration": {
							Type:     schema.TypeInt,
							Optional: true,
						},
						"messages_per_second": {
							Type:     schema.TypeInt,
							Optional: true,
						},
						"total": {
							Type:     schema.TypeInt,
							Optional: true,
						},
					},
				},
			},
			"quiet_time": {
				Type:     schema.TypeSet,
				Optional: true,
				Set:      quietTimeHash,
				MaxItems: 1,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"end": {
							Type:     schema.TypeString,
							Optional: true,
						},
						"start": {
							Type:     schema.TypeString,
							Optional: true,
						},
					},
				},
			},
		},
	}
}

func resourceAwsPinpointAppCreate(d *schema.ResourceData, meta interface{}) error {
	pinpointconn := meta.(*AWSClient).pinpointconn

	var name string
	if v, ok := d.GetOk("name"); ok {
		name = v.(string)
	} else if v, ok := d.GetOk("name_prefix"); ok {
		name = resource.PrefixedUniqueId(v.(string))
	} else {
		name = resource.UniqueId()
	}

	log.Printf("[DEBUG] Pinpoint create app: %s", name)

	req := &pinpoint.CreateAppInput{
		CreateApplicationRequest: &pinpoint.CreateApplicationRequest{
			Name: aws.String(name),
		},
	}

	output, err := pinpointconn.CreateApp(req)
	if err != nil {
		return fmt.Errorf("[ERROR] creating Pinpoint app: %s", err)
	}

	d.SetId(*output.ApplicationResponse.Id)

	return resourceAwsPinpointAppUpdate(d, meta)
}

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

	appSettings := &pinpoint.WriteApplicationSettingsRequest{}

	//if d.HasChange("cloudwatch_metrics_enabled") {
	//	appSettings.CloudWatchMetricsEnabled = aws.Bool(d.Get("cloudwatch_metrics_enabled").(bool));
	//}

	if d.HasChange("campaign_hook") {
		appSettings.CampaignHook = expandCampaignHook(d)
	}

	if d.HasChange("limits") {
		appSettings.Limits = expandCampaignLimits(d.Get("limits").(*schema.Set))
	}

	if d.HasChange("quiet_time") {
		appSettings.QuietTime = expandQuietTime(d.Get("quiet_time").(*schema.Set))
	}

	req := pinpoint.UpdateApplicationSettingsInput{
		ApplicationId:                   aws.String(d.Id()),
		WriteApplicationSettingsRequest: appSettings,
	}

	_, err := conn.UpdateApplicationSettings(&req)
	if err != nil {
		return err
	}

	return resourceAwsPinpointAppRead(d, meta)
}

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

	log.Printf("[INFO] Reading Pinpoint App Attributes for %s", d.Id())

	app, err := conn.GetApp(&pinpoint.GetAppInput{
		ApplicationId: aws.String(d.Id()),
	})
	if err != nil {
		if isAWSErr(err, pinpoint.ErrCodeNotFoundException, "") {
			log.Printf("[WARN] Pinpoint App (%s) not found, error code (404)", d.Id())
			d.SetId("")
			return nil
		}

		return err
	}

	settings, err := conn.GetApplicationSettings(&pinpoint.GetApplicationSettingsInput{
		ApplicationId: aws.String(d.Id()),
	})
	if err != nil {
		if isAWSErr(err, pinpoint.ErrCodeNotFoundException, "") {
			log.Printf("[WARN] Pinpoint App (%s) not found, error code (404)", d.Id())
			d.SetId("")
			return nil
		}

		return err
	}

	d.Set("name", app.ApplicationResponse.Name)
	d.Set("application_id", app.ApplicationResponse.Id)

	d.Set("campaign_hook", flattenCampaignHook(settings.ApplicationSettingsResource.CampaignHook))
	d.Set("limits", flattenCampaignLimits(settings.ApplicationSettingsResource.Limits))
	d.Set("quiet_time", flattenQuietTime(settings.ApplicationSettingsResource.QuietTime))

	return nil
}

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

	log.Printf("[DEBUG] Pinpoint Delete App: %s", d.Id())
	_, err := conn.DeleteApp(&pinpoint.DeleteAppInput{
		ApplicationId: aws.String(d.Id()),
	})
	if err != nil {
		return err
	}
	return nil
}

func expandCampaignHook(d *schema.ResourceData) *pinpoint.CampaignHook {
	configs := d.Get("campaign_hook").(*schema.Set).List()
	if configs == nil || len(configs) == 0 {
		return nil
	}

	m := configs[0].(map[string]interface{})

	ch := &pinpoint.CampaignHook{}

	if m["lambda_function_name"] != nil {
		ch.LambdaFunctionName = aws.String(m["lambda_function_name"].(string))
	}

	if m["mode"] != nil {
		ch.Mode = aws.String(m["mode"].(string))
	}

	if m["web_url"] != nil {
		ch.WebUrl = aws.String(m["web_url"].(string))
	}

	return ch
}

func flattenCampaignHook(ch *pinpoint.CampaignHook) []interface{} {
	l := make([]interface{}, 0)

	m := map[string]interface{}{}

	if ch.LambdaFunctionName != nil {
		m["lambda_function_name"] = *ch.LambdaFunctionName
	}

	if ch.Mode != nil && *ch.Mode != "" {
		m["mode"] = *ch.Mode
	}

	if ch.WebUrl != nil {
		m["web_url"] = *ch.WebUrl
	}

	if len(m) <= 0 {
		return nil
	}

	l = append(l, m)

	return l
}

func expandCampaignLimits(s *schema.Set) *pinpoint.CampaignLimits {
	if s == nil || s.Len() == 0 {
		return nil
	}
	m := s.List()[0].(map[string]interface{})

	cl := pinpoint.CampaignLimits{}

	if m["daily"] != nil {
		cl.Daily = aws.Int64(int64(m["daily"].(int)))
	}

	if m["maximum_duration"] != nil {
		cl.MaximumDuration = aws.Int64(int64(m["maximum_duration"].(int)))
	}

	if m["messages_per_second"] != nil {
		cl.MessagesPerSecond = aws.Int64(int64(m["messages_per_second"].(int)))
	}
	if m["total"] != nil {
		cl.Total = aws.Int64(int64(m["total"].(int)))
	}

	return &cl
}

func flattenCampaignLimits(cl *pinpoint.CampaignLimits) []interface{} {
	l := make([]interface{}, 0)

	m := map[string]interface{}{}

	if cl.Daily != nil {
		m["daily"] = *cl.Daily
	}
	if cl.MaximumDuration != nil {
		m["maximum_duration"] = *cl.MaximumDuration
	}
	if cl.MessagesPerSecond != nil {
		m["messages_per_second"] = *cl.MessagesPerSecond
	}

	if cl.Total != nil {
		m["total"] = *cl.Total
	}

	if len(m) <= 0 {
		return nil
	}

	l = append(l, m)

	return l
}

func expandQuietTime(s *schema.Set) *pinpoint.QuietTime {
	if s == nil || s.Len() == 0 {
		return nil
	}

	m := s.List()[0].(map[string]interface{})

	qt := pinpoint.QuietTime{}

	if m["end"] != nil {
		qt.End = aws.String(m["end"].(string))
	}

	if m["start"] != nil {
		qt.Start = aws.String(m["start"].(string))
	}

	return &qt
}

func flattenQuietTime(qt *pinpoint.QuietTime) []interface{} {
	l := make([]interface{}, 0)

	m := map[string]interface{}{}

	if qt.End != nil {
		m["end"] = qt.End
	}
	if qt.Start != nil {
		m["start"] = qt.Start
	}

	if len(m) <= 0 {
		return nil
	}

	l = append(l, m)

	return l
}

// Assemble the hash for the aws_pinpoint_app campaignHook
// TypeSet attribute.
func campaignHookHash(v interface{}) int {
	var buf bytes.Buffer
	m := v.(map[string]interface{})
	if v, ok := m["lambda_function_name"]; ok {
		buf.WriteString(fmt.Sprintf("%s-", v.(string)))
	}
	if v, ok := m["mode"]; ok {
		buf.WriteString(fmt.Sprintf("%s-", v.(string)))
	}
	if v, ok := m["web_url"]; ok {
		buf.WriteString(fmt.Sprintf("%s-", v.(string)))
	}
	return hashcode.String(buf.String())
}

// Assemble the hash for the aws_pinpoint_app campaignLimits
// TypeSet attribute.
func campaignLimitsHash(v interface{}) int {
	var buf bytes.Buffer
	m := v.(map[string]interface{})
	if v, ok := m["daily"]; ok {
		buf.WriteString(fmt.Sprintf("%d-", v.(int)))
	}
	if v, ok := m["maximum_duration"]; ok {
		buf.WriteString(fmt.Sprintf("%d-", v.(int)))
	}
	if v, ok := m["messages_per_second"]; ok {
		buf.WriteString(fmt.Sprintf("%d-", v.(int)))
	}
	if v, ok := m["total"]; ok {
		buf.WriteString(fmt.Sprintf("%d-", v.(int)))
	}
	return hashcode.String(buf.String())
}

// Assemble the hash for the aws_pinpoint_app quietTime
// TypeSet attribute.
func quietTimeHash(v interface{}) int {
	var buf bytes.Buffer
	m := v.(map[string]interface{})
	if v, ok := m["end"]; ok {
		buf.WriteString(fmt.Sprintf("%s-", v.(string)))
	}
	if v, ok := m["start"]; ok {
		buf.WriteString(fmt.Sprintf("%s-", v.(string)))
	}
	return hashcode.String(buf.String())
}
<|endoftext|>