<commit_before>// 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 main

import (
	"fmt"
	"log"
	"net/http"
	"os"

	"github.com/kkdai/luis"
	"github.com/line/line-bot-sdk-go/linebot"
)

var bot *linebot.Client
var luisAction *LuisAction
var allIntents *luis.IntentListResponse

func main() {
	var err error
	appID := os.Getenv("APP_ID")
	apiKey := os.Getenv("APP_KEY")
	log.Println("Luis:", appID, apiKey)
	luisAction = NewLuisAction(appID, apiKey)

	bot, err = linebot.New(os.Getenv("ChannelSecret"), os.Getenv("ChannelAccessToken"))
	log.Println("Bot:", bot, " err:", err)
	http.HandleFunc("/callback", callbackHandler)
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
}

func callbackHandler(w http.ResponseWriter, r *http.Request) {
	events, err := bot.ParseRequest(r)

	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}

	for _, event := range events {
		if event.Type == linebot.EventTypeMessage {
			switch message := event.Message.(type) {
			case *linebot.TextMessage:
				ret := luisAction.Predict(message.Text)
				if ret == "None" || ret == "" {

					res, err := luisAction.GetIntents()
					if err != nil {
						log.Println(err)
						return
					}
					var intentList []string
					log.Println("All intent:", *res)
					for _, v := range *res {
						if v.Name != "None" {
							intentList = append(intentList, v.Name)
						}
					}

					ListAllIntents(bot, event.ReplyToken, intentList, message.Text)

				} else {
					if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(fmt.Sprintf("Hi Dady/Mam: I just want to :%s", ret))).Do(); err != nil {
						log.Print(err)
					}
				}
			}
		}
	}
}

//ListAllIntents :
func ListAllIntents(bot *linebot.Client, replyToken string, intents []string, utterance string) {

	// var buttons []linebot.TemplateAction

	askStmt := fmt.Sprintf("Your utterance %s is not exist, please select correct intent.", utterance)
	log.Println("askStmt:", askStmt)

	// template := linebot.NewButtonsTemplate("", "Please select your intent of your word", "test",
	template := linebot.NewButtonsTemplate("", "Select your intent", "test",
		linebot.NewPostbackTemplateAction(intents[0], intents[0], ""),
		linebot.NewPostbackTemplateAction(intents[1], intents[1], ""),
		linebot.NewPostbackTemplateAction(intents[2], intents[2], ""),
		linebot.NewPostbackTemplateAction(intents[3], intents[3], ""))

	//	if _, err := bot.ReplyMessage(replyToken, linebot.NewTemplateMessage("test....", template)).Do(); err != nil {
	if _, err := bot.ReplyMessage(
		replyToken,
		linebot.NewTemplateMessage("Select your intent", template)).Do(); err != nil {
		log.Print(err)
	}
}
<commit_msg>no message<commit_after>// 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 main

import (
	"fmt"
	"log"
	"net/http"
	"os"

	"github.com/kkdai/luis"
	"github.com/line/line-bot-sdk-go/linebot"
)

var bot *linebot.Client
var luisAction *LuisAction
var allIntents *luis.IntentListResponse
var currentUtterance string

func main() {
	var err error
	appID := os.Getenv("APP_ID")
	apiKey := os.Getenv("APP_KEY")
	log.Println("Luis:", appID, apiKey)
	luisAction = NewLuisAction(appID, apiKey)

	bot, err = linebot.New(os.Getenv("ChannelSecret"), os.Getenv("ChannelAccessToken"))
	log.Println("Bot:", bot, " err:", err)
	http.HandleFunc("/callback", callbackHandler)
	port := os.Getenv("PORT")
	addr := fmt.Sprintf(":%s", port)
	http.ListenAndServe(addr, nil)
}

func callbackHandler(w http.ResponseWriter, r *http.Request) {
	events, err := bot.ParseRequest(r)

	if err != nil {
		if err == linebot.ErrInvalidSignature {
			w.WriteHeader(400)
		} else {
			w.WriteHeader(500)
		}
		return
	}

	for _, event := range events {
		if event.Type == linebot.EventTypeMessage {
			switch message := event.Message.(type) {
			case *linebot.TextMessage:
				ret := luisAction.Predict(message.Text)
				if ret == "None" || ret == "" {

					res, err := luisAction.GetIntents()
					if err != nil {
						log.Println(err)
						return
					}
					var intentList []string
					log.Println("All intent:", *res)
					for _, v := range *res {
						if v.Name != "None" {
							intentList = append(intentList, v.Name)
						}
					}
					//List all intents
					ListAllIntents(bot, event.ReplyToken, intentList, message.Text)

				} else {
					if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(fmt.Sprintf("Hi Dady/Mam: I just want to :%s", ret))).Do(); err != nil {
						log.Print(err)
					}
				}
			}
		} else if event.Type == linebot.EventTypePostback {
			//Add new utterance into original intent
			luisAction.AddUtterance(event.Postback.Data, currentUtterance)
			retStr := fmt.Sprintf("Your intent: %s already add new utterance :%s", event.Postback.Data, currentUtterance)
			if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(retStr)).Do(); err != nil {
				log.Print(err)
			}
		}
	}
}

//ListAllIntents :
func ListAllIntents(bot *linebot.Client, replyToken string, intents []string, utterance string) {
	askStmt := fmt.Sprintf("Your utterance %s is not exist, please select correct intent.", utterance)
	log.Println("askStmt:", askStmt)

	template := linebot.NewButtonsTemplate("", "Select your intent", utterance,
		linebot.NewPostbackTemplateAction(intents[0], intents[0], ""),
		linebot.NewPostbackTemplateAction(intents[1], intents[1], ""),
		linebot.NewPostbackTemplateAction(intents[2], intents[2], ""),
		linebot.NewPostbackTemplateAction(intents[3], intents[3], ""))

	//	if _, err := bot.ReplyMessage(replyToken, linebot.NewTemplateMessage("test....", template)).Do(); err != nil {
	if _, err := bot.ReplyMessage(
		replyToken,
		linebot.NewTemplateMessage("Select your intent", template)).Do(); err != nil {
		log.Print(err)
	}
	currentUtterance = utterance
}
<|endoftext|>


<commit_before>// Copyright 2013 Google Inc. All Rights Reserved.
//
// 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 main

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

	"github.com/rakyll/drivefuse/blob"
	"github.com/rakyll/drivefuse/config"
	"github.com/rakyll/drivefuse/fileio"
	"github.com/rakyll/drivefuse/logger"
	"github.com/rakyll/drivefuse/metadata"
	"github.com/rakyll/drivefuse/mount"
	"github.com/rakyll/drivefuse/syncer"
	client "github.com/rakyll/drivefuse/third_party/code.google.com/p/google-api-go-client/drive/v2"
)

var (
	flagDataPath   = flag.String("datapath", "", "path of the data directory")
	flagMountPoint = flag.String("mountpoint", "", "mount point")
	flagBlockSync  = flag.Bool("blocksync", false, "set true to force blocking sync on startup")

	metaService  *metadata.MetaService
	driveService *client.Service
	blobManager  *blob.Manager
)

func main() {
	flag.Parse()

	shutdownChan := make(chan io.Closer, 1)
	go gracefullyShutDown(shutdownChan)

	cfg, err := config.New(*flagDataPath)
	if err != nil {
		logger.F("Error while reading and initializing configuration:", err)
	}

	transport := cfg.GetDefaultTransport()

	metaService, _ = metadata.New(cfg.GetMetadataPath())
	driveService, _ = client.New(transport.Client())
	blobManager = blob.New(cfg.GetBlobPath())

	downloader := fileio.NewDownloader(
		transport.Client(),
		metaService,
		blobManager)

	syncManager := syncer.NewCachedSyncer(
		driveService,
		metaService,
		blobManager)

	if *flagBlockSync {
		syncManager.Sync(true)
	}
	syncManager.Start()

	logger.V("mounting...")
	if err = mount.MountAndServe(*flagMountPoint, metaService, blobManager, downloader); err != nil {
		logger.F(err)
	}
}

func gracefulShutDown(shutdownc <-chan io.Closer) {
	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGHUP)
	signal.Notify(c, syscall.SIGINT)
	for {
		sig := <-c
		sig, ok := sig.(syscall.Signal)
		if !ok {
			// ignore non-unix signals
			return
		}
		switch sig {
		case syscall.SIGINT:
			logger.V("Gracefully shutting down...")
			mount.Umount(*flagMountPoint)
			// TODO(burcud): Handle Umount errors
			go func() {
				<-time.After(3 * time.Second)
				logger.V("Couldn't umount, do it manually, now shutting down...")
				os.Exit(0)
			}()
		}
	}
}
<commit_msg>Fix broken build.<commit_after>// Copyright 2013 Google Inc. All Rights Reserved.
//
// 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 main

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

	"github.com/rakyll/drivefuse/blob"
	"github.com/rakyll/drivefuse/config"
	"github.com/rakyll/drivefuse/fileio"
	"github.com/rakyll/drivefuse/logger"
	"github.com/rakyll/drivefuse/metadata"
	"github.com/rakyll/drivefuse/mount"
	"github.com/rakyll/drivefuse/syncer"
	client "github.com/rakyll/drivefuse/third_party/code.google.com/p/google-api-go-client/drive/v2"
)

var (
	flagDataPath   = flag.String("datapath", "", "path of the data directory")
	flagMountPoint = flag.String("mountpoint", "", "mount point")
	flagBlockSync  = flag.Bool("blocksync", false, "set true to force blocking sync on startup")

	metaService  *metadata.MetaService
	driveService *client.Service
	blobManager  *blob.Manager
)

func main() {
	flag.Parse()

	shutdownChan := make(chan io.Closer, 1)
	go gracefulShutDown(shutdownChan)

	cfg, err := config.New(*flagDataPath)
	if err != nil {
		logger.F("Error while reading and initializing configuration:", err)
	}

	transport := cfg.GetDefaultTransport()

	metaService, _ = metadata.New(cfg.GetMetadataPath())
	driveService, _ = client.New(transport.Client())
	blobManager = blob.New(cfg.GetBlobPath())

	downloader := fileio.NewDownloader(
		transport.Client(),
		metaService,
		blobManager)

	syncManager := syncer.NewCachedSyncer(
		driveService,
		metaService,
		blobManager)

	if *flagBlockSync {
		syncManager.Sync(true)
	}
	syncManager.Start()

	logger.V("mounting...")
	if err = mount.MountAndServe(*flagMountPoint, metaService, blobManager, downloader); err != nil {
		logger.F(err)
	}
}

func gracefulShutDown(shutdownc <-chan io.Closer) {
	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGHUP)
	signal.Notify(c, syscall.SIGINT)
	for {
		sig := <-c
		sig, ok := sig.(syscall.Signal)
		if !ok {
			// ignore non-unix signals
			return
		}
		switch sig {
		case syscall.SIGINT:
			logger.V("Gracefully shutting down...")
			mount.Umount(*flagMountPoint)
			// TODO(burcud): Handle Umount errors
			go func() {
				<-time.After(3 * time.Second)
				logger.V("Couldn't umount, do it manually, now shutting down...")
				os.Exit(0)
			}()
		}
	}
}
<|endoftext|>


<commit_before>// Enhanced Markdown template processor.
package main

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

	"github.com/mh-cbon/emd/cli"
	"github.com/mh-cbon/emd/deprecated"
	"github.com/mh-cbon/emd/emd"
	gostd "github.com/mh-cbon/emd/go"
	gononstd "github.com/mh-cbon/emd/go-nonstd"
	"github.com/mh-cbon/emd/provider"
	"github.com/mh-cbon/emd/std"
)

// VERSION defines the running build id.
var VERSION = "0.0.0"

var program = cli.NewProgram("emd", VERSION)

var verbose bool

func logMsg(f string, args ...interface{}) {
	if verbose {
		log.Printf(f+"\n", args...)
	}
}

func main() {
	program.Bind()
	if err := program.Run(os.Args); err != nil {
		log.Println(err)
		os.Exit(1)
	}
}

// gen sub command
type gencommand struct {
	*cli.Command
	in        string
	out       string
	data      string
	help      bool
	shortHelp bool
}

// init sub command
type initcommand struct {
	*cli.Command
	help      bool
	shortHelp bool
	out       string
	force     bool
}

func init() {
	gen := &gencommand{Command: cli.NewCommand("gen", "Process an emd file.", Generate)}
	gen.Set.StringVar(&gen.in, "in", "", "Input src file")
	gen.Set.StringVar(&gen.out, "out", "-", "Output destination, defaults to stdout")
	gen.Set.StringVar(&gen.data, "data", "", "JSON map of data")
	gen.Set.BoolVar(&gen.help, "help", false, "Show help")
	gen.Set.BoolVar(&gen.shortHelp, "h", false, "Show help")
	program.Add(gen)

	ini := &initcommand{Command: cli.NewCommand("init", "Init a basic emd file.", InitFile)}
	ini.Set.BoolVar(&ini.help, "help", false, "Show help")
	ini.Set.BoolVar(&ini.shortHelp, "h", false, "Show help")
	ini.Set.BoolVar(&ini.force, "force", false, "Force write")
	ini.Set.StringVar(&ini.out, "out", "README.e.md", "Out file")
	program.Add(ini)

	verbose = os.Getenv("VERBOSE") != ""
}

// Generate is the cli command implementation of gen.
func Generate(s cli.Commander) error {

	cmd, ok := s.(*gencommand)
	if ok == false {
		return fmt.Errorf("Invalid command type %T", s)
	}

	if cmd.help || cmd.shortHelp {
		return program.ShowCmdUsage(cmd)
	}

	out, err := getStdout(cmd.out)
	if err != nil {
		return err
	}
	if x, ok := out.(io.Closer); ok {
		defer x.Close()
	}

	cwd, err := os.Getwd()
	if err != nil {
		return err
	}
	logMsg("cwd %q", cwd)

	gopath := filepath.Join(os.Getenv("GOPATH"), "src")
	gopath = strings.Replace(gopath, "\\", "/", -1)

	if len(cwd) > len(gopath) && cwd[:len(gopath)] != gopath {
		cwd, err = filepath.EvalSymlinks(cwd)
		if err != nil {
			return err
		}
		if cwd[:len(gopath)] != gopath {
			return fmt.Errorf("Invalid working directory %q", cwd)
		}
	}

	projectPath := cwd[len(gopath):]
	logMsg("projectPath %q", projectPath)

	plugins := getPlugins()
	data, err := getData(projectPath)
	if err != nil {
		return err
	}

	if cmd.data != "" {
		if err := json.Unmarshal([]byte(cmd.data), &data); err != nil {
			return fmt.Errorf("Cannot decode JSON data string: %v", err)
		}
	}

	gen := emd.NewGenerator()

	gen.SetDataMap(data)

	if cmd.in != "" {
		if err := gen.AddFileTemplate(cmd.in); err != nil {
			return err
		}
	} else if s, err := os.Stat("README.e.md"); !os.IsNotExist(err) && s.IsDir() == false {
		if err := gen.AddFileTemplate("README.e.md"); err != nil {
			return err
		}
	} else {
		var b bytes.Buffer
		io.Copy(&b, os.Stdin)
		if b.Len() > 0 {
			gen.AddTemplate(b.String())
		} else {
			gen.AddTemplate(defTemplate)
		}
	}

	for name, plugin := range plugins {
		if err := plugin(gen); err != nil {
			return fmt.Errorf("Failed to register %v package: %v", name, err)
		}
	}

	if err := gen.Execute(out); err != nil {
		return fmt.Errorf("Generator failed: %v", err)
	}

	return nil
}

func getData(cwd string) (map[string]interface{}, error) {
	p := provider.Default(cwd)
	if p.Match() == false {
		return nil, fmt.Errorf("Failed to identify this path %q\n", cwd)
	}
	return map[string]interface{}{
		"Name":         p.GetProjectName(),
		"User":         p.GetUserName(),
		"ProviderURL":  p.GetProviderURL(),
		"ProviderName": p.GetProviderID(),
		"URL":          p.GetURL(),
		"ProjectURL":   p.GetProjectURL(),
		"Branch":       "master",
	}, nil
}

func getPlugins() map[string]func(*emd.Generator) error {
	return map[string]func(*emd.Generator) error{
		"std":        std.Register,
		"gostd":      gostd.Register,
		"gononstd":   gononstd.Register,
		"deprecated": deprecated.Register,
	}
}

func getStdout(out string) (io.Writer, error) {

	ret := os.Stdout

	if out != "-" {
		f, err := os.Create(out)
		if err != nil {
			f, err = os.Open(out)
			if err != nil {
				return nil, fmt.Errorf("Cannot open out destination: %v", err)
			}
		}
		ret = f
	}
	return ret, nil
}

// InitFile creates a basic emd file if none exits.
func InitFile(s cli.Commander) error {

	cmd, ok := s.(*initcommand)
	if ok == false {
		return fmt.Errorf("Invalid command type %T", s)
	}

	if cmd.help || cmd.shortHelp {
		return program.ShowCmdUsage(cmd)
	}

	out := cmd.out
	if cmd.out == "" {
		out = "README.e.md"
	}
	if _, err := os.Stat(out); !cmd.force && !os.IsNotExist(err) {
		return fmt.Errorf("File exits at %q", out)
	}
	return ioutil.WriteFile(out, []byte(defTemplate), os.ModePerm)
}

var defTemplate = `# {{.Name}}

{{template "badge/goreport" .}} {{template "badge/godoc" .}}

{{pkgdoc}}

# {{toc 5}}

# Install

{{template "gh/releases" .}}

#### go
{{template "go/install" .}}
`
<commit_msg>fix out of range err<commit_after>// Enhanced Markdown template processor.
package main

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

	"github.com/mh-cbon/emd/cli"
	"github.com/mh-cbon/emd/deprecated"
	"github.com/mh-cbon/emd/emd"
	gostd "github.com/mh-cbon/emd/go"
	gononstd "github.com/mh-cbon/emd/go-nonstd"
	"github.com/mh-cbon/emd/provider"
	"github.com/mh-cbon/emd/std"
)

// VERSION defines the running build id.
var VERSION = "0.0.0"

var program = cli.NewProgram("emd", VERSION)

var verbose bool

func logMsg(f string, args ...interface{}) {
	if verbose {
		log.Printf(f+"\n", args...)
	}
}

func main() {
	program.Bind()
	if err := program.Run(os.Args); err != nil {
		log.Println(err)
		os.Exit(1)
	}
}

// gen sub command
type gencommand struct {
	*cli.Command
	in        string
	out       string
	data      string
	help      bool
	shortHelp bool
}

// init sub command
type initcommand struct {
	*cli.Command
	help      bool
	shortHelp bool
	out       string
	force     bool
}

func init() {
	gen := &gencommand{Command: cli.NewCommand("gen", "Process an emd file.", Generate)}
	gen.Set.StringVar(&gen.in, "in", "", "Input src file")
	gen.Set.StringVar(&gen.out, "out", "-", "Output destination, defaults to stdout")
	gen.Set.StringVar(&gen.data, "data", "", "JSON map of data")
	gen.Set.BoolVar(&gen.help, "help", false, "Show help")
	gen.Set.BoolVar(&gen.shortHelp, "h", false, "Show help")
	program.Add(gen)

	ini := &initcommand{Command: cli.NewCommand("init", "Init a basic emd file.", InitFile)}
	ini.Set.BoolVar(&ini.help, "help", false, "Show help")
	ini.Set.BoolVar(&ini.shortHelp, "h", false, "Show help")
	ini.Set.BoolVar(&ini.force, "force", false, "Force write")
	ini.Set.StringVar(&ini.out, "out", "README.e.md", "Out file")
	program.Add(ini)

	verbose = os.Getenv("VERBOSE") != ""
}

// Generate is the cli command implementation of gen.
func Generate(s cli.Commander) error {

	cmd, ok := s.(*gencommand)
	if ok == false {
		return fmt.Errorf("Invalid command type %T", s)
	}

	if cmd.help || cmd.shortHelp {
		return program.ShowCmdUsage(cmd)
	}

	out, err := getStdout(cmd.out)
	if err != nil {
		return err
	}
	if x, ok := out.(io.Closer); ok {
		defer x.Close()
	}

	cwd, err := os.Getwd()
	if err != nil {
		return err
	}
	logMsg("cwd %q", cwd)

	gopath := filepath.Join(os.Getenv("GOPATH"), "src")
	gopath = strings.Replace(gopath, "\\", "/", -1)
	logMsg("gopath %q", gopath)

	if !strings.HasPrefix(cwd, gopath) {
		cwd, err = filepath.EvalSymlinks(cwd)
		if err != nil {
			return err
		}
	}
	if !strings.HasPrefix(cwd, gopath) {
		return fmt.Errorf("Invalid working directory %q", cwd)
	}
	logMsg("cwd %q", cwd)

	projectPath := cwd[len(gopath):]
	logMsg("projectPath %q", projectPath)

	plugins := getPlugins()
	data, err := getData(projectPath)
	if err != nil {
		return err
	}

	if cmd.data != "" {
		if err := json.Unmarshal([]byte(cmd.data), &data); err != nil {
			return fmt.Errorf("Cannot decode JSON data string: %v", err)
		}
	}

	gen := emd.NewGenerator()

	gen.SetDataMap(data)

	if cmd.in != "" {
		if err := gen.AddFileTemplate(cmd.in); err != nil {
			return err
		}
	} else if s, err := os.Stat("README.e.md"); !os.IsNotExist(err) && s.IsDir() == false {
		if err := gen.AddFileTemplate("README.e.md"); err != nil {
			return err
		}
	} else {
		var b bytes.Buffer
		io.Copy(&b, os.Stdin)
		if b.Len() > 0 {
			gen.AddTemplate(b.String())
		} else {
			gen.AddTemplate(defTemplate)
		}
	}

	for name, plugin := range plugins {
		if err := plugin(gen); err != nil {
			return fmt.Errorf("Failed to register %v package: %v", name, err)
		}
	}

	if err := gen.Execute(out); err != nil {
		return fmt.Errorf("Generator failed: %v", err)
	}

	return nil
}

func getData(cwd string) (map[string]interface{}, error) {
	p := provider.Default(cwd)
	if p.Match() == false {
		return nil, fmt.Errorf("Failed to identify this path %q\n", cwd)
	}
	return map[string]interface{}{
		"Name":         p.GetProjectName(),
		"User":         p.GetUserName(),
		"ProviderURL":  p.GetProviderURL(),
		"ProviderName": p.GetProviderID(),
		"URL":          p.GetURL(),
		"ProjectURL":   p.GetProjectURL(),
		"Branch":       "master",
	}, nil
}

func getPlugins() map[string]func(*emd.Generator) error {
	return map[string]func(*emd.Generator) error{
		"std":        std.Register,
		"gostd":      gostd.Register,
		"gononstd":   gononstd.Register,
		"deprecated": deprecated.Register,
	}
}

func getStdout(out string) (io.Writer, error) {

	ret := os.Stdout

	if out != "-" {
		f, err := os.Create(out)
		if err != nil {
			f, err = os.Open(out)
			if err != nil {
				return nil, fmt.Errorf("Cannot open out destination: %v", err)
			}
		}
		ret = f
	}
	return ret, nil
}

// InitFile creates a basic emd file if none exits.
func InitFile(s cli.Commander) error {

	cmd, ok := s.(*initcommand)
	if ok == false {
		return fmt.Errorf("Invalid command type %T", s)
	}

	if cmd.help || cmd.shortHelp {
		return program.ShowCmdUsage(cmd)
	}

	out := cmd.out
	if cmd.out == "" {
		out = "README.e.md"
	}
	if _, err := os.Stat(out); !cmd.force && !os.IsNotExist(err) {
		return fmt.Errorf("File exits at %q", out)
	}
	return ioutil.WriteFile(out, []byte(defTemplate), os.ModePerm)
}

var defTemplate = `# {{.Name}}

{{template "badge/goreport" .}} {{template "badge/godoc" .}}

{{pkgdoc}}

# {{toc 5}}

# Install

{{template "gh/releases" .}}

#### go
{{template "go/install" .}}
`
<|endoftext|>


<commit_before>package main

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

	"github.com/pborman/uuid"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/client/restclient"
	"k8s.io/kubernetes/pkg/client/unversioned"
	"k8s.io/kubernetes/pkg/util/intstr"
)

var masterHost string

func init() {
	flag.StringVar(&masterHost, "master", "http://127.0.0.1:8080", "usage")
	flag.Parse()
}

type etcdClusterController struct {
	kclient *unversioned.Client
}

func (c *etcdClusterController) Run() {
	eventCh, errCh := monitorNewCluster()
	for {
		select {
		case event := <-eventCh:
			c.createCluster(event)
		case err := <-errCh:
			panic(err)
		}
	}
}

func (c *etcdClusterController) createCluster(event newCluster) {
	size := event.Size
	uuid := generateUUID()

	initialCluster := []string{}
	for i := 0; i < size; i++ {
		initialCluster = append(initialCluster, fmt.Sprintf("etcd%d-%s=http://etcd%d-%s:2380", i, uuid, i, uuid))
	}

	for i := 0; i < size; i++ {
		etcdName := fmt.Sprintf("etcd%d-%s", i, uuid)

		svc := makeEtcdService(etcdName, uuid)
		_, err := c.kclient.Services("default").Create(svc)
		if err != nil {
			panic(err)
		}
		// TODO: add and expose client port
		pod := makeEtcdPod(etcdName, uuid, initialCluster)
		_, err = c.kclient.Pods("default").Create(pod)
		if err != nil {
			panic(err)
		}
	}
}

type newCluster struct {
	Kind       string            `json:"kind"`
	ApiVersion string            `json:"apiVersion"`
	Metadata   map[string]string `json:"metadata"`
	Size       int               `json:"size"`
}

type Event struct {
	Type   string
	Object newCluster
}

func monitorNewCluster() (<-chan newCluster, <-chan error) {
	events := make(chan newCluster)
	errc := make(chan error, 1)
	go func() {
		resp, err := http.Get(masterHost + "/apis/coreos.com/v1/namespaces/default/etcdclusters?watch=true")
		if err != nil {
			errc <- err
			return
		}
		if resp.StatusCode != 200 {
			errc <- errors.New("Invalid status code: " + resp.Status)
			return
		}
		log.Println("start watching...")
		for {
			decoder := json.NewDecoder(resp.Body)
			var ev Event
			err = decoder.Decode(&ev)
			if err != nil {
				errc <- err
			}
			event := ev.Object
			log.Println("new cluster size:", event.Size)
			events <- event
		}
	}()

	return events, errc
}

func main() {
	c := &etcdClusterController{
		kclient: mustCreateClient(masterHost),
	}
	log.Println("etcd cluster controller starts running...")
	c.Run()
}

func mustCreateClient(host string) *unversioned.Client {
	cfg := &restclient.Config{
		Host:  host,
		QPS:   100,
		Burst: 100,
	}
	c, err := unversioned.New(cfg)
	if err != nil {
		panic(err)
	}
	return c
}

func generateUUID() string {
	return uuid.New()
}

func makeEtcdService(etcdName, uuid string) *api.Service {
	labels := map[string]string{
		"etcd_node": etcdName,
		"etcd_uuid": uuid,
	}
	svc := &api.Service{
		ObjectMeta: api.ObjectMeta{
			Name:   etcdName,
			Labels: labels,
		},
		Spec: api.ServiceSpec{
			Ports: []api.ServicePort{{
				Name:       "server",
				Port:       2380,
				TargetPort: intstr.FromInt(2380),
				Protocol:   api.ProtocolTCP,
			}},
			Selector: labels,
		},
	}
	return svc
}

func makeEtcdPod(etcdName, uuid string, initialCluster []string) *api.Pod {
	pod := &api.Pod{
		ObjectMeta: api.ObjectMeta{
			Name: etcdName,
			Labels: map[string]string{
				"app":       "etcd",
				"etcd_node": etcdName,
				"etcd_uuid": uuid,
			},
		},
		Spec: api.PodSpec{
			Containers: []api.Container{
				{
					Command: []string{
						"/usr/local/bin/etcd",
						"--name",
						etcdName,
						"--initial-advertise-peer-urls",
						fmt.Sprintf("http://%s:2380", etcdName),
						"--listen-peer-urls",
						"http://0.0.0.0:2380",
						"--listen-client-urls",
						"http://0.0.0.0:2379",
						"--advertise-client-urls",
						fmt.Sprintf("http://%s:2379", etcdName),
						"--initial-cluster",
						strings.Join(initialCluster, ","),
						"--initial-cluster-state",
						"new",
					},
					Name:  etcdName,
					Image: "gcr.io/coreos-k8s-scale-testing/etcd-amd64:3.0.4",
					Ports: []api.ContainerPort{
						{
							Name:          "server",
							ContainerPort: int32(2380),
							Protocol:      api.ProtocolTCP,
						},
					},
				},
			},
			RestartPolicy: api.RestartPolicyNever,
		},
	}
	return pod
}
<commit_msg>change name format of etcd cluster<commit_after>package main

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

	"github.com/pborman/uuid"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/client/restclient"
	"k8s.io/kubernetes/pkg/client/unversioned"
	"k8s.io/kubernetes/pkg/util/intstr"
)

var masterHost string

func init() {
	flag.StringVar(&masterHost, "master", "http://127.0.0.1:8080", "TODO: usage")
	flag.Parse()
}

type etcdClusterController struct {
	kclient *unversioned.Client
}

func (c *etcdClusterController) Run() {
	eventCh, errCh := monitorNewCluster()
	for {
		select {
		case event := <-eventCh:
			c.createCluster(event)
		case err := <-errCh:
			panic(err)
		}
	}
}

func (c *etcdClusterController) createCluster(event newCluster) {
	size := event.Size
	clusterName := event.Metadata["name"]

	initialCluster := []string{}
	for i := 0; i < size; i++ {
		initialCluster = append(initialCluster, fmt.Sprintf("%s-%04d=http://%s-%04d:2380", clusterName, i, clusterName, i))
	}

	for i := 0; i < size; i++ {
		etcdName := fmt.Sprintf("%s-%04d", clusterName, i)

		svc := makeEtcdService(etcdName, clusterName)
		_, err := c.kclient.Services("default").Create(svc)
		if err != nil {
			panic(err)
		}
		// TODO: add and expose client port
		pod := makeEtcdPod(etcdName, clusterName, initialCluster)
		_, err = c.kclient.Pods("default").Create(pod)
		if err != nil {
			panic(err)
		}
	}
}

type newCluster struct {
	Kind       string            `json:"kind"`
	ApiVersion string            `json:"apiVersion"`
	Metadata   map[string]string `json:"metadata"`
	Size       int               `json:"size"`
}

type Event struct {
	Type   string
	Object newCluster
}

func monitorNewCluster() (<-chan newCluster, <-chan error) {
	events := make(chan newCluster)
	errc := make(chan error, 1)
	go func() {
		resp, err := http.Get(masterHost + "/apis/coreos.com/v1/namespaces/default/etcdclusters?watch=true")
		if err != nil {
			errc <- err
			return
		}
		if resp.StatusCode != 200 {
			errc <- errors.New("Invalid status code: " + resp.Status)
			return
		}
		log.Println("start watching...")
		for {
			decoder := json.NewDecoder(resp.Body)
			var ev Event
			err = decoder.Decode(&ev)
			if err != nil {
				errc <- err
			}
			event := ev.Object
			log.Println("new cluster size:", event.Size, event.Metadata)
			events <- event
		}
	}()

	return events, errc
}

func main() {
	c := &etcdClusterController{
		kclient: mustCreateClient(masterHost),
	}
	log.Println("etcd cluster controller starts running...")
	c.Run()
}

func mustCreateClient(host string) *unversioned.Client {
	cfg := &restclient.Config{
		Host:  host,
		QPS:   100,
		Burst: 100,
	}
	c, err := unversioned.New(cfg)
	if err != nil {
		panic(err)
	}
	return c
}

func generateUUID() string {
	return uuid.New()
}

func makeEtcdService(etcdName, uuid string) *api.Service {
	labels := map[string]string{
		"etcd_node": etcdName,
		"etcd_uuid": uuid,
	}
	svc := &api.Service{
		ObjectMeta: api.ObjectMeta{
			Name:   etcdName,
			Labels: labels,
		},
		Spec: api.ServiceSpec{
			Ports: []api.ServicePort{{
				Name:       "server",
				Port:       2380,
				TargetPort: intstr.FromInt(2380),
				Protocol:   api.ProtocolTCP,
			}},
			Selector: labels,
		},
	}
	return svc
}

func makeEtcdPod(etcdName, uuid string, initialCluster []string) *api.Pod {
	pod := &api.Pod{
		ObjectMeta: api.ObjectMeta{
			Name: etcdName,
			Labels: map[string]string{
				"app":       "etcd",
				"etcd_node": etcdName,
				"etcd_uuid": uuid,
			},
		},
		Spec: api.PodSpec{
			Containers: []api.Container{
				{
					Command: []string{
						"/usr/local/bin/etcd",
						"--name",
						etcdName,
						"--initial-advertise-peer-urls",
						fmt.Sprintf("http://%s:2380", etcdName),
						"--listen-peer-urls",
						"http://0.0.0.0:2380",
						"--listen-client-urls",
						"http://0.0.0.0:2379",
						"--advertise-client-urls",
						fmt.Sprintf("http://%s:2379", etcdName),
						"--initial-cluster",
						strings.Join(initialCluster, ","),
						"--initial-cluster-state",
						"new",
					},
					Name:  etcdName,
					Image: "gcr.io/coreos-k8s-scale-testing/etcd-amd64:3.0.4",
					Ports: []api.ContainerPort{
						{
							Name:          "server",
							ContainerPort: int32(2380),
							Protocol:      api.ProtocolTCP,
						},
					},
				},
			},
			RestartPolicy: api.RestartPolicyNever,
		},
	}
	return pod
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"

	"github.com/gopheracademy/congo/app"
	"github.com/gopheracademy/congo/js"
	"github.com/gopheracademy/congo/models"
	"github.com/gopheracademy/congo/swagger"
	"github.com/gopheracademy/congo/util"
	"github.com/jinzhu/gorm"
	"github.com/kelseyhightower/envconfig"
	_ "github.com/lib/pq"
	"github.com/markbates/goth"
	"github.com/markbates/goth/gothic"
	"github.com/markbates/goth/providers/twitter"
	"github.com/raphael/goa"
	//	_ "gopkg.in/authboss.v0/remember"
	jg "github.com/dgrijalva/jwt-go"
	"github.com/raphael/goa-middleware/cors"
	"github.com/raphael/goa-middleware/jwt"
)

func main() {

	goth.UseProviders(
		twitter.New(os.Getenv("TWITTER_KEY"), os.Getenv("TWITTER_SECRET"), "http://arrakis:8080/api/auth/twitter/callback"),
		//		gplus.New(os.Getenv("GPLUS_KEY"), os.Getenv("GPLUS_SECRET"), "http://localhost:3000/auth/gplus/callback"),
		//		github.New(os.Getenv("GITHUB_KEY"), os.Getenv("GITHUB_SECRET"), "http://localhost:3000/auth/github/callback"),
		//		linkedin.New(os.Getenv("LINKEDIN_KEY"), os.Getenv("LINKEDIN_SECRET"), "http://localhost:3000/auth/linkedin/callback"),
	)
	cfg := util.Config{}
	if err := envconfig.Process("congo", &cfg); err != nil {
		log.Fatalf("config error [%s]", err)
		os.Exit(1)
	}

	// Create service
	service := goa.New("API")

	// Setup middleware
	service.Use(goa.RequestID())
	service.Use(goa.LogRequest())
	service.Use(goa.Recover())

	// cors specification
	cspec, err := cors.New(func() {
		cors.Origin("https://cfp.gophercon.com", func() {
			cors.Resource("/api", func() {
				cors.Headers("Authorization")
				cors.Methods("GET", "POST", "PUT", "DELETE", "OPTIONS")
				cors.MaxAge(600)
				cors.Credentials(true)
				cors.Vary("Http-Origin")
			})
		})
	})
	if err != nil {
		panic(err)
	}
	// mount the cors controller
	service.Use(cors.Middleware(cspec))

	db, err := connectDB()
	if err != nil {
		panic(err)
	}
	spec := &jwt.Specification{
		AllowParam:       false,
		AuthOptions:      false,
		TTLMinutes:       60,
		Issuer:           "api.gopheracademy.com",
		KeySigningMethod: jwt.RSA256,
		SigningKeyFunc:   privateKey,
		ValidationFunc:   pubKey,
	}

	tm := jwt.NewTokenManager(spec)
	claims := make(map[string]interface{})
	claims["sub"] = "1"

	t, err := tm.Create(claims)
	// a token to get in through the backdoor printed to standard out
	fmt.Println(t)

	a := NewAuthController(service, &db, tm, spec)
	app.MountAuthController(service, a)
	// Mount "user" controller
	c3 := NewUserController(service, models.NewUserDB(db))
	app.MountUserController(service, c3)
	c3.Use(jwt.Middleware(spec))
	c4 := NewProposalController(service, models.NewProposalDB(db))
	app.MountProposalController(service, c4)
	c4.Use(jwt.Middleware(spec))

	js.MountController(service)
	// Mount Swagger spec provider controller
	swagger.MountController(service)

	gothic.GetProviderName = provider

	hostStr := fmt.Sprintf(":%d", cfg.Port)
	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		log.Fatal(err)
	}
	service.ServeFiles("/assets/*filepath", http.Dir(filepath.Join(dir, "public")))
	service.ListenAndServe(hostStr)
}
func provider(r *http.Request) (string, error) {
	return "twitter", nil
}
func connectDB() (gorm.DB, error) {
	var db gorm.DB
	constr := fmt.Sprintf("user=%s host=%s port=%d dbname=%s password=%s sslmode=disable",
		"postgres",
		"127.0.0.1",
		5433,
		"postgres",
		"postgres")

	var err error
	db, err = gorm.Open("postgres", constr)
	if err == nil {
		db.AutoMigrate(&models.User{})
	}
	db.LogMode(true)
	return db, err
}
func pubKey(*jg.Token) (interface{}, error) {
	return ioutil.ReadFile("keys/gc.rsa.pub")
}

func privateKey() (interface{}, error) {
	return ioutil.ReadFile("keys/gc.rsa")
}
<commit_msg>panic when can't open keys<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"

	"github.com/gopheracademy/congo/app"
	"github.com/gopheracademy/congo/js"
	"github.com/gopheracademy/congo/models"
	"github.com/gopheracademy/congo/swagger"
	"github.com/gopheracademy/congo/util"
	"github.com/jinzhu/gorm"
	"github.com/kelseyhightower/envconfig"
	_ "github.com/lib/pq"
	"github.com/markbates/goth"
	"github.com/markbates/goth/gothic"
	"github.com/markbates/goth/providers/twitter"
	"github.com/raphael/goa"
	//	_ "gopkg.in/authboss.v0/remember"
	jg "github.com/dgrijalva/jwt-go"
	"github.com/raphael/goa-middleware/cors"
	"github.com/raphael/goa-middleware/jwt"
)

func main() {

	goth.UseProviders(
		twitter.New(os.Getenv("TWITTER_KEY"), os.Getenv("TWITTER_SECRET"), "http://arrakis:8080/api/auth/twitter/callback"),
		//		gplus.New(os.Getenv("GPLUS_KEY"), os.Getenv("GPLUS_SECRET"), "http://localhost:3000/auth/gplus/callback"),
		//		github.New(os.Getenv("GITHUB_KEY"), os.Getenv("GITHUB_SECRET"), "http://localhost:3000/auth/github/callback"),
		//		linkedin.New(os.Getenv("LINKEDIN_KEY"), os.Getenv("LINKEDIN_SECRET"), "http://localhost:3000/auth/linkedin/callback"),
	)
	cfg := util.Config{}
	if err := envconfig.Process("congo", &cfg); err != nil {
		log.Fatalf("config error [%s]", err)
		os.Exit(1)
	}

	// Create service
	service := goa.New("API")

	// Setup middleware
	service.Use(goa.RequestID())
	service.Use(goa.LogRequest())
	service.Use(goa.Recover())

	// cors specification
	cspec, err := cors.New(func() {
		cors.Origin("https://cfp.gophercon.com", func() {
			cors.Resource("/api", func() {
				cors.Headers("Authorization")
				cors.Methods("GET", "POST", "PUT", "DELETE", "OPTIONS")
				cors.MaxAge(600)
				cors.Credentials(true)
				cors.Vary("Http-Origin")
			})
		})
	})
	if err != nil {
		panic(err)
	}
	// mount the cors controller
	service.Use(cors.Middleware(cspec))

	db, err := connectDB()
	if err != nil {
		panic(err)
	}
	spec := &jwt.Specification{
		AllowParam:       false,
		AuthOptions:      false,
		TTLMinutes:       60,
		Issuer:           "api.gopheracademy.com",
		KeySigningMethod: jwt.RSA256,
		SigningKeyFunc:   privateKey,
		ValidationFunc:   pubKey,
	}

	tm := jwt.NewTokenManager(spec)
	claims := make(map[string]interface{})
	claims["sub"] = "1"

	t, err := tm.Create(claims)
	// a token to get in through the backdoor printed to standard out
	fmt.Println(t)

	a := NewAuthController(service, &db, tm, spec)
	app.MountAuthController(service, a)
	// Mount "user" controller
	c3 := NewUserController(service, models.NewUserDB(db))
	app.MountUserController(service, c3)
	c3.Use(jwt.Middleware(spec))
	c4 := NewProposalController(service, models.NewProposalDB(db))
	app.MountProposalController(service, c4)
	c4.Use(jwt.Middleware(spec))

	js.MountController(service)
	// Mount Swagger spec provider controller
	swagger.MountController(service)

	gothic.GetProviderName = provider

	hostStr := fmt.Sprintf(":%d", cfg.Port)
	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		log.Fatal(err)
	}
	service.ServeFiles("/assets/*filepath", http.Dir(filepath.Join(dir, "public")))
	service.ListenAndServe(hostStr)
}
func provider(r *http.Request) (string, error) {
	return "twitter", nil
}
func connectDB() (gorm.DB, error) {
	var db gorm.DB
	constr := fmt.Sprintf("user=%s host=%s port=%d dbname=%s password=%s sslmode=disable",
		"postgres",
		"127.0.0.1",
		5433,
		"postgres",
		"postgres")

	var err error
	db, err = gorm.Open("postgres", constr)
	if err == nil {
		db.AutoMigrate(&models.User{})
	}
	db.LogMode(true)
	return db, err
}
func pubKey(*jg.Token) (interface{}, error) {
	//TODO(BJK) make the keys an ENV var
	f, err := os.Open("keys/gc.rsa.pub")
	defer f.Close()
	if err != nil {
		panic(err)
	}
	return ioutil.ReadFile("keys/gc.rsa.pub")
}

func privateKey() (interface{}, error) {
	//TODO(BJK) make the keys an ENV var
	f, err := os.Open("keys/gc.rsa")
	defer f.Close()
	if err != nil {
		panic(err)
	}
	return ioutil.ReadFile("keys/gc.rsa")
}
<|endoftext|>


<commit_before>package adapter

import (
	"context"
	"encoding/hex"
	"flag"
	"fmt"
	"net"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/gorilla/securecookie"
	"github.com/lestrrat/go-server-starter/listener"
	"github.com/sirupsen/logrus"
)

// Version is the version of go-nginx-oauth2-adapter.
const Version = "0.3.0"

// Main starts the go-nginx-oauth2-adapter server.
func Main(args []string) int {

	flagSet := flag.NewFlagSet(args[0], flag.ContinueOnError)
	var configFile string
	var configtest bool
	var showVersion bool
	var showHelp bool
	var genKey bool
	flagSet.StringVar(&configFile, "c", "", "configuration file")
	flagSet.StringVar(&configFile, "config", "", "configuration file")
	flagSet.BoolVar(&configtest, "t", false, "test configuration and exit")
	flagSet.BoolVar(&configtest, "configtest", false, "test configuration and exit")
	flagSet.BoolVar(&showVersion, "v", false, "show version information")
	flagSet.BoolVar(&showVersion, "version", false, "show version information")
	flagSet.BoolVar(&showHelp, "h", false, "show help")
	flagSet.BoolVar(&showHelp, "help", false, "show help")
	flagSet.BoolVar(&genKey, "g", false, "shorthand of genkey")
	flagSet.BoolVar(&genKey, "genkey", false, "generate random key for cookie")
	err := flagSet.Parse(args[1:])
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"err": err.Error(),
		}).Error("error while parsing flags")
		return 2
	}

	if showVersion {
		fmt.Println("go-nginx-oauth2-adapter", Version)
		return 0
	}

	if showHelp {
		flagSet.Usage()
		return 0
	}

	if genKey {
		fmt.Println(hex.EncodeToString(securecookie.GenerateRandomKey(64)))
		fmt.Println(hex.EncodeToString(securecookie.GenerateRandomKey(32)))
		return 0
	}

	c, err := parseConfig(configFile)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"err": err.Error(),
		}).Error("error while parsing configure")
		return 1
	}
	c.ConfigTest = configtest

	s, err := NewServer(*c)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"err": err.Error(),
		}).Error("init server error")
		return 1
	}
	if configtest {
		return 0
	}

	l, err := getListener(c)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"err": err.Error(),
		}).Error("listen error")
		return 1
	}
	server := &http.Server{
		Handler: LoggingHandler(s),
	}
	go func() {
		err := server.Serve(l)
		if err == http.ErrServerClosed {
			return
		}
		if err != nil {
			logrus.WithFields(logrus.Fields{
				"err": err.Error(),
			}).Fatal("serve error")
		}
	}()

	waitSignal()
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	err = server.Shutdown(ctx)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"err": err.Error(),
		}).Error("shutdown server error")
	}
	return 0
}

func parseConfig(configFile string) (*Config, error) {
	c := NewConfig()
	if err := c.LoadEnv(); err != nil {
		return nil, err
	}
	if configFile != "" {
		if err := c.LoadYaml(configFile); err != nil {
			return nil, err
		}
	}

	return c, nil
}

func waitSignal() {
	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, syscall.SIGTERM)
	for {
		s := <-signalChan
		if s == syscall.SIGTERM {
			logrus.Info("received SIGTERM")
			return
		}
	}
}

func getListener(c *Config) (net.Listener, error) {
	listeners, err := listener.ListenAll()
	if err != nil && err != listener.ErrNoListeningTarget {
		panic(err)
	}
	if err != listener.ErrNoListeningTarget {
		return listeners[0], nil
	}

	// Fallback if not running under Server::Starter
	return net.Listen("tcp", c.Address)
}
<commit_msg>bump version<commit_after>package adapter

import (
	"context"
	"encoding/hex"
	"flag"
	"fmt"
	"net"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/gorilla/securecookie"
	"github.com/lestrrat/go-server-starter/listener"
	"github.com/sirupsen/logrus"
)

// Version is the version of go-nginx-oauth2-adapter.
const Version = "0.3.2"

// Main starts the go-nginx-oauth2-adapter server.
func Main(args []string) int {

	flagSet := flag.NewFlagSet(args[0], flag.ContinueOnError)
	var configFile string
	var configtest bool
	var showVersion bool
	var showHelp bool
	var genKey bool
	flagSet.StringVar(&configFile, "c", "", "configuration file")
	flagSet.StringVar(&configFile, "config", "", "configuration file")
	flagSet.BoolVar(&configtest, "t", false, "test configuration and exit")
	flagSet.BoolVar(&configtest, "configtest", false, "test configuration and exit")
	flagSet.BoolVar(&showVersion, "v", false, "show version information")
	flagSet.BoolVar(&showVersion, "version", false, "show version information")
	flagSet.BoolVar(&showHelp, "h", false, "show help")
	flagSet.BoolVar(&showHelp, "help", false, "show help")
	flagSet.BoolVar(&genKey, "g", false, "shorthand of genkey")
	flagSet.BoolVar(&genKey, "genkey", false, "generate random key for cookie")
	err := flagSet.Parse(args[1:])
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"err": err.Error(),
		}).Error("error while parsing flags")
		return 2
	}

	if showVersion {
		fmt.Println("go-nginx-oauth2-adapter", Version)
		return 0
	}

	if showHelp {
		flagSet.Usage()
		return 0
	}

	if genKey {
		fmt.Println(hex.EncodeToString(securecookie.GenerateRandomKey(64)))
		fmt.Println(hex.EncodeToString(securecookie.GenerateRandomKey(32)))
		return 0
	}

	c, err := parseConfig(configFile)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"err": err.Error(),
		}).Error("error while parsing configure")
		return 1
	}
	c.ConfigTest = configtest

	s, err := NewServer(*c)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"err": err.Error(),
		}).Error("init server error")
		return 1
	}
	if configtest {
		return 0
	}

	l, err := getListener(c)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"err": err.Error(),
		}).Error("listen error")
		return 1
	}
	server := &http.Server{
		Handler: LoggingHandler(s),
	}
	go func() {
		err := server.Serve(l)
		if err == http.ErrServerClosed {
			return
		}
		if err != nil {
			logrus.WithFields(logrus.Fields{
				"err": err.Error(),
			}).Fatal("serve error")
		}
	}()

	waitSignal()
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()
	err = server.Shutdown(ctx)
	if err != nil {
		logrus.WithFields(logrus.Fields{
			"err": err.Error(),
		}).Error("shutdown server error")
	}
	return 0
}

func parseConfig(configFile string) (*Config, error) {
	c := NewConfig()
	if err := c.LoadEnv(); err != nil {
		return nil, err
	}
	if configFile != "" {
		if err := c.LoadYaml(configFile); err != nil {
			return nil, err
		}
	}

	return c, nil
}

func waitSignal() {
	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, syscall.SIGTERM)
	for {
		s := <-signalChan
		if s == syscall.SIGTERM {
			logrus.Info("received SIGTERM")
			return
		}
	}
}

func getListener(c *Config) (net.Listener, error) {
	listeners, err := listener.ListenAll()
	if err != nil && err != listener.ErrNoListeningTarget {
		panic(err)
	}
	if err != listener.ErrNoListeningTarget {
		return listeners[0], nil
	}

	// Fallback if not running under Server::Starter
	return net.Listen("tcp", c.Address)
}
<|endoftext|>


<commit_before>// Copyright 2017 XUEQIU.COM
//
// 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 main

import (
	"net/http"
	"os"

	"github.com/urfave/cli"

	"fmt"

	"path/filepath"

	"github.com/cupcake/rdb"
	"github.com/elazarl/go-bindata-assetfs"
	"github.com/julienschmidt/httprouter"
	"github.com/xueqiu/rdr/static"
)

//go:generate go-bindata -prefix "static/" -o=static/static.go -pkg=static -ignore static.go static/...
//go:generate go-bindata -prefix "views/" -o=views/views.go -pkg=views -ignore views.go views/...

func decode(c *cli.Context, decoder *Decoder, filepath string) {
	f, err := os.Open(filepath)
	if err != nil {
		fmt.Fprintf(c.App.ErrWriter, "open rdbfile err: %v\n", err)
		close(decoder.Entries)
		return
	}
	err = rdb.Decode(f, decoder)
	if err != nil {
		fmt.Fprintf(c.App.ErrWriter, "decode rdbfile err: %v\n", err)
		close(decoder.Entries)
		return
	}
}

var counters = NewSafeMap()

// show parse rdbfile(s) and show statistical information by html
func show(c *cli.Context) {
	if c.NArg() < 1 {
		fmt.Fprintln(c.App.ErrWriter, "show requires at least 1 argument")
		cli.ShowCommandHelp(c, "show")
		return
	}

	// parse rdbfile
	fmt.Fprintln(c.App.Writer, "start parsing...")
	instances := []string{}
	for _, file := range c.Args() {
		decoder := NewDecoder()
		go decode(c, decoder, file)
		counter := NewCounter()
		counter.Count(decoder.Entries)
		filename := filepath.Base(file)
		counters.Set(filename, counter)
		instances = append(instances, filename)
		fmt.Fprintf(c.App.Writer, "parse %v  done\n", file)
	}

	// init html template
	// init common data in template
	initHTMLTmpl()
	tplCommonData["Instances"] = instances

	// start http server
	staticFS := assetfs.AssetFS{
		Asset:     static.Asset,
		AssetDir:  static.AssetDir,
		AssetInfo: static.AssetInfo,
	}
	router := httprouter.New()
	router.ServeFiles("/static/*filepath", &staticFS)
	router.GET("/", index)
	router.GET("/instance/:path", rdbReveal)
	fmt.Fprintln(c.App.Writer, "parsing finished, please access http://127.0.0.1:"+c.String("port"))
	listenErr := http.ListenAndServe(":"+c.String("port"), router)
	if listenErr != nil {
		fmt.Fprintf(c.App.ErrWriter, "Listen port err: %v\n", listenErr)
	}
}

// keys is function for command `keys`
// output all keys in rdbfile(s) get from args
func keys(c *cli.Context) {
	if c.NArg() < 1 {
		fmt.Fprintln(c.App.ErrWriter, "keys requires at least 1 argument")
		cli.ShowCommandHelp(c, "keys")
		return
	}
	for _, filepath := range c.Args() {
		decoder := NewDecoder()
		go decode(c, decoder, filepath)
		for e := range decoder.Entries {
			fmt.Fprintf(c.App.Writer, "%v\n", e.Key)
		}
	}
}

func main() {
	app := cli.NewApp()
	app.Name = "rdr"
	app.Usage = "a tool to parse redis rdbfile"
	app.Version = "v0.0.1"
	app.Writer = os.Stdout
	app.ErrWriter = os.Stderr
	var port uint
	app.Commands = []cli.Command{
		cli.Command{
			Name:      "show",
			Usage:     "show statistical information of rdbfile by webpage",
			ArgsUsage: "FILE1 [FILE2] [FILE3]...",
			Flags: []cli.Flag{
				cli.UintFlag{
					Name:        "port, p",
					Value:       8080,
					Usage:       "Port for rdr to listen",
					Destination: &port,
				},
			},
			Action: show,
		},
		cli.Command{
			Name:      "keys",
			Usage:     "get all keys from rdbfile",
			ArgsUsage: "FILE1 [FILE2] [FILE3]...",
			Action:    keys,
		},
	}
	app.CommandNotFound = func(c *cli.Context, command string) {
		fmt.Fprintf(c.App.ErrWriter, "command %q can not be found.\n", command)
		cli.ShowAppHelp(c)
	}
	app.Run(os.Args)
}
<commit_msg>remove unused variable<commit_after>// Copyright 2017 XUEQIU.COM
//
// 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 main

import (
	"net/http"
	"os"

	"github.com/urfave/cli"

	"fmt"

	"path/filepath"

	"github.com/cupcake/rdb"
	"github.com/elazarl/go-bindata-assetfs"
	"github.com/julienschmidt/httprouter"
	"github.com/xueqiu/rdr/static"
)

//go:generate go-bindata -prefix "static/" -o=static/static.go -pkg=static -ignore static.go static/...
//go:generate go-bindata -prefix "views/" -o=views/views.go -pkg=views -ignore views.go views/...

func decode(c *cli.Context, decoder *Decoder, filepath string) {
	f, err := os.Open(filepath)
	if err != nil {
		fmt.Fprintf(c.App.ErrWriter, "open rdbfile err: %v\n", err)
		close(decoder.Entries)
		return
	}
	err = rdb.Decode(f, decoder)
	if err != nil {
		fmt.Fprintf(c.App.ErrWriter, "decode rdbfile err: %v\n", err)
		close(decoder.Entries)
		return
	}
}

var counters = NewSafeMap()

// show parse rdbfile(s) and show statistical information by html
func show(c *cli.Context) {
	if c.NArg() < 1 {
		fmt.Fprintln(c.App.ErrWriter, "show requires at least 1 argument")
		cli.ShowCommandHelp(c, "show")
		return
	}

	// parse rdbfile
	fmt.Fprintln(c.App.Writer, "start parsing...")
	instances := []string{}
	for _, file := range c.Args() {
		decoder := NewDecoder()
		go decode(c, decoder, file)
		counter := NewCounter()
		counter.Count(decoder.Entries)
		filename := filepath.Base(file)
		counters.Set(filename, counter)
		instances = append(instances, filename)
		fmt.Fprintf(c.App.Writer, "parse %v  done\n", file)
	}

	// init html template
	// init common data in template
	initHTMLTmpl()
	tplCommonData["Instances"] = instances

	// start http server
	staticFS := assetfs.AssetFS{
		Asset:     static.Asset,
		AssetDir:  static.AssetDir,
		AssetInfo: static.AssetInfo,
	}
	router := httprouter.New()
	router.ServeFiles("/static/*filepath", &staticFS)
	router.GET("/", index)
	router.GET("/instance/:path", rdbReveal)
	fmt.Fprintln(c.App.Writer, "parsing finished, please access http://127.0.0.1:"+c.String("port"))
	listenErr := http.ListenAndServe(":"+c.String("port"), router)
	if listenErr != nil {
		fmt.Fprintf(c.App.ErrWriter, "Listen port err: %v\n", listenErr)
	}
}

// keys is function for command `keys`
// output all keys in rdbfile(s) get from args
func keys(c *cli.Context) {
	if c.NArg() < 1 {
		fmt.Fprintln(c.App.ErrWriter, "keys requires at least 1 argument")
		cli.ShowCommandHelp(c, "keys")
		return
	}
	for _, filepath := range c.Args() {
		decoder := NewDecoder()
		go decode(c, decoder, filepath)
		for e := range decoder.Entries {
			fmt.Fprintf(c.App.Writer, "%v\n", e.Key)
		}
	}
}

func main() {
	app := cli.NewApp()
	app.Name = "rdr"
	app.Usage = "a tool to parse redis rdbfile"
	app.Version = "v0.0.1"
	app.Writer = os.Stdout
	app.ErrWriter = os.Stderr
	app.Commands = []cli.Command{
		cli.Command{
			Name:      "show",
			Usage:     "show statistical information of rdbfile by webpage",
			ArgsUsage: "FILE1 [FILE2] [FILE3]...",
			Flags: []cli.Flag{
				cli.UintFlag{
					Name:  "port, p",
					Value: 8080,
					Usage: "Port for rdr to listen",
				},
			},
			Action: show,
		},
		cli.Command{
			Name:      "keys",
			Usage:     "get all keys from rdbfile",
			ArgsUsage: "FILE1 [FILE2] [FILE3]...",
			Action:    keys,
		},
	}
	app.CommandNotFound = func(c *cli.Context, command string) {
		fmt.Fprintf(c.App.ErrWriter, "command %q can not be found.\n", command)
		cli.ShowAppHelp(c)
	}
	app.Run(os.Args)
}
<|endoftext|>


<commit_before>package main

import (
	"net/http"
	"fmt"
	"log"
	"io/ioutil"
	"bytes"
	"net/url"
)

func main() {
	println("Init facebook.go > main()")
	http.HandleFunc("/facebook", facebook)
	http.HandleFunc("/", welcome)
	err := http.ListenAndServe("0.0.0.0:3000", nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

func facebook(writer http.ResponseWriter, request *http.Request) {
	urlStr := "https://graph.facebook.com/v2.5/feed"
	data := url.Values{}
	data.Set("access_token", request.FormValue("access_token"))
	data.Add("message",request.FormValue("message"))

	client := &http.Client{}
	r, error := http.NewRequest("POST", urlStr, bytes.NewBufferString(data.Encode()))
	r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	resp, _ := client.Do(r)
	if error != nil {
		fmt.Printf("%s", error)
		//os.Exit(1)
	}

	defer resp.Body.Close()
	contents, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("%s", err)
		//os.Exit(1)
	}
	//fmt.Printf("%s\n", string(contents))
	writer.Header().Set("Content-Type", "text/html; charset=utf-8")
	writer.Write(contents)
}

func welcome(writer http.ResponseWriter, request *http.Request) {
	writer.Header().Set("Content-Type", "text/html; charset=utf-8")
	writer.Write([]byte("
Welcome to Go Facebook POC!!!
"))
}<commit_msg>Supports only HTTP POST<commit_after>package main

import (
	"net/http"
	"fmt"
	"log"
	"io/ioutil"
	"bytes"
	"net/url"
)

func main() {
	println("Init facebook.go > main()")
	http.HandleFunc("/facebook", facebook)
	http.HandleFunc("/", welcome)
	err := http.ListenAndServe("0.0.0.0:3000", nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

func facebook(writer http.ResponseWriter, request *http.Request) {
	writer.Header().Set("Content-Type", "text/html; charset=utf-8")
	if (request.Method != "POST") {
		writer.Write([]byte("{error:'Unsupported HTTP method - " + request.Method + ". : Supports ONLY - HTTP POST'}"))
	} else {
		urlStr := "https://graph.facebook.com/v2.5/feed"
		data := url.Values{}
		data.Set("access_token", request.FormValue("access_token"))
		data.Add("message", request.FormValue("message"))

		client := &http.Client{}
		r, error := http.NewRequest("POST", urlStr, bytes.NewBufferString(data.Encode()))
		r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
		resp, _ := client.Do(r)
		if error != nil {
			fmt.Printf("%s", error)
			//os.Exit(1)
		}

		defer resp.Body.Close()
		contents, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			fmt.Printf("%s", err)
			//os.Exit(1)
		}
		//fmt.Printf("%s\n", string(contents))
		writer.Write(contents)
	}
}

func welcome(writer http.ResponseWriter, request *http.Request) {
	writer.Header().Set("Content-Type", "text/html; charset=utf-8")
	writer.Write([]byte("
Welcome to Go Facebook POC!!!
"))
}<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"net/http"
	"net/url"
	"strings"
	"time"

	"github.com/krishnasrinivas/v2tov4proxy/auth"
	"github.com/vulcand/oxy/forward"
)

// Proxy from a V2 ingress to V4 egress.
type proxy struct {
	scheme  string       // http or https of the Minio server
	host    string       // host:port of the Minio server
	ingress auth.Signer  // signer at the ingress (V2)
	egress  auth.Signer  // signer at the egress (v4)
	h       http.Handler // forwarding handler
}

func (p proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if strings.Contains(r.Header.Get("Authorization"), auth.SignV4Algorithm) {
		// If the signature is V4 then pass through the request as is
		// as it will be authenticated by the Minio server.
		p.h.ServeHTTP(w, r)
		return
	}

	// url.RawPath will be valid if path has any encoded characters, if not it will
	// be empty - in which case we need to consider url.Path (bug in net/http?)
	encodedResource := r.URL.RawPath
	encodedQuery := r.URL.RawQuery
	if encodedResource == "" {
		splits := strings.Split(r.URL.Path, "?")
		if len(splits) > 0 {
			encodedResource = splits[0]
		}
	}

	expectedAuth := p.ingress.Sign(r.Method, encodedResource, encodedQuery, r.Header)
	gotAuth := r.Header.Get("Authorization")

	if gotAuth != expectedAuth {
		fmt.Printf("Error: got: %s, expected:%s\n", gotAuth, expectedAuth)
		w.WriteHeader(http.StatusForbidden)
		return
	}

	dateStr := time.Now().UTC().Format(auth.DateFormat)
	r.Header.Set("X-Amz-Date", dateStr)                      // Mandatory for V4 signature.
	r.Header.Set("Host", r.Host)                             // Host header at the ingress will be availabe as r.Host
	r.Header.Set("X-Amz-Content-Sha256", "UNSIGNED-PAYLOAD") // We don't compute SHA256 for the data.

	// In case _ or - ro ~ were encoded, decode it - to be V4 compatible.
	encodedResource = canonicalEncoding(encodedResource)
	encodedQuery = canonicalEncoding(encodedQuery)
	r.URL.RawPath = encodedResource
	r.URL.RawQuery = encodedQuery
	r.URL.Path = canonicalEncoding(r.URL.Path)

	// for encodedQuery, "/" should be encoded. (mc currently does not encode "/")
	encodedQuery = strings.Replace(encodedQuery, "/", "%2F", -1)
	r.Header.Set("Authorization", p.egress.Sign(r.Method, encodedResource, encodedQuery, r.Header))

	// Forward the request to Minio server.
	r.URL.Scheme = p.scheme
	r.URL.Host = p.host
	p.h.ServeHTTP(w, r)
}

// Sign-V4 spec mandates - _ ~ not to be encoded.
func canonicalEncoding(str string) string {
	str = strings.Replace(str, "%2D", "-", -1)
	str = strings.Replace(str, "%5F", "_", -1)
	str = strings.Replace(str, "%7E", "~", -1)
	return str
}

// We have a no-op rewriter so that the forwarder does not add it's own headers.
type norewrite struct{}

func (r norewrite) Rewrite(req *http.Request) {}

func main() {
	// Local listening address for ingress data.
	listenAddr := flag.String("l", ":8000", "listen address")
	// Forwarding address.
	fwdAddr := flag.String("f", "http://localhost:9000", "forward address")

	// Credentials.
	accessKey := flag.String("access", "", "access key")
	secretKey := flag.String("secret", "", "secret key")

	// If cert and key is specified we enable https on listening server.
	cert := flag.String("cert", "", "certficate for https")
	key := flag.String("key", "", "key for https")
	flag.Parse()

	host := *fwdAddr
	scheme := "http"
	u, err := url.Parse(*fwdAddr)
	if err == nil {
		host = u.Host
		if u.Scheme != "" {
			scheme = u.Scheme
		}
	}

	if *accessKey == "" || *secretKey == "" {
		fmt.Println("access/secret key should be specified")
		return
	}

	// Forwarding http.Handler
	fwd, _ := forward.New(forward.PassHostHeader(true), forward.Rewriter(norewrite{}))

	// HTTP server.
	server := &http.Server{
		Addr: *listenAddr,
		Handler: proxy{
			scheme,
			host,
			auth.CredentialsV2{*accessKey, *secretKey, "us-east-1"},
			auth.CredentialsV4{*accessKey, *secretKey, "us-east-1"},
			fwd,
		},
	}

	if *cert != "" && *key != "" {
		fmt.Println(server.ListenAndServeTLS(*cert, *key))
	} else {
		fmt.Println(server.ListenAndServe())
	}
}
<commit_msg>Enable forward pkg logging.<commit_after>package main

import (
	"flag"
	"fmt"
	"net/http"
	"net/url"
	"os"
	"strings"
	"time"

	"github.com/krishnasrinivas/v2tov4proxy/auth"
	"github.com/vulcand/oxy/forward"
	"github.com/vulcand/oxy/utils"
)

// Proxy from a V2 ingress to V4 egress.
type proxy struct {
	scheme  string       // http or https of the Minio server
	host    string       // host:port of the Minio server
	ingress auth.Signer  // signer at the ingress (V2)
	egress  auth.Signer  // signer at the egress (v4)
	h       http.Handler // forwarding handler
}

func (p proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if strings.Contains(r.Header.Get("Authorization"), auth.SignV4Algorithm) {
		// If the signature is V4 then pass through the request as is
		// as it will be authenticated by the Minio server.
		p.h.ServeHTTP(w, r)
		return
	}

	// url.RawPath will be valid if path has any encoded characters, if not it will
	// be empty - in which case we need to consider url.Path (bug in net/http?)
	encodedResource := r.URL.RawPath
	encodedQuery := r.URL.RawQuery
	if encodedResource == "" {
		splits := strings.Split(r.URL.Path, "?")
		if len(splits) > 0 {
			encodedResource = splits[0]
		}
	}

	expectedAuth := p.ingress.Sign(r.Method, encodedResource, encodedQuery, r.Header)
	gotAuth := r.Header.Get("Authorization")

	if gotAuth != expectedAuth {
		fmt.Printf("Error: got: %s, expected:%s\n", gotAuth, expectedAuth)
		w.WriteHeader(http.StatusForbidden)
		return
	}

	dateStr := time.Now().UTC().Format(auth.DateFormat)
	r.Header.Set("X-Amz-Date", dateStr)                      // Mandatory for V4 signature.
	r.Header.Set("Host", r.Host)                             // Host header at the ingress will be availabe as r.Host
	r.Header.Set("X-Amz-Content-Sha256", "UNSIGNED-PAYLOAD") // We don't compute SHA256 for the data.

	// In case _ or - ro ~ were encoded, decode it - to be V4 compatible.
	encodedResource = canonicalEncoding(encodedResource)
	encodedQuery = canonicalEncoding(encodedQuery)
	r.URL.RawPath = encodedResource
	r.URL.RawQuery = encodedQuery
	r.URL.Path = canonicalEncoding(r.URL.Path)

	// for encodedQuery, "/" should be encoded. (mc currently does not encode "/")
	encodedQuery = strings.Replace(encodedQuery, "/", "%2F", -1)
	r.Header.Set("Authorization", p.egress.Sign(r.Method, encodedResource, encodedQuery, r.Header))

	// Forward the request to Minio server.
	r.URL.Scheme = p.scheme
	r.URL.Host = p.host
	p.h.ServeHTTP(w, r)
}

// Sign-V4 spec mandates - _ ~ not to be encoded.
func canonicalEncoding(str string) string {
	str = strings.Replace(str, "%2D", "-", -1)
	str = strings.Replace(str, "%5F", "_", -1)
	str = strings.Replace(str, "%7E", "~", -1)
	return str
}

// We have a no-op rewriter so that the forwarder does not add it's own headers.
type norewrite struct{}

func (r norewrite) Rewrite(req *http.Request) {}

func main() {
	// Local listening address for ingress data.
	listenAddr := flag.String("l", ":8000", "listen address")
	// Forwarding address.
	fwdAddr := flag.String("f", "http://localhost:9000", "forward address")

	// Credentials.
	accessKey := flag.String("access", "", "access key")
	secretKey := flag.String("secret", "", "secret key")

	// If cert and key is specified we enable https on listening server.
	cert := flag.String("cert", "", "certficate for https")
	key := flag.String("key", "", "key for https")
	flag.Parse()

	host := *fwdAddr
	scheme := "http"
	u, err := url.Parse(*fwdAddr)
	if err == nil {
		host = u.Host
		if u.Scheme != "" {
			scheme = u.Scheme
		}
	}

	if *accessKey == "" || *secretKey == "" {
		fmt.Println("access/secret key should be specified")
		return
	}

	// Forwarding http.Handler
	fwd, _ := forward.New(forward.PassHostHeader(true), forward.Rewriter(norewrite{}), forward.Logger(utils.NewFileLogger(os.Stdout, utils.INFO)))

	// HTTP server.
	server := &http.Server{
		Addr: *listenAddr,
		Handler: proxy{
			scheme,
			host,
			auth.CredentialsV2{*accessKey, *secretKey, "us-east-1"},
			auth.CredentialsV4{*accessKey, *secretKey, "us-east-1"},
			fwd,
		},
	}

	if *cert != "" && *key != "" {
		fmt.Println(server.ListenAndServeTLS(*cert, *key))
	} else {
		fmt.Println(server.ListenAndServe())
	}
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
	"strings"

	"github.com/gorilla/sessions"
	"github.com/joeshaw/envdecode"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
)

type configuration struct {
	ClientID              string   `env:"CLIENT_ID,required"`                                       // Google Client ID
	ClientSecret          string   `env:"CLIENT_SECRET,required"`                                   // Google Client Secret
	SessionSecret         string   `env:"SESSION_SECRET,required"`                                  // Random session auth key
	SessionEncrypttionKey string   `env:"SESSION_ENCRYPTION_KEY,required"`                          // Random session encryption key
	DNSName               string   `env:"DNS_NAME,required"`                                        // Public facing DNS Hostname
	CookieMaxAge          int      `env:"COOKIE_MAX_AGE,default=1440"`                              // Cookie MaxAge, Defaults to 1 day
	CookieName            string   `env:"COOKIE_NAME,default=sproxy_session"`                       // The name of the cookie
	ProxyURL              *url.URL `env:"PROXY_URL,default=http://localhost:8000/"`                 // URL to Proxy to
	CallbackPath          string   `env:"CALLBACK_PATH,default=/auth/callback/google"`              // Callback URL
	HealthCheckPath       string   `env:"HEALTH_CHECK_PATH,default=/en-US/static/html/credit.html"` // Health Check path in splunk, this path is proxied w/o auth. The default is a static file served by the splunk web server
	EmailSuffix           string   `env:"EMAIL_SUFFIX,default=@heroku.com"`                         // Required email suffix. Emails w/o this suffix will not be let in
	StateToken            string   `env:"STATE_TOKEN,required"`                                     // Token used when communicating with Google Oauth2 provider
}

var config configuration

func newOauth2Config() *oauth2.Config {
	return &oauth2.Config{
		ClientID:     config.ClientID,
		ClientSecret: config.ClientSecret,
		RedirectURL:  "https://" + config.DNSName + config.CallbackPath,
		Scopes:       []string{"https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"},
		Endpoint:     google.Endpoint,
	}
}

// Authorize the user based on the email stored in the named session and matching the suffix. If the email doesn't exist
// in the session or if the 'OpenIDUser' isn't set in the session, then redirect, otherwise set the X-Openid-User
// header to what was stored in the session.
func authorize(s sessions.Store, h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		logPrefix := fmt.Sprintf("app=sproxy fn=authorize method=%s path=%s\n",
			r.Method, r.URL.Path)

		session, err := s.Get(r, config.CookieName)
		if err != nil {
			log.Printf("%s auth=failed error=%q\n", logPrefix, err.Error())
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		o2c := newOauth2Config()

		redirect := o2c.AuthCodeURL(config.StateToken, oauth2.AccessTypeOnline)

		session.Values["return_to"] = r.URL.RequestURI()
		session.Save(r, w)

		email, ok := session.Values["email"]
		if !ok || email == nil || !strings.HasSuffix(email.(string), config.EmailSuffix) {
			if email == nil {
				email = ""
			}
			log.Printf("%s auth=failed missing=Email email=%s redirect=%s\n", logPrefix, email.(string), redirect)
			http.Redirect(w, r, redirect, http.StatusTemporaryRedirect)
			return
		}

		openIDUser, ok := session.Values["OpenIDUser"]
		if !ok || openIDUser == nil {
			if openIDUser == nil {
				openIDUser = ""
			}
			log.Printf("%s auth=failed missing=OpenIDUser user=%s redirect=%s\n", logPrefix, openIDUser.(string), redirect)
			http.Redirect(w, r, redirect, http.StatusFound)
			return
		}

		r.Header.Set("X-Openid-User", openIDUser.(string))
		h.ServeHTTP(w, r)
	})
}

// enforceXForwardedProto header is set before processing the handler.
// If it's not then redirect to the https version of the URL.
func enforceXForwardedProto(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		xff := r.Header.Get("X-Forwarded-Proto")
		if xff == "https" {
			h.ServeHTTP(w, r)
			return
		}

		u := new(url.URL)
		*u = *r.URL
		u.Scheme = "https"
		if u.Host == "" {
			u.Host = r.Host
		}

		http.Redirect(w, r, u.String(), http.StatusFound)
	})
}

// Set the OpenIDUser and other session values based on the data from Google
func handleGoogleCallback(s sessions.Store) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		logPrefix := fmt.Sprintf("app=sproxy fn=callback method=%s path=%s\n",
			r.Method, r.URL.Path)

		o2c := newOauth2Config()

		if v := r.FormValue("state"); v != config.StateToken {
			log.Printf("%s callback=failed error=%s\n", logPrefix, fmt.Sprintf("Bad state token: %s", v))
			http.Error(w, "Bad Request", http.StatusBadRequest)
			return
		}

		ctx := context.Background()
		t, err := o2c.Exchange(r.Context(), r.FormValue("code"))
		if err != nil {
			log.Printf("%s callback=failed error=%s\n", logPrefix, err.Error())
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
		gp, err := fetchGoogleProfile(ctx, t, o2c)
		if err != nil {
			log.Printf("%s %s\n", logPrefix, err.Error())
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		if gp.Email == "" || !strings.HasSuffix(gp.Email, config.EmailSuffix) {
			err := fmt.Errorf("Invalid Google Profile Email: %q", gp.Email)
			log.Printf("%s callback=failed error=%s\n", logPrefix, err.Error())
			http.Error(w, err.Error(), http.StatusForbidden)
			return
		}

		session, err := s.Get(r, config.CookieName)
		if err != nil {
			log.Printf("%s callback=failed error=%s\n", logPrefix, err.Error())
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		session.Values["email"] = gp.Email
		session.Values["GoogleID"] = gp.ID

		parts := strings.SplitN(gp.Email, "@", 2)
		if len(parts) < 2 {
			err := fmt.Errorf("Unable to determine OpenIDUser from email %q", gp.Email)
			log.Printf("%s callback=failed error=%s\n", logPrefix, err.Error())
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		session.Values["OpenIDUser"] = strings.ToLower(parts[0])
		target, ok := session.Values["return_to"].(string)
		if !ok {
			target = "/"
		}

		if err := session.Save(r, w); err != nil {
			log.Printf("%s callback=failed error=%s\n", logPrefix, err.Error())
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		log.Printf("%s callback=successful\n", logPrefix)
		http.Redirect(w, r, target, http.StatusFound)
	})
}

func handleAuthLogout(s sessions.Store) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		logPrefix := fmt.Sprintf("app=sproxy fn=logout method=%s path=%s\n",
			r.Method, r.URL.Path)

		config.CookieMaxAge = -1
		session, err := s.Get(r, config.CookieName)
		if err != nil || session == nil {
			log.Printf("%s logout=failed error=%s\n", logPrefix, err.Error())
			return
		}

		// clear out session values
		//session.Values = map[interface{}]interface{}{}
		//store.Options.MaxAge = -1
		session.Save(r, w)

		log.Printf("%s logout=successful\n", logPrefix)
		http.Redirect(w, r, "/", http.StatusFound)
	})
}

func main() {
	if err := envdecode.Decode(&config); err != nil {
		log.Fatal(err)
	}

	switch len(config.SessionEncrypttionKey) {
	case 16, 24, 32:
	default:
		log.Fatal("Length of SESSION_ENCRYPTION_KEY is not 16, 24 or 32")
	}

	store := sessions.NewCookieStore([]byte(config.SessionSecret), []byte(config.SessionEncrypttionKey))
	store.Options.MaxAge = config.CookieMaxAge
	store.Options.Secure = true

	proxy := httputil.NewSingleHostReverseProxy(config.ProxyURL)

	// Handle Google Callback
	http.Handle(config.CallbackPath, handleGoogleCallback(store))

	// Health Check
	http.Handle(config.HealthCheckPath, proxy)

	// Base HTTP Request handler
	http.Handle("/", enforceXForwardedProto(authorize(store, proxy)))

	http.Handle("/auth/logout", handleAuthLogout(store))
	http.Handle("/logout", handleAuthLogout(store))

	host := os.Getenv("HOST")

	port := os.Getenv("PORT")
	if port == "" {
		port = "5000"
	}

	listen := host + ":" + port
	log.Println("Listening on", listen)

	log.Fatal(http.ListenAndServe(listen, nil))
}
<commit_msg>removing logout func<commit_after>package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
	"strings"

	"github.com/gorilla/sessions"
	"github.com/joeshaw/envdecode"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
)

type configuration struct {
	ClientID              string   `env:"CLIENT_ID,required"`                                       // Google Client ID
	ClientSecret          string   `env:"CLIENT_SECRET,required"`                                   // Google Client Secret
	SessionSecret         string   `env:"SESSION_SECRET,required"`                                  // Random session auth key
	SessionEncrypttionKey string   `env:"SESSION_ENCRYPTION_KEY,required"`                          // Random session encryption key
	DNSName               string   `env:"DNS_NAME,required"`                                        // Public facing DNS Hostname
	CookieMaxAge          int      `env:"COOKIE_MAX_AGE,default=1440"`                              // Cookie MaxAge, Defaults to 1 day
	CookieName            string   `env:"COOKIE_NAME,default=sproxy_session"`                       // The name of the cookie
	ProxyURL              *url.URL `env:"PROXY_URL,default=http://localhost:8000/"`                 // URL to Proxy to
	CallbackPath          string   `env:"CALLBACK_PATH,default=/auth/callback/google"`              // Callback URL
	HealthCheckPath       string   `env:"HEALTH_CHECK_PATH,default=/en-US/static/html/credit.html"` // Health Check path in splunk, this path is proxied w/o auth. The default is a static file served by the splunk web server
	EmailSuffix           string   `env:"EMAIL_SUFFIX,default=@heroku.com"`                         // Required email suffix. Emails w/o this suffix will not be let in
	StateToken            string   `env:"STATE_TOKEN,required"`                                     // Token used when communicating with Google Oauth2 provider
}

var config configuration

func newOauth2Config() *oauth2.Config {
	return &oauth2.Config{
		ClientID:     config.ClientID,
		ClientSecret: config.ClientSecret,
		RedirectURL:  "https://" + config.DNSName + config.CallbackPath,
		Scopes:       []string{"https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"},
		Endpoint:     google.Endpoint,
	}
}

// Authorize the user based on the email stored in the named session and matching the suffix. If the email doesn't exist
// in the session or if the 'OpenIDUser' isn't set in the session, then redirect, otherwise set the X-Openid-User
// header to what was stored in the session.
func authorize(s sessions.Store, h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		logPrefix := fmt.Sprintf("app=sproxy fn=authorize method=%s path=%s\n",
			r.Method, r.URL.Path)

		session, err := s.Get(r, config.CookieName)
		if err != nil {
			log.Printf("%s auth=failed error=%q\n", logPrefix, err.Error())
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		o2c := newOauth2Config()

		redirect := o2c.AuthCodeURL(config.StateToken, oauth2.AccessTypeOnline)

		session.Values["return_to"] = r.URL.RequestURI()
		session.Save(r, w)

		email, ok := session.Values["email"]
		if !ok || email == nil || !strings.HasSuffix(email.(string), config.EmailSuffix) {
			if email == nil {
				email = ""
			}
			log.Printf("%s auth=failed missing=Email email=%s redirect=%s\n", logPrefix, email.(string), redirect)
			http.Redirect(w, r, redirect, http.StatusTemporaryRedirect)
			return
		}

		openIDUser, ok := session.Values["OpenIDUser"]
		if !ok || openIDUser == nil {
			if openIDUser == nil {
				openIDUser = ""
			}
			log.Printf("%s auth=failed missing=OpenIDUser user=%s redirect=%s\n", logPrefix, openIDUser.(string), redirect)
			http.Redirect(w, r, redirect, http.StatusFound)
			return
		}

		r.Header.Set("X-Openid-User", openIDUser.(string))
		h.ServeHTTP(w, r)
	})
}

// enforceXForwardedProto header is set before processing the handler.
// If it's not then redirect to the https version of the URL.
func enforceXForwardedProto(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		xff := r.Header.Get("X-Forwarded-Proto")
		if xff == "https" {
			h.ServeHTTP(w, r)
			return
		}

		u := new(url.URL)
		*u = *r.URL
		u.Scheme = "https"
		if u.Host == "" {
			u.Host = r.Host
		}

		http.Redirect(w, r, u.String(), http.StatusFound)
	})
}

// Set the OpenIDUser and other session values based on the data from Google
func handleGoogleCallback(s sessions.Store) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		logPrefix := fmt.Sprintf("app=sproxy fn=callback method=%s path=%s\n",
			r.Method, r.URL.Path)

		o2c := newOauth2Config()

		if v := r.FormValue("state"); v != config.StateToken {
			log.Printf("%s callback=failed error=%s\n", logPrefix, fmt.Sprintf("Bad state token: %s", v))
			http.Error(w, "Bad Request", http.StatusBadRequest)
			return
		}

		ctx := context.Background()
		t, err := o2c.Exchange(r.Context(), r.FormValue("code"))
		if err != nil {
			log.Printf("%s callback=failed error=%s\n", logPrefix, err.Error())
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
		gp, err := fetchGoogleProfile(ctx, t, o2c)
		if err != nil {
			log.Printf("%s %s\n", logPrefix, err.Error())
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		if gp.Email == "" || !strings.HasSuffix(gp.Email, config.EmailSuffix) {
			err := fmt.Errorf("Invalid Google Profile Email: %q", gp.Email)
			log.Printf("%s callback=failed error=%s\n", logPrefix, err.Error())
			http.Error(w, err.Error(), http.StatusForbidden)
			return
		}

		session, err := s.Get(r, config.CookieName)
		if err != nil {
			log.Printf("%s callback=failed error=%s\n", logPrefix, err.Error())
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		session.Values["email"] = gp.Email
		session.Values["GoogleID"] = gp.ID

		parts := strings.SplitN(gp.Email, "@", 2)
		if len(parts) < 2 {
			err := fmt.Errorf("Unable to determine OpenIDUser from email %q", gp.Email)
			log.Printf("%s callback=failed error=%s\n", logPrefix, err.Error())
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		session.Values["OpenIDUser"] = strings.ToLower(parts[0])
		target, ok := session.Values["return_to"].(string)
		if !ok {
			target = "/"
		}

		if err := session.Save(r, w); err != nil {
			log.Printf("%s callback=failed error=%s\n", logPrefix, err.Error())
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		log.Printf("%s callback=successful\n", logPrefix)
		http.Redirect(w, r, target, http.StatusFound)
	})
}

func main() {
	if err := envdecode.Decode(&config); err != nil {
		log.Fatal(err)
	}

	switch len(config.SessionEncrypttionKey) {
	case 16, 24, 32:
	default:
		log.Fatal("Length of SESSION_ENCRYPTION_KEY is not 16, 24 or 32")
	}

	store := sessions.NewCookieStore([]byte(config.SessionSecret), []byte(config.SessionEncrypttionKey))
	store.Options.MaxAge = config.CookieMaxAge
	store.Options.Secure = true

	proxy := httputil.NewSingleHostReverseProxy(config.ProxyURL)

	// Handle Google Callback
	http.Handle(config.CallbackPath, handleGoogleCallback(store))

	// Health Check
	http.Handle(config.HealthCheckPath, proxy)

	// Base HTTP Request handler
	http.Handle("/", enforceXForwardedProto(authorize(store, proxy)))

	host := os.Getenv("HOST")

	port := os.Getenv("PORT")
	if port == "" {
		port = "5000"
	}

	listen := host + ":" + port
	log.Println("Listening on", listen)

	log.Fatal(http.ListenAndServe(listen, nil))
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/Masterminds/semver"
)

var version = semver.MustParse("v1.3.5")

func main() {
	flag.Parse()
	if err := ensureTooldir(); err != nil {
		fatal("failed to locate or create tool directory", err)
	}
	cmd, tool := parseArgs()

	if cmd == "version" {
		fmt.Fprintf(os.Stdout, "retool %s", version)
		os.Exit(0)
	}

	if !specExists() {
		if cmd == "add" {
			err := writeBlankSpec()
			if err != nil {
				fatal("failed to write blank spec", err)
			}
		} else {
			fatal("tools.json does not yet exist. You need to add a tool first with 'retool add'", nil)
		}
	}

	s, err := read()
	if err != nil {
		fatal("failed to load tools.json", err)
	}

	switch cmd {
	case "add":
		s.add(tool)
	case "upgrade":
		s.upgrade(tool)
	case "remove":
		s.remove(tool)
	case "build":
		s.build()
	case "sync":
		s.sync()
	case "do":
		s.sync()
		do()
	case "clean":
		log("the clean subcommand is deprecated and has no effect")
	default:
		fatal(fmt.Sprintf("unknown cmd %q", cmd), nil)
	}
}
<commit_msg>Version v1.3.6<commit_after>package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/Masterminds/semver"
)

var version = semver.MustParse("v1.3.6")

func main() {
	flag.Parse()
	if err := ensureTooldir(); err != nil {
		fatal("failed to locate or create tool directory", err)
	}
	cmd, tool := parseArgs()

	if cmd == "version" {
		fmt.Fprintf(os.Stdout, "retool %s", version)
		os.Exit(0)
	}

	if !specExists() {
		if cmd == "add" {
			err := writeBlankSpec()
			if err != nil {
				fatal("failed to write blank spec", err)
			}
		} else {
			fatal("tools.json does not yet exist. You need to add a tool first with 'retool add'", nil)
		}
	}

	s, err := read()
	if err != nil {
		fatal("failed to load tools.json", err)
	}

	switch cmd {
	case "add":
		s.add(tool)
	case "upgrade":
		s.upgrade(tool)
	case "remove":
		s.remove(tool)
	case "build":
		s.build()
	case "sync":
		s.sync()
	case "do":
		s.sync()
		do()
	case "clean":
		log("the clean subcommand is deprecated and has no effect")
	default:
		fatal(fmt.Sprintf("unknown cmd %q", cmd), nil)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"regexp"
	"reflect"
	"strings"
	"os"
)

type config_paths struct {
	flannel_conf_path        string
	master_conf_path         string
	node_conf_path           string
	validity_check_conf_path string
}

type DefaultOpts struct {
	Flannel_opts         []string `yaml:"flannel_options"`
	Kubelet_opts         []string `yaml:"kubelet_options"`
	Kube_proxy_opts      []string `yaml:"kube_proxy_options"`
	Kube_apiserver_opts  []string `yaml:"kube_apiserver_options"`
	Kube_controller_opts []string `yaml:"kube_controller_manager_options"`
	Kube_scheduller_opts []string `yaml:"kube_scheduler_options"`
}

type ValidityOpts struct {
	Args_check struct {
			   Flannel_opts         []string `yaml:"flannel_options"`
			   Kubelet_opts         []string `yaml:"kubelet_options"`
			   Kube_proxy_opts      []string `yaml:"kube_proxy_options"`
			   Kube_apiserver_opts  []string `yaml:"kube_apiserver_options"`
			   Kube_controller_opts []string `yaml:"kube_controller_manager_options"`
			   Kube_scheduller_opts []string `yasml:"kube_scheduler_options"`
		   } `yaml: args_check`
}

//const relative_prefix_path = "/home/k8s_kdt/kdt/"
const relative_prefix_path = "D:\\go_src\\contrib\\ansible\\"

func main() {
	var conf_paths = config_paths{
		flannel_conf_path:        "roles/flannel/defaults/main.yaml",
		master_conf_path:         "roles/master/defaults/main.yml",
		node_conf_path:           "roles/node/defaults/main.yml",
		validity_check_conf_path: "roles/validity-check/defaults/main.yml",
	}

	paths := [2]string{conf_paths.validity_check_conf_path, conf_paths.flannel_conf_path}
	isEqual, _ := CompareArgs(paths, ValidityOpts{}, DefaultOpts{}, "flannel")
	fmt.Println("flannel flags keep consistency? ", isEqual)
	if !isEqual {
		os.Exit(-1)
	}
}

func CompareArgs(file_path [2]string, validity_opts ValidityOpts, default_opts DefaultOpts, component_name string) (bool bool, err error) {
	fmt.Printf("Check %s args in path %s and path %s.\n", component_name, file_path[0], file_path[1])
	field_name := strings.Title(component_name + "_opts")
	validity_value, default_value, err := yaml_unmarshal(file_path, validity_opts, default_opts, field_name)
	if err != nil {
		return false, err
	}

	fmt.Printf("%s validity args are %v\n", component_name, validity_value)
	fmt.Printf("%s default args are %v\n", component_name, default_value)
	if isInclude(validity_value, default_value) && isInclude(default_value, validity_value) {
		return true, nil
	}
	return false, nil
}

func yaml_unmarshal(file_path [2]string, validity_opts ValidityOpts, default_opts DefaultOpts, field_name string) ([]string, []string, error) {
	data, err := ioutil.ReadFile(relative_prefix_path + file_path[0])
	if err != nil {
		return []string{}, []string{}, fmt.Errorf("Reading config file failed: %v", err)
	}
	yaml.Unmarshal(data, &validity_opts)

	data, err = ioutil.ReadFile(relative_prefix_path + file_path[1])
	if err != nil {
		return []string{}, []string{}, fmt.Errorf("Reading config file failed: %v", err)
	}
	yaml.Unmarshal(data, &default_opts)

	validity_value := reflect.ValueOf(validity_opts).FieldByName("Args_check").FieldByName(field_name).Interface()
	default_value := reflect.ValueOf(default_opts).FieldByName(field_name).Interface()
	val, _ := validity_value.([]string)
	def, _ := default_value.([]string)
	return val, def, nil
}

func isInclude(args0, args1 []string) bool {
	regx := regexp.MustCompile(`s*-+([^s=]+).*`)
	for _, arg0 := range args0 {
		include := false
		for _, arg1 := range args1 {
			if regx.FindStringSubmatch(arg0)[1] == regx.FindStringSubmatch(arg1)[1] {
				include = true
				break
			}
		}
		if !include {
			return include
		}
	}
	return true
}
<commit_msg>format output<commit_after>package main

import (
	"fmt"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"regexp"
	"reflect"
	"strings"
	"os"
)

type config_paths struct {
	flannel_conf_path        string
	master_conf_path         string
	node_conf_path           string
	validity_check_conf_path string
}

type DefaultOpts struct {
	Flannel_opts         []string `yaml:"flannel_options"`
	Kubelet_opts         []string `yaml:"kubelet_options"`
	Kube_proxy_opts      []string `yaml:"kube_proxy_options"`
	Kube_apiserver_opts  []string `yaml:"kube_apiserver_options"`
	Kube_controller_opts []string `yaml:"kube_controller_manager_options"`
	Kube_scheduller_opts []string `yaml:"kube_scheduler_options"`
}

type ValidityOpts struct {
	Args_check struct {
			   Flannel_opts         []string `yaml:"flannel_options"`
			   Kubelet_opts         []string `yaml:"kubelet_options"`
			   Kube_proxy_opts      []string `yaml:"kube_proxy_options"`
			   Kube_apiserver_opts  []string `yaml:"kube_apiserver_options"`
			   Kube_controller_opts []string `yaml:"kube_controller_manager_options"`
			   Kube_scheduller_opts []string `yasml:"kube_scheduler_options"`
		   } `yaml: args_check`
}

//const relative_prefix_path = "/home/k8s_kdt/kdt/"
const relative_prefix_path = "D:\\go_src\\contrib\\ansible\\"

func main() {
	var conf_paths = config_paths{
		flannel_conf_path:        "roles/flannel/defaults/main.yaml",
		master_conf_path:         "roles/master/defaults/main.yml",
		node_conf_path:           "roles/node/defaults/main.yml",
		validity_check_conf_path: "roles/validity-check/defaults/main.yml",
	}

	paths := [2]string{conf_paths.validity_check_conf_path, conf_paths.flannel_conf_path}
	isEqual, _ := CompareArgs(paths, ValidityOpts{}, DefaultOpts{}, "flannel")
	fmt.Println("flannel flags keep consistency?", isEqual)
	if !isEqual {
		os.Exit(1)
	}
}

func CompareArgs(file_path [2]string, validity_opts ValidityOpts, default_opts DefaultOpts, component_name string) (bool bool, err error) {
	fmt.Printf("Check %s args in \"%s\" and \"%s\".\n", component_name, file_path[0], file_path[1])
	field_name := strings.Title(component_name + "_opts")
	validity_value, default_value, err := yaml_unmarshal(file_path, validity_opts, default_opts, field_name)
	if err != nil {
		return false, err
	}

	fmt.Printf("%s validity args are %v\n", component_name, validity_value)
	fmt.Printf("%s default args are %v\n", component_name, default_value)
	if isInclude(validity_value, default_value) && isInclude(default_value, validity_value) {
		return true, nil
	}
	return false, nil
}

func yaml_unmarshal(file_path [2]string, validity_opts ValidityOpts, default_opts DefaultOpts, field_name string) ([]string, []string, error) {
	data, err := ioutil.ReadFile(relative_prefix_path + file_path[0])
	if err != nil {
		return []string{}, []string{}, fmt.Errorf("Reading config file failed: %v", err)
	}
	yaml.Unmarshal(data, &validity_opts)

	data, err = ioutil.ReadFile(relative_prefix_path + file_path[1])
	if err != nil {
		return []string{}, []string{}, fmt.Errorf("Reading config file failed: %v", err)
	}
	yaml.Unmarshal(data, &default_opts)

	validity_value := reflect.ValueOf(validity_opts).FieldByName("Args_check").FieldByName(field_name).Interface()
	default_value := reflect.ValueOf(default_opts).FieldByName(field_name).Interface()
	val, _ := validity_value.([]string)
	def, _ := default_value.([]string)
	return val, def, nil
}

func isInclude(args0, args1 []string) bool {
	regx := regexp.MustCompile(`s*-+([^s=]+).*`)
	for _, arg0 := range args0 {
		include := false
		for _, arg1 := range args1 {
			if regx.FindStringSubmatch(arg0)[1] == regx.FindStringSubmatch(arg1)[1] {
				include = true
				break
			}
		}
		if !include {
			return include
		}
	}
	return true
}
<|endoftext|>


<commit_before>package main

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

	"github.com/olekukonko/tablewriter"
)

var (
	version   string
	branch    string
	revision  string
	buildDate string
	goVersion = runtime.Version()
)

func main() {

	fmt.Printf("[estafette] Starting estafette-ci-builder (version=%v, branch=%v, revision=%v, buildDate=%v, goVersion=%v)\n", version, branch, revision, buildDate, goVersion)

	// read yaml
	manifest, err := readManifest(".estafette.yaml")
	if err != nil {
		log.Fatal(err)
	}

	// get current working directory
	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("[estafette] Running %v pipelines\n", len(manifest.Pipelines))

	err = setEstafetteGlobalEnvvars()
	if err != nil {
		log.Fatal(err)
	}

	envvars := collectEstafetteEnvvars(manifest)

	result := runPipelines(manifest, dir, envvars)

	renderStats(result)

	handleExit(result)
}

func handleExit(result estafetteRunPipelinesResult) {

	if result.HasErrors() {
		os.Exit(1)
	}

	os.Exit(0)
}

func renderStats(result estafetteRunPipelinesResult) {

	data := make([][]string, 0)

	dockerPullDurationTotal := 0.0
	dockerRunDurationTotal := 0.0
	var dockerImageSizeTotal int64

	for _, s := range result.PipelineResults {

		dockerImageSize := fmt.Sprintf("%v", s.DockerImageSize/1024/1024)
		dockerPullDuration := fmt.Sprintf("%.0f", s.DockerPullDuration.Seconds())

		if s.IsDockerImagePulled {
			dockerImageSize = ""
			dockerPullDuration = ""
		}

		detail := ""
		if s.HasErrors() {
			for _, err := range s.Errors() {
				detail += err.Error()
			}
		}

		data = append(data, []string{
			s.Pipeline.Name,
			s.Pipeline.ContainerImage,
			dockerImageSize,
			dockerPullDuration,
			fmt.Sprintf("%.0f", s.DockerRunDuration.Seconds()),
			fmt.Sprintf("%.0f", s.DockerPullDuration.Seconds()+s.DockerRunDuration.Seconds()),
			s.Status,
			detail,
		})

		dockerPullDurationTotal += s.DockerPullDuration.Seconds()
		dockerRunDurationTotal += s.DockerRunDuration.Seconds()
		dockerImageSizeTotal += s.DockerImageSize
	}

	fmt.Println("")
	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Pipeline", "Image", "Size (MB)", "Pull (s)", "Run (s)", "Total (s)", "Status", "Detail"})
	table.SetFooter([]string{"", "Total", fmt.Sprintf("%v", dockerImageSizeTotal/1024/1024), fmt.Sprintf("%.0f", dockerPullDurationTotal), fmt.Sprintf("%.0f", dockerRunDurationTotal), fmt.Sprintf("%.0f", dockerPullDurationTotal+dockerRunDurationTotal), "", ""})
	table.SetBorder(false)
	table.AppendBulk(data)
	table.Render()
	fmt.Println("")
}
<commit_msg>print combined status in footer<commit_after>package main

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

	"github.com/olekukonko/tablewriter"
)

var (
	version   string
	branch    string
	revision  string
	buildDate string
	goVersion = runtime.Version()
)

func main() {

	fmt.Printf("[estafette] Starting estafette-ci-builder (version=%v, branch=%v, revision=%v, buildDate=%v, goVersion=%v)\n", version, branch, revision, buildDate, goVersion)

	// read yaml
	manifest, err := readManifest(".estafette.yaml")
	if err != nil {
		log.Fatal(err)
	}

	// get current working directory
	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("[estafette] Running %v pipelines\n", len(manifest.Pipelines))

	err = setEstafetteGlobalEnvvars()
	if err != nil {
		log.Fatal(err)
	}

	envvars := collectEstafetteEnvvars(manifest)

	result := runPipelines(manifest, dir, envvars)

	renderStats(result)

	handleExit(result)
}

func handleExit(result estafetteRunPipelinesResult) {

	if result.HasErrors() {
		os.Exit(1)
	}

	os.Exit(0)
}

func renderStats(result estafetteRunPipelinesResult) {

	data := make([][]string, 0)

	dockerPullDurationTotal := 0.0
	dockerRunDurationTotal := 0.0
	var dockerImageSizeTotal int64
	statusTotal := "SUCCEEDED"

	for _, s := range result.PipelineResults {

		dockerImageSize := fmt.Sprintf("%v", s.DockerImageSize/1024/1024)
		dockerPullDuration := fmt.Sprintf("%.0f", s.DockerPullDuration.Seconds())

		if s.IsDockerImagePulled {
			dockerImageSize = ""
			dockerPullDuration = ""
		}

		detail := ""
		if s.HasErrors() {
			for _, err := range s.Errors() {
				detail += err.Error()
			}
		}

		if s.Status == "FAILED" {
			statusTotal = "FAILED"
		}

		data = append(data, []string{
			s.Pipeline.Name,
			s.Pipeline.ContainerImage,
			dockerImageSize,
			dockerPullDuration,
			fmt.Sprintf("%.0f", s.DockerRunDuration.Seconds()),
			fmt.Sprintf("%.0f", s.DockerPullDuration.Seconds()+s.DockerRunDuration.Seconds()),
			s.Status,
			detail,
		})

		dockerPullDurationTotal += s.DockerPullDuration.Seconds()
		dockerRunDurationTotal += s.DockerRunDuration.Seconds()
		dockerImageSizeTotal += s.DockerImageSize
	}

	fmt.Println("")
	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Pipeline", "Image", "Size (MB)", "Pull (s)", "Run (s)", "Total (s)", "Status", "Detail"})
	table.SetFooter([]string{"", "Total", fmt.Sprintf("%v", dockerImageSizeTotal/1024/1024), fmt.Sprintf("%.0f", dockerPullDurationTotal), fmt.Sprintf("%.0f", dockerRunDurationTotal), fmt.Sprintf("%.0f", dockerPullDurationTotal+dockerRunDurationTotal), statusTotal, ""})
	table.SetBorder(false)
	table.AppendBulk(data)
	table.Render()
	fmt.Println("")
}
<|endoftext|>