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

package cmd

import (
	"path/filepath"
	"sort"
	"strings"

	"github.com/minio/cli"
	"github.com/posener/complete"
)

// fsComplete knows how to complete file/dir names by the given path
type fsComplete struct{}

func (fs fsComplete) Predict(a complete.Args) (prediction []string) {
	return complete.PredictFiles("*").Predict(a)
}

// Complete S3 path. If the prediction result is only one directory,
// then recursively scans it. This is needed to satisfy posener/complete
// (look at posener/complete.PredictFiles)
func completeS3Path(s3Path string) (prediction []string) {

	// Convert alias/bucket/incompl to alias/bucket/ to list its contents
	parentDirPath := filepath.Dir(s3Path) + "/"
	clnt, err := newClient(parentDirPath)
	if err != nil {
		return nil
	}

	// Calculate alias from the path
	alias := splitStr(s3Path, "/", 3)[0]

	// List dirPath content and only pick elements that corresponds
	// to the path that we want to complete
	for content := range clnt.List(false, false, DirFirst) {
		completeS3Path := alias + getKey(content)
		if content.Type.IsDir() {
			if !strings.HasSuffix(completeS3Path, "/") {
				completeS3Path += "/"
			}
		}
		if strings.HasPrefix(completeS3Path, s3Path) {
			prediction = append(prediction, completeS3Path)
		}
	}

	// If completion found only one directory, recursively scan it.
	if len(prediction) == 1 && strings.HasSuffix(prediction[0], "/") {
		prediction = append(prediction, completeS3Path(prediction[0])...)
	}

	return
}

// s3Complete knows how to complete an mc s3 path
type s3Complete struct{}

func (s3 s3Complete) Predict(a complete.Args) (prediction []string) {
	defer func() {
		sort.Strings(prediction)
	}()

	loadMcConfig = loadMcConfigFactory()
	conf, err := loadMcConfig()
	if err != nil {
		return nil
	}

	arg := a.Last

	if strings.IndexByte(arg, '/') == -1 {
		// Only predict alias since '/' is not found
		for alias := range conf.Hosts {
			if strings.HasPrefix(alias, arg) {
				prediction = append(prediction, alias+"/")
			}
		}
		if len(prediction) == 1 && strings.HasSuffix(prediction[0], "/") {
			prediction = append(prediction, completeS3Path(prediction[0])...)
		}
	} else {
		// Predict S3 path
		prediction = completeS3Path(arg)
	}

	return
}

// aliasComplete only completes aliases
type aliasComplete struct{}

func (al aliasComplete) Predict(a complete.Args) (prediction []string) {
	defer func() {
		sort.Strings(prediction)
	}()

	loadMcConfig = loadMcConfigFactory()
	conf, err := loadMcConfig()
	if err != nil {
		return nil
	}

	arg := a.Last
	for alias := range conf.Hosts {
		if strings.HasPrefix(alias, arg) {
			prediction = append(prediction, alias+"/")
		}
	}

	return
}

var s3Completer = s3Complete{}
var aliasCompleter = aliasComplete{}
var fsCompleter = fsComplete{}

// The list of all commands supported by mc with their mapping
// with their bash completer function
var completeCmds = map[string]complete.Predictor{
	"/ls":     complete.PredictOr(s3Completer, fsCompleter),
	"/cp":     complete.PredictOr(s3Completer, fsCompleter),
	"/rm":     complete.PredictOr(s3Completer, fsCompleter),
	"/cat":    complete.PredictOr(s3Completer, fsCompleter),
	"/head":   complete.PredictOr(s3Completer, fsCompleter),
	"/diff":   complete.PredictOr(s3Completer, fsCompleter),
	"/find":   complete.PredictOr(s3Completer, fsCompleter),
	"/mirror": complete.PredictOr(s3Completer, fsCompleter),
	"/pipe":   complete.PredictOr(s3Completer, fsCompleter),
	"/stat":   complete.PredictOr(s3Completer, fsCompleter),
	"/watch":  complete.PredictOr(s3Completer, fsCompleter),
	"/policy": complete.PredictOr(s3Completer, fsCompleter),

	"/mb":  aliasCompleter,
	"/sql": s3Completer,

	"/admin/info":       aliasCompleter,
	"/admin/heal":       s3Completer,
	"/admin/credential": aliasCompleter,

	"/admin/config/get": aliasCompleter,
	"/admin/config/set": aliasCompleter,

	"/admin/service/status":  aliasCompleter,
	"/admin/service/restart": aliasCompleter,
	"/admin/service/stop":    aliasCompleter,

	"/admin/profile/start": aliasCompleter,
	"/admin/profile/stop":  aliasCompleter,

	"/admin/policy/add":    aliasCompleter,
	"/admin/policy/list":   aliasCompleter,
	"/admin/policy/remove": aliasCompleter,

	"/admin/user/add":     aliasCompleter,
	"/admin/user/policy:": aliasCompleter,
	"/admin/user/disable": aliasCompleter,
	"/admin/user/enable":  aliasCompleter,
	"/admin/user/list":    aliasCompleter,
	"/admin/user/remove":  aliasCompleter,

	"/event/add":    aliasCompleter,
	"/event/list":   aliasCompleter,
	"/event/remove": aliasCompleter,

	"/session/clear":  nil,
	"/session/list":   nil,
	"/session/resume": nil,

	"/share/download": nil,
	"/share/list":     nil,
	"/share/upload":   nil,

	"/config/host/add":    nil,
	"/config/host/list":   aliasCompleter,
	"/config/host/remove": aliasCompleter,

	"/update":  nil,
	"/version": nil,
}

// flagsToCompleteFlags transforms a cli.Flag to complete.Flags
// understood by posener/complete library.
func flagsToCompleteFlags(flags []cli.Flag) complete.Flags {
	var complFlags = make(complete.Flags)
	for _, f := range flags {
		for _, s := range strings.Split(f.GetName(), ",") {
			var flagName string
			s = strings.TrimSpace(s)
			if len(s) == 1 {
				flagName = "-" + s
			} else {
				flagName = "--" + s
			}
			complFlags[flagName] = complete.PredictNothing
		}
	}
	return complFlags
}

// This function recursively transforms cli.Command to complete.Command
// understood by posener/complete library.
func cmdToCompleteCmd(cmd cli.Command, parentPath string) complete.Command {
	var complCmd complete.Command
	complCmd.Sub = make(complete.Commands)

	for _, subCmd := range cmd.Subcommands {
		complCmd.Sub[subCmd.Name] = cmdToCompleteCmd(subCmd, parentPath+"/"+cmd.Name)
	}

	complCmd.Flags = flagsToCompleteFlags(cmd.Flags)
	complCmd.Args = completeCmds[parentPath+"/"+cmd.Name]
	return complCmd
}

// Main function to answer to bash completion calls
func mainComplete() error {
	// Recursively register all commands and subcommands
	// along with global and local flags
	var complCmds = make(complete.Commands)
	for _, cmd := range appCmds {
		complCmds[cmd.Name] = cmdToCompleteCmd(cmd, "")
	}
	complFlags := flagsToCompleteFlags(globalFlags)
	mcComplete := complete.Command{
		Sub:         complCmds,
		GlobalFlags: complFlags,
	}
	// Answer to bash completion call
	complete.New("mc", mcComplete).Run()
	return nil
}
<commit_msg>complete: Add support of rb completion (#2689)<commit_after>/*
 * Minio Client (C) 2019 Minio, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cmd

import (
	"path/filepath"
	"sort"
	"strings"

	"github.com/minio/cli"
	"github.com/posener/complete"
)

// fsComplete knows how to complete file/dir names by the given path
type fsComplete struct{}

func (fs fsComplete) Predict(a complete.Args) (prediction []string) {
	return complete.PredictFiles("*").Predict(a)
}

// Complete S3 path. If the prediction result is only one directory,
// then recursively scans it. This is needed to satisfy posener/complete
// (look at posener/complete.PredictFiles)
func completeS3Path(s3Path string) (prediction []string) {

	// Convert alias/bucket/incompl to alias/bucket/ to list its contents
	parentDirPath := filepath.Dir(s3Path) + "/"
	clnt, err := newClient(parentDirPath)
	if err != nil {
		return nil
	}

	// Calculate alias from the path
	alias := splitStr(s3Path, "/", 3)[0]

	// List dirPath content and only pick elements that corresponds
	// to the path that we want to complete
	for content := range clnt.List(false, false, DirFirst) {
		completeS3Path := alias + getKey(content)
		if content.Type.IsDir() {
			if !strings.HasSuffix(completeS3Path, "/") {
				completeS3Path += "/"
			}
		}
		if strings.HasPrefix(completeS3Path, s3Path) {
			prediction = append(prediction, completeS3Path)
		}
	}

	// If completion found only one directory, recursively scan it.
	if len(prediction) == 1 && strings.HasSuffix(prediction[0], "/") {
		prediction = append(prediction, completeS3Path(prediction[0])...)
	}

	return
}

// s3Complete knows how to complete an mc s3 path
type s3Complete struct {
	deepLevel int
}

func (s3 s3Complete) Predict(a complete.Args) (prediction []string) {
	defer func() {
		sort.Strings(prediction)
	}()

	loadMcConfig = loadMcConfigFactory()
	conf, err := loadMcConfig()
	if err != nil {
		return nil
	}

	arg := a.Last

	if strings.IndexByte(arg, '/') == -1 {
		// Only predict alias since '/' is not found
		for alias := range conf.Hosts {
			if strings.HasPrefix(alias, arg) {
				prediction = append(prediction, alias+"/")
			}
		}
		if len(prediction) == 1 && strings.HasSuffix(prediction[0], "/") {
			prediction = append(prediction, completeS3Path(prediction[0])...)
		}
	} else {
		// Complete S3 path until the specified path deep level
		if s3.deepLevel > 0 {
			if strings.Count(arg, "/") >= s3.deepLevel {
				return []string{arg}
			}
		}
		// Predict S3 path
		prediction = completeS3Path(arg)
	}

	return
}

// aliasComplete only completes aliases
type aliasComplete struct{}

func (al aliasComplete) Predict(a complete.Args) (prediction []string) {
	defer func() {
		sort.Strings(prediction)
	}()

	loadMcConfig = loadMcConfigFactory()
	conf, err := loadMcConfig()
	if err != nil {
		return nil
	}

	arg := a.Last
	for alias := range conf.Hosts {
		if strings.HasPrefix(alias, arg) {
			prediction = append(prediction, alias+"/")
		}
	}

	return
}

var s3Completer = s3Complete{}
var aliasCompleter = aliasComplete{}
var fsCompleter = fsComplete{}

// The list of all commands supported by mc with their mapping
// with their bash completer function
var completeCmds = map[string]complete.Predictor{
	"/ls":     complete.PredictOr(s3Completer, fsCompleter),
	"/cp":     complete.PredictOr(s3Completer, fsCompleter),
	"/rm":     complete.PredictOr(s3Completer, fsCompleter),
	"/rb":     complete.PredictOr(s3Complete{deepLevel: 2}, fsCompleter),
	"/cat":    complete.PredictOr(s3Completer, fsCompleter),
	"/head":   complete.PredictOr(s3Completer, fsCompleter),
	"/diff":   complete.PredictOr(s3Completer, fsCompleter),
	"/find":   complete.PredictOr(s3Completer, fsCompleter),
	"/mirror": complete.PredictOr(s3Completer, fsCompleter),
	"/pipe":   complete.PredictOr(s3Completer, fsCompleter),
	"/stat":   complete.PredictOr(s3Completer, fsCompleter),
	"/watch":  complete.PredictOr(s3Completer, fsCompleter),
	"/policy": complete.PredictOr(s3Completer, fsCompleter),

	"/mb":  aliasCompleter,
	"/sql": s3Completer,

	"/admin/info":       aliasCompleter,
	"/admin/heal":       s3Completer,
	"/admin/credential": aliasCompleter,

	"/admin/config/get": aliasCompleter,
	"/admin/config/set": aliasCompleter,

	"/admin/service/status":  aliasCompleter,
	"/admin/service/restart": aliasCompleter,
	"/admin/service/stop":    aliasCompleter,

	"/admin/profile/start": aliasCompleter,
	"/admin/profile/stop":  aliasCompleter,

	"/admin/policy/add":    aliasCompleter,
	"/admin/policy/list":   aliasCompleter,
	"/admin/policy/remove": aliasCompleter,

	"/admin/user/add":     aliasCompleter,
	"/admin/user/policy:": aliasCompleter,
	"/admin/user/disable": aliasCompleter,
	"/admin/user/enable":  aliasCompleter,
	"/admin/user/list":    aliasCompleter,
	"/admin/user/remove":  aliasCompleter,

	"/event/add":    aliasCompleter,
	"/event/list":   aliasCompleter,
	"/event/remove": aliasCompleter,

	"/session/clear":  nil,
	"/session/list":   nil,
	"/session/resume": nil,

	"/share/download": nil,
	"/share/list":     nil,
	"/share/upload":   nil,

	"/config/host/add":    nil,
	"/config/host/list":   aliasCompleter,
	"/config/host/remove": aliasCompleter,

	"/update":  nil,
	"/version": nil,
}

// flagsToCompleteFlags transforms a cli.Flag to complete.Flags
// understood by posener/complete library.
func flagsToCompleteFlags(flags []cli.Flag) complete.Flags {
	var complFlags = make(complete.Flags)
	for _, f := range flags {
		for _, s := range strings.Split(f.GetName(), ",") {
			var flagName string
			s = strings.TrimSpace(s)
			if len(s) == 1 {
				flagName = "-" + s
			} else {
				flagName = "--" + s
			}
			complFlags[flagName] = complete.PredictNothing
		}
	}
	return complFlags
}

// This function recursively transforms cli.Command to complete.Command
// understood by posener/complete library.
func cmdToCompleteCmd(cmd cli.Command, parentPath string) complete.Command {
	var complCmd complete.Command
	complCmd.Sub = make(complete.Commands)

	for _, subCmd := range cmd.Subcommands {
		complCmd.Sub[subCmd.Name] = cmdToCompleteCmd(subCmd, parentPath+"/"+cmd.Name)
	}

	complCmd.Flags = flagsToCompleteFlags(cmd.Flags)
	complCmd.Args = completeCmds[parentPath+"/"+cmd.Name]
	return complCmd
}

// Main function to answer to bash completion calls
func mainComplete() error {
	// Recursively register all commands and subcommands
	// along with global and local flags
	var complCmds = make(complete.Commands)
	for _, cmd := range appCmds {
		complCmds[cmd.Name] = cmdToCompleteCmd(cmd, "")
	}
	complFlags := flagsToCompleteFlags(globalFlags)
	mcComplete := complete.Command{
		Sub:         complCmds,
		GlobalFlags: complFlags,
	}
	// Answer to bash completion call
	complete.New("mc", mcComplete).Run()
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/xyproto/env"
	"github.com/xyproto/kal"
	"github.com/xyproto/textoutput"
	"github.com/xyproto/vt100"
)

// centerPad will pad a string with spaces up to the given width,
// so that the string is centered.
func centerPad(s string, width int) string {
	l := len([]rune(s))
	if l < width {
		after := (width - l) / 2
		before := (width - l) - after
		return strings.Repeat(" ", before) + s + strings.Repeat(" ", after)
	}
	return s
}

// rightPad will pad the right side of a string with spaces
func rightPad(s string, width int) string {
	l := len([]rune(s))
	if l < width {
		after := (width - l)
		return s + strings.Repeat(" ", after)
	}
	return s
}

func centeredMonthYearString(cal kal.Calendar, year int, month time.Month, width int) string {
	s := cal.MonthName(month)
	s += fmt.Sprintf(" %d", year)
	return centerPad(s, width)
}

func weekdayPosition(mondayFirst bool, current time.Time) int {
	weekdayPosition := int(current.Weekday())
	if mondayFirst {
		weekdayPosition--
		if weekdayPosition < 0 {
			weekdayPosition = 6
		}
	}
	return weekdayPosition
}

// MonthCalendar returns a string that is a complete overview of the given month
func MonthCalendar(cal *kal.Calendar, givenYear int, givenMonth time.Month) string {

	mondayFirst := (*cal).MondayFirst()

	var descriptions, sb strings.Builder

	now := time.Now()
	current := time.Date(givenYear, givenMonth, 1, 0, 0, 0, 0, now.Location())

	// Add the week, if this is the current month
	var weekString string
	if now.Month() == givenMonth && now.Year() == givenYear {
		_, w := now.ISOWeek()
		weekString = "w" + strconv.Itoa(w)
	}

	// Month and year, centered
	sb.WriteString("<lightblue>" + centeredMonthYearString(*cal, givenYear, givenMonth, 20-len(weekString)) + "</lightblue><darkgray>" + weekString + "</darkgray>\n")

	// The shortened names of the week days
	sb.WriteString("<white>" + kal.TwoLetterDays(*cal, (*cal).MondayFirst()) + "</white>\n")

	// Indentation before the first day of the month
	sb.WriteString(strings.Repeat(" ", weekdayPosition(mondayFirst, current)*3))

	// Output all the numbers of the month, with linebreaks at appropriate locations
	for current.Month() == givenMonth {
		if current.Day() == now.Day() && current.Month() == now.Month() && current.Year() == now.Year() { // Today
			sb.WriteString(fmt.Sprintf(vt100.BackgroundBlue.String()+"<lightyellow>%2d</lightyellow> ", current.Day()))
		} else if isRedDay := kal.RedDay(*cal, current); current.Weekday() == time.Sunday || isRedDay { // Red day
			// TODO: Collect descriptions, then print them below
			sb.WriteString(fmt.Sprintf("<red>%2d</red> ", current.Day()))
			if isRedDay {
				if mondayFirst {
					descriptions.WriteString(fmt.Sprintf("<red>%2d. %s</red> - %s\n", current.Day(), (*cal).MonthName(givenMonth), kal.Describe(*cal, current)))
				} else {
					descriptions.WriteString(fmt.Sprintf("<red>%s %d</red> - %s\n", (*cal).MonthName(givenMonth), current.Day(), kal.Describe(*cal, current)))
				}
			}
		} else if kal.FlagDay(*cal, current) { // Flag day
			// TODO: Collect descriptions, then print them below
			sb.WriteString(fmt.Sprintf("<lightblue>%2d</lightblue> ", current.Day()))
			if mondayFirst {
				descriptions.WriteString(fmt.Sprintf("<lightblue>%2d. %s</lightblue> - %s (flaggdag)\n", current.Day(), (*cal).MonthName(givenMonth), kal.Describe(*cal, current)))
			} else {
				descriptions.WriteString(fmt.Sprintf("<lightblue>%s %d</lightblue> - %s (flaggdag)\n", (*cal).MonthName(givenMonth), current.Day(), kal.Describe(*cal, current)))
			}
		} else { // Ordinary day
			sb.WriteString(fmt.Sprintf("%2d ", current.Day()))
		}
		current = current.AddDate(0, 0, 1)

		if (mondayFirst && (current.Weekday() == time.Monday)) || (!mondayFirst && (current.Weekday() == time.Sunday)) {
			sb.WriteString("\n")
		}
	}

	calendarString := sb.String()
	if !strings.HasSuffix(calendarString, "\n") {
		calendarString += "\n"
	}

	if ds := descriptions.String(); len(ds) > 0 {
		return calendarString + "\n" + ds
	}

	return calendarString
}

func main() {
	now := time.Now()

	currentYear := now.Year()
	currentMonth := now.Month()

	// Check if the first given argument is a number. If yes, use that as the current year.
	if len(os.Args) > 2 {
		if m, err := strconv.Atoi(os.Args[1]); err == nil && m >= 1 && m <= 12 { // success
			currentMonth = time.Month(m)
		}
		if y, err := strconv.Atoi(os.Args[2]); err == nil { // success
			currentYear = y
		}
	} else if len(os.Args) > 1 {
		if y, err := strconv.Atoi(os.Args[1]); err == nil { // success
			currentYear = y
		}
		// Assume that a single argument <= 12 was intended to be a month
		if currentYear >= 1 && currentYear <= 12 {
			currentMonth = time.Month(currentYear)
			currentYear = now.Year()
		}
	}

	langEnv := strings.TrimSuffix(env.Str("LC_ALL", env.Str("LANG")), ".UTF-8")
	if langEnv == "C" || env.Str("LC_ALL") == "C" {
		langEnv = "en_US" // default to en_US
	}

	cal, err := kal.NewCalendar(langEnv, true)
	if err != nil {
		log.Fatalln("could not create a calendar with langEnv " + langEnv)
	}

	moCal := MonthCalendar(&cal, currentYear, currentMonth)

	o := textoutput.New()
	o.Print(moCal)
}
<commit_msg>Minor changes to the flag day description output<commit_after>package main

import (
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/xyproto/env"
	"github.com/xyproto/kal"
	"github.com/xyproto/textoutput"
	"github.com/xyproto/vt100"
)

// centerPad will pad a string with spaces up to the given width,
// so that the string is centered.
func centerPad(s string, width int) string {
	l := len([]rune(s))
	if l < width {
		after := (width - l) / 2
		before := (width - l) - after
		return strings.Repeat(" ", before) + s + strings.Repeat(" ", after)
	}
	return s
}

// rightPad will pad the right side of a string with spaces
func rightPad(s string, width int) string {
	l := len([]rune(s))
	if l < width {
		after := (width - l)
		return s + strings.Repeat(" ", after)
	}
	return s
}

func centeredMonthYearString(cal kal.Calendar, year int, month time.Month, width int) string {
	s := cal.MonthName(month)
	s += fmt.Sprintf(" %d", year)
	return centerPad(s, width)
}

func weekdayPosition(mondayFirst bool, current time.Time) int {
	weekdayPosition := int(current.Weekday())
	if mondayFirst {
		weekdayPosition--
		if weekdayPosition < 0 {
			weekdayPosition = 6
		}
	}
	return weekdayPosition
}

// MonthCalendar returns a string that is a complete overview of the given month
func MonthCalendar(cal *kal.Calendar, givenYear int, givenMonth time.Month) string {

	mondayFirst := (*cal).MondayFirst()

	var descriptions, sb strings.Builder

	now := time.Now()
	current := time.Date(givenYear, givenMonth, 1, 0, 0, 0, 0, now.Location())

	// Add the week, if this is the current month
	var weekString string
	if now.Month() == givenMonth && now.Year() == givenYear {
		_, w := now.ISOWeek()
		weekString = "w" + strconv.Itoa(w)
	}

	// Month and year, centered
	sb.WriteString("<lightblue>" + centeredMonthYearString(*cal, givenYear, givenMonth, 20-len(weekString)) + "</lightblue><darkgray>" + weekString + "</darkgray>\n")

	// The shortened names of the week days
	sb.WriteString("<white>" + kal.TwoLetterDays(*cal, (*cal).MondayFirst()) + "</white>\n")

	// Indentation before the first day of the month
	sb.WriteString(strings.Repeat(" ", weekdayPosition(mondayFirst, current)*3))

	// Output all the numbers of the month, with linebreaks at appropriate locations
	for current.Month() == givenMonth {
		isFlagDay := kal.FlagDay(*cal, current)
		if current.Day() == now.Day() && current.Month() == now.Month() && current.Year() == now.Year() { // Today
			sb.WriteString(fmt.Sprintf(vt100.BackgroundBlue.String()+"<lightyellow>%2d</lightyellow> ", current.Day()))
		} else if isRedDay := kal.RedDay(*cal, current); current.Weekday() == time.Sunday || isRedDay { // Red day
			// TODO: Collect descriptions, then print them below
			sb.WriteString(fmt.Sprintf("<red>%2d</red> ", current.Day()))
			if isRedDay {
				if isFlagDay {
					if mondayFirst {
						descriptions.WriteString(fmt.Sprintf("<lightblue>%2d. %s</lightblue> - %s (flaggdag)\n", current.Day(), (*cal).MonthName(givenMonth), kal.Describe(*cal, current)))
					} else {
						descriptions.WriteString(fmt.Sprintf("<lightblue>%s %d</lightblue> - %s (flaggdag)\n", (*cal).MonthName(givenMonth), current.Day(), kal.Describe(*cal, current)))
					}
				} else {
					if mondayFirst {
						descriptions.WriteString(fmt.Sprintf("<red>%2d. %s</red> - %s\n", current.Day(), (*cal).MonthName(givenMonth), kal.Describe(*cal, current)))
					} else {
						descriptions.WriteString(fmt.Sprintf("<red>%s %d</red> - %s\n", (*cal).MonthName(givenMonth), current.Day(), kal.Describe(*cal, current)))
					}
				}
			}
		} else if isFlagDay { // Flag day
			// TODO: Collect descriptions, then print them below
			sb.WriteString(fmt.Sprintf("<lightblue>%2d</lightblue> ", current.Day()))
			if mondayFirst {
				descriptions.WriteString(fmt.Sprintf("<lightblue>%2d. %s</lightblue> - %s (flaggdag)\n", current.Day(), (*cal).MonthName(givenMonth), kal.Describe(*cal, current)))
			} else {
				descriptions.WriteString(fmt.Sprintf("<lightblue>%s %d</lightblue> - %s (flaggdag)\n", (*cal).MonthName(givenMonth), current.Day(), kal.Describe(*cal, current)))
			}
		} else { // Ordinary day
			sb.WriteString(fmt.Sprintf("%2d ", current.Day()))
		}

		current = current.AddDate(0, 0, 1)

		if (mondayFirst && (current.Weekday() == time.Monday)) || (!mondayFirst && (current.Weekday() == time.Sunday)) {
			sb.WriteString("\n")
		}
	}

	calendarString := sb.String()
	if !strings.HasSuffix(calendarString, "\n") {
		calendarString += "\n"
	}

	if ds := descriptions.String(); len(ds) > 0 {
		return calendarString + "\n" + ds
	}

	return calendarString
}

func main() {
	now := time.Now()

	currentYear := now.Year()
	currentMonth := now.Month()

	// Check if the first given argument is a number. If yes, use that as the current year.
	if len(os.Args) > 2 {
		if m, err := strconv.Atoi(os.Args[1]); err == nil && m >= 1 && m <= 12 { // success
			currentMonth = time.Month(m)
		}
		if y, err := strconv.Atoi(os.Args[2]); err == nil { // success
			currentYear = y
		}
	} else if len(os.Args) > 1 {
		if y, err := strconv.Atoi(os.Args[1]); err == nil { // success
			currentYear = y
		}
		// Assume that a single argument <= 12 was intended to be a month
		if currentYear >= 1 && currentYear <= 12 {
			currentMonth = time.Month(currentYear)
			currentYear = now.Year()
		}
	}

	langEnv := strings.TrimSuffix(env.Str("LC_ALL", env.Str("LANG")), ".UTF-8")
	if langEnv == "C" || env.Str("LC_ALL") == "C" {
		langEnv = "en_US" // default to en_US
	}

	cal, err := kal.NewCalendar(langEnv, true)
	if err != nil {
		log.Fatalln("could not create a calendar with langEnv " + langEnv)
	}

	moCal := MonthCalendar(&cal, currentYear, currentMonth)

	o := textoutput.New()
	o.Print(moCal)
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io"
	"os"
	"runtime/pprof"
	"strings"
	"time"

	"talisman/prompt"
	"talisman/talismanrc"

	"runtime"

	log "github.com/sirupsen/logrus"
	"github.com/spf13/afero"
	flag "github.com/spf13/pflag"
)

var (
	showVersion bool
	//Version : Version of talisman
	Version       = "Development Build"
	interactive   bool
	talismanInput io.Reader
)

const (
	//PrePush : Const for name of pre-push hook
	PrePush = "pre-push"
	//PreCommit : Const for name of of pre-commit hook
	PreCommit = "pre-commit"
	//EXIT_SUCCESS : Const to indicate successful talisman invocation
	EXIT_SUCCESS = 0
	//EXIT_FAILURE : Const to indicate failed successful invocation
	EXIT_FAILURE = 1
)

var options struct {
	Debug           bool
	LogLevel        string
	GitHook         string
	Pattern         string
	Scan            bool
	IgnoreHistory   bool
	Checksum        string
	ReportDirectory string
	ScanWithHtml    bool
	ShouldProfile   bool
}

//var options Options

func init() {
	log.SetOutput(os.Stderr)
	talismanInput = os.Stdin
	flag.BoolVarP(&options.Debug,
		"debug", "d", false,
		"enable debug mode (warning: very verbose)")
	flag.StringVarP(&options.LogLevel,
		"loglevel", "l", "error",
		"set log level for talisman (allowed values: error|info|warn|debug, default: error)")
	flag.BoolVarP(&showVersion,
		"version", "v", false,
		"show current version of talisman")
	flag.StringVarP(&options.Pattern,
		"pattern", "p", "",
		"pattern (glob-like) of files to scan (ignores githooks)")
	flag.StringVarP(&options.GitHook,
		"githook", "g", PrePush,
		"either pre-push or pre-commit")
	flag.BoolVarP(&options.Scan,
		"scan", "s", false,
		"scanner scans the git commit history for potential secrets")
	flag.BoolVarP(&options.IgnoreHistory,
		"ignoreHistory", "^", false,
		"scanner scans all files on current head, will not scan through git commit history")
	flag.StringVarP(&options.Checksum,
		"checksum", "c", "",
		"checksum calculator calculates checksum and suggests .talismanrc entry")
	flag.StringVarP(&options.ReportDirectory,
		"reportDirectory", "r", "talisman_report",
		"directory where the scan report will be stored")
	flag.BoolVarP(&options.ScanWithHtml,
		"scanWithHtml", "w", false,
		"generate html report (**Make sure you have installed talisman_html_report to use this, as mentioned in talisman Readme**)")
	flag.BoolVarP(&interactive,
		"interactive", "i", false,
		"interactively update talismanrc (only makes sense with -g/--githook)")
	flag.BoolVarP(&options.ShouldProfile,
		"profile", "f", false,
		"profile cpu and memory usage of talisman")
}

func main() {
	flag.Parse()

	if flag.NFlag() == 0 {
		flag.PrintDefaults()
		os.Exit(EXIT_SUCCESS)
	}

	if showVersion {
		fmt.Printf("talisman %s\n", Version)
		os.Exit(EXIT_SUCCESS)
	}

	if options.GitHook != "" {
		if !(options.GitHook == PreCommit || options.GitHook == PrePush) {
			fmt.Println(fmt.Errorf("githook should be %s or %s, but got %s", PreCommit, PrePush, options.GitHook))
			os.Exit(EXIT_FAILURE)
		}
	}

	if options.ShouldProfile {
		stopProfFunc := setupProfiling()
		defer stopProfFunc()
	}

	promptContext := prompt.NewPromptContext(interactive, prompt.NewPrompt())
	os.Exit(run(promptContext))
}

func run(promptContext prompt.PromptContext) (returnCode int) {
	start := time.Now()
	defer func() { fmt.Printf("Talisman done in %v\n", time.Since(start)) }()

	if err := validateGitExecutable(afero.NewOsFs(), runtime.GOOS); err != nil {
		log.Errorf("error validating git executable: %v", err)
		return 1
	}

	setLogLevel()

	if options.GitHook == "" {
		options.GitHook = PrePush
	}

	optionsBytes, _ := json.Marshal(options)
	fields := make(map[string]interface{})
	_ = json.Unmarshal(optionsBytes, &fields)
	log.WithFields(fields).Debug("Talisman execution environment")

	if options.Checksum != "" {
		log.Infof("Running %s patterns against checksum calculator", options.Checksum)
		return NewChecksumCmd(strings.Fields(options.Checksum)).Run()
	} else if options.Scan {
		log.Infof("Running scanner")
		return NewScannerCmd(options.IgnoreHistory, options.ReportDirectory).Run(talismanrc.For(talismanrc.ScanMode))
	} else if options.ScanWithHtml {
		log.Infof("Running scanner with html report")
		return NewScannerCmd(options.IgnoreHistory, "talisman_html_report").Run(talismanrc.For(talismanrc.ScanMode))
	} else if options.Pattern != "" {
		log.Infof("Running scan for %s", options.Pattern)
		return NewPatternCmd(options.Pattern).Run(talismanrc.For(talismanrc.HookMode), promptContext)
	} else if options.GitHook == PreCommit {
		log.Infof("Running %s hook", options.GitHook)
		return NewPreCommitHook().Run(talismanrc.For(talismanrc.HookMode), promptContext)
	} else {
		log.Infof("Running %s hook", options.GitHook)
		return NewPrePushHook(talismanInput).Run(talismanrc.For(talismanrc.HookMode), promptContext)
	}
}

func validateGitExecutable(fs afero.Fs, operatingSystem string) error {
	if operatingSystem == "windows" {
		extensions := strings.ToLower(os.Getenv("PATHEXT"))
		windowsExecutables := strings.Split(extensions, ";")
		for _, executable := range windowsExecutables {
			gitExecutable := fmt.Sprintf("git%s", executable)
			exists, err := afero.Exists(fs, gitExecutable)
			if err != nil {
				return err
			}
			if exists {
				return fmt.Errorf("not allowed to have git executable located in repository: %s", gitExecutable)
			}
		}
	}
	return nil
}

func setLogLevel() {
	switch options.LogLevel {
	case "info":
		log.SetLevel(log.InfoLevel)
	case "debug":
		log.SetLevel(log.DebugLevel)
	case "error":
		log.SetLevel(log.ErrorLevel)
	case "warn":
		log.SetLevel(log.WarnLevel)
	default:
		log.SetLevel(log.ErrorLevel)
	}
	if options.Debug {
		log.SetLevel(log.DebugLevel)
	}
}

func setupProfiling() func() {
	log.Info("Profiling initiated")
	cpuProfFile, err := os.Create("talisman.cpuprof")
	if err != nil {
		log.Fatalf("Unable to create cpu profiling output file talisman.cpuprof: %v", err)
	}

	_ = pprof.StartCPUProfile(cpuProfFile)
	progEnded := false

	go func() {
		memProfFile, err := os.Create("talisman.memprof")
		if err != nil {
			log.Fatalf("Unable to create memory profiling output file talisman.memprof: %v", err)
		}
		memProfTimer := time.NewTimer(500 * time.Millisecond)

		for !progEnded {
			<-memProfTimer.C
			_ = pprof.WriteHeapProfile(memProfFile)
		}

		_ = memProfFile.Close()
	}()

	return func() {
		progEnded = true
		pprof.StopCPUProfile()
		log.Info("Profiling completed")
		cpuProfFile.Close()
	}
}
<commit_msg>Move mem prof file creation outside go routine<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io"
	"os"
	"runtime/pprof"
	"strings"
	"time"

	"talisman/prompt"
	"talisman/talismanrc"

	"runtime"

	log "github.com/sirupsen/logrus"
	"github.com/spf13/afero"
	flag "github.com/spf13/pflag"
)

var (
	showVersion bool
	//Version : Version of talisman
	Version       = "Development Build"
	interactive   bool
	talismanInput io.Reader
)

const (
	//PrePush : Const for name of pre-push hook
	PrePush = "pre-push"
	//PreCommit : Const for name of of pre-commit hook
	PreCommit = "pre-commit"
	//EXIT_SUCCESS : Const to indicate successful talisman invocation
	EXIT_SUCCESS = 0
	//EXIT_FAILURE : Const to indicate failed successful invocation
	EXIT_FAILURE = 1
)

var options struct {
	Debug           bool
	LogLevel        string
	GitHook         string
	Pattern         string
	Scan            bool
	IgnoreHistory   bool
	Checksum        string
	ReportDirectory string
	ScanWithHtml    bool
	ShouldProfile   bool
}

//var options Options

func init() {
	log.SetOutput(os.Stderr)
	talismanInput = os.Stdin
	flag.BoolVarP(&options.Debug,
		"debug", "d", false,
		"enable debug mode (warning: very verbose)")
	flag.StringVarP(&options.LogLevel,
		"loglevel", "l", "error",
		"set log level for talisman (allowed values: error|info|warn|debug, default: error)")
	flag.BoolVarP(&showVersion,
		"version", "v", false,
		"show current version of talisman")
	flag.StringVarP(&options.Pattern,
		"pattern", "p", "",
		"pattern (glob-like) of files to scan (ignores githooks)")
	flag.StringVarP(&options.GitHook,
		"githook", "g", PrePush,
		"either pre-push or pre-commit")
	flag.BoolVarP(&options.Scan,
		"scan", "s", false,
		"scanner scans the git commit history for potential secrets")
	flag.BoolVarP(&options.IgnoreHistory,
		"ignoreHistory", "^", false,
		"scanner scans all files on current head, will not scan through git commit history")
	flag.StringVarP(&options.Checksum,
		"checksum", "c", "",
		"checksum calculator calculates checksum and suggests .talismanrc entry")
	flag.StringVarP(&options.ReportDirectory,
		"reportDirectory", "r", "talisman_report",
		"directory where the scan report will be stored")
	flag.BoolVarP(&options.ScanWithHtml,
		"scanWithHtml", "w", false,
		"generate html report (**Make sure you have installed talisman_html_report to use this, as mentioned in talisman Readme**)")
	flag.BoolVarP(&interactive,
		"interactive", "i", false,
		"interactively update talismanrc (only makes sense with -g/--githook)")
	flag.BoolVarP(&options.ShouldProfile,
		"profile", "f", false,
		"profile cpu and memory usage of talisman")
}

func main() {
	flag.Parse()

	if flag.NFlag() == 0 {
		flag.PrintDefaults()
		os.Exit(EXIT_SUCCESS)
	}

	if showVersion {
		fmt.Printf("talisman %s\n", Version)
		os.Exit(EXIT_SUCCESS)
	}

	if options.GitHook != "" {
		if !(options.GitHook == PreCommit || options.GitHook == PrePush) {
			fmt.Println(fmt.Errorf("githook should be %s or %s, but got %s", PreCommit, PrePush, options.GitHook))
			os.Exit(EXIT_FAILURE)
		}
	}

	if options.ShouldProfile {
		stopProfFunc := setupProfiling()
		defer stopProfFunc()
	}

	promptContext := prompt.NewPromptContext(interactive, prompt.NewPrompt())
	os.Exit(run(promptContext))
}

func run(promptContext prompt.PromptContext) (returnCode int) {
	start := time.Now()
	defer func() { fmt.Printf("Talisman done in %v\n", time.Since(start)) }()

	if err := validateGitExecutable(afero.NewOsFs(), runtime.GOOS); err != nil {
		log.Errorf("error validating git executable: %v", err)
		return 1
	}

	setLogLevel()

	if options.GitHook == "" {
		options.GitHook = PrePush
	}

	optionsBytes, _ := json.Marshal(options)
	fields := make(map[string]interface{})
	_ = json.Unmarshal(optionsBytes, &fields)
	log.WithFields(fields).Debug("Talisman execution environment")

	if options.Checksum != "" {
		log.Infof("Running %s patterns against checksum calculator", options.Checksum)
		return NewChecksumCmd(strings.Fields(options.Checksum)).Run()
	} else if options.Scan {
		log.Infof("Running scanner")
		return NewScannerCmd(options.IgnoreHistory, options.ReportDirectory).Run(talismanrc.For(talismanrc.ScanMode))
	} else if options.ScanWithHtml {
		log.Infof("Running scanner with html report")
		return NewScannerCmd(options.IgnoreHistory, "talisman_html_report").Run(talismanrc.For(talismanrc.ScanMode))
	} else if options.Pattern != "" {
		log.Infof("Running scan for %s", options.Pattern)
		return NewPatternCmd(options.Pattern).Run(talismanrc.For(talismanrc.HookMode), promptContext)
	} else if options.GitHook == PreCommit {
		log.Infof("Running %s hook", options.GitHook)
		return NewPreCommitHook().Run(talismanrc.For(talismanrc.HookMode), promptContext)
	} else {
		log.Infof("Running %s hook", options.GitHook)
		return NewPrePushHook(talismanInput).Run(talismanrc.For(talismanrc.HookMode), promptContext)
	}
}

func validateGitExecutable(fs afero.Fs, operatingSystem string) error {
	if operatingSystem == "windows" {
		extensions := strings.ToLower(os.Getenv("PATHEXT"))
		windowsExecutables := strings.Split(extensions, ";")
		for _, executable := range windowsExecutables {
			gitExecutable := fmt.Sprintf("git%s", executable)
			exists, err := afero.Exists(fs, gitExecutable)
			if err != nil {
				return err
			}
			if exists {
				return fmt.Errorf("not allowed to have git executable located in repository: %s", gitExecutable)
			}
		}
	}
	return nil
}

func setLogLevel() {
	switch options.LogLevel {
	case "info":
		log.SetLevel(log.InfoLevel)
	case "debug":
		log.SetLevel(log.DebugLevel)
	case "error":
		log.SetLevel(log.ErrorLevel)
	case "warn":
		log.SetLevel(log.WarnLevel)
	default:
		log.SetLevel(log.ErrorLevel)
	}
	if options.Debug {
		log.SetLevel(log.DebugLevel)
	}
}

func setupProfiling() func() {
	log.Info("Profiling initiated")

	cpuProfFile, err := os.Create("talisman.cpuprof")
	if err != nil {
		log.Fatalf("Unable to create cpu profiling output file talisman.cpuprof: %v", err)
	}

	memProfFile, err := os.Create("talisman.memprof")
	if err != nil {
		log.Fatalf("Unable to create memory profiling output file talisman.memprof: %v", err)
	}

	_ = pprof.StartCPUProfile(cpuProfFile)
	progEnded := false

	go func() {
		memProfTimer := time.NewTimer(500 * time.Millisecond)

		for !progEnded {
			<-memProfTimer.C
			_ = pprof.WriteHeapProfile(memProfFile)
		}
	}()

	return func() {
		progEnded = true
		pprof.StopCPUProfile()
		log.Info("Profiling completed")
		_ = cpuProfFile.Close()
		_ = memProfFile.Close()
	}
}
<|endoftext|>


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

package main

import (
	"github.com/tsuru/config"
	"github.com/tsuru/tsuru/cmd"
	"github.com/tsuru/tsuru/provision"
	_ "github.com/tsuru/tsuru/provision/docker"
	"os"
)

const defaultConfigPath = "/etc/tsuru/tsuru.conf"

func buildManager() *cmd.Manager {
	m := cmd.NewManager("tsr", "0.5.1", "", os.Stdout, os.Stderr, os.Stdin, nil)
	m.Register(&tsrCommand{Command: &apiCmd{}})
	m.Register(&tsrCommand{Command: tokenCmd{}})
	m.Register(&tsrCommand{Command: &healerCmd{}})
	registerProvisionersCommands(m)
	return m
}

func registerProvisionersCommands(m *cmd.Manager) {
	provisioners := provision.Registry()
	for _, p := range provisioners {
		if c, ok := p.(cmd.Commandable); ok {
			commands := c.Commands()
			for _, cmd := range commands {
				m.Register(&tsrCommand{Command: cmd})
			}
		}
	}
}

func main() {
	config.ReadConfigFile(defaultConfigPath)
	m := buildManager()
	m.Run(os.Args[1:])
}
<commit_msg>cmd/tsr: bump to 0.5.2<commit_after>// Copyright 2014 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"github.com/tsuru/config"
	"github.com/tsuru/tsuru/cmd"
	"github.com/tsuru/tsuru/provision"
	_ "github.com/tsuru/tsuru/provision/docker"
	"os"
)

const defaultConfigPath = "/etc/tsuru/tsuru.conf"

func buildManager() *cmd.Manager {
	m := cmd.NewManager("tsr", "0.5.2", "", os.Stdout, os.Stderr, os.Stdin, nil)
	m.Register(&tsrCommand{Command: &apiCmd{}})
	m.Register(&tsrCommand{Command: tokenCmd{}})
	m.Register(&tsrCommand{Command: &healerCmd{}})
	registerProvisionersCommands(m)
	return m
}

func registerProvisionersCommands(m *cmd.Manager) {
	provisioners := provision.Registry()
	for _, p := range provisioners {
		if c, ok := p.(cmd.Commandable); ok {
			commands := c.Commands()
			for _, cmd := range commands {
				m.Register(&tsrCommand{Command: cmd})
			}
		}
	}
}

func main() {
	config.ReadConfigFile(defaultConfigPath)
	m := buildManager()
	m.Run(os.Args[1:])
}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/ec2"
	"sync"
	"time"
)

func setEC2Param(region string, wg *sync.WaitGroup, instanceParamEC2 *[]ec2.DescribeInstancesOutput) {

	ec2instance := ec2.New(session.New(), &aws.Config{Region: aws.String(region)}) //generate API query instance
	resp, err := ec2instance.DescribeInstances(nil)                                //get instance information from API

	if err != nil {
		fmt.Println(err)
		return
	}

	*instanceParamEC2 = append(*instanceParamEC2, *resp) //set response instanceParamEC2 array

	wg.Done()

}

func getEC2Param(region string) *ec2.DescribeInstancesOutput {

	ec2instance := ec2.New(session.New(), &aws.Config{Region: aws.String(region)}) //generate API query instance
	resp, err := ec2instance.DescribeInstances(nil)                                //get instance information from API

	if err != nil {
		fmt.Println(err)
		return nil
	}

	return resp //return response (json)
}

func createKey(region string) (string, string) {

	name := "cq_" + time.Now().String()

	ec2instance := ec2.New(session.New(), &aws.Config{Region: aws.String(region)}) //generate API query instance
	resp, err := ec2instance.CreateKeyPair(&ec2.CreateKeyPairInput{
		KeyName: aws.String(name),
	})

	if err != nil {
		fmt.Println(err)
		return "", ""
	}

	return *resp.KeyMaterial, name //return secret-key

}

func getInstanceParam(region string, iid string) *ec2.DescribeInstancesOutput {

	ec2instance := ec2.New(session.New(), &aws.Config{Region: aws.String(region)}) //generate API query instance
	resp, err := ec2instance.DescribeInstances(&ec2.DescribeInstancesInput{
		InstanceIds: []*string{
			aws.String(iid),
		},
	})

	if err != nil {
		fmt.Println(err)
		return nil
	}

	return resp //return response (json)
}

func checkInstanceCreated(region string, iid string) *ec2.DescribeInstancesOutput {

	resp := getInstanceParam(region, iid)

	for i := 0; i < 60; i++ { //60 seconds

		for _, Reservations := range resp.Reservations {
			for _, Instances := range Reservations.Instances {
				if Instances.PublicIpAddress != nil {
					fmt.Printf("\n")
					return resp
				}
			}
		}

		time.Sleep(1000 * time.Millisecond)
		resp = getInstanceParam(region, iid)

	}

	return resp
}
<commit_msg>fix easyup keypair name<commit_after>package cmd

import (
	"fmt"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/ec2"
	"sync"
	"time"
)

func setEC2Param(region string, wg *sync.WaitGroup, instanceParamEC2 *[]ec2.DescribeInstancesOutput) {

	ec2instance := ec2.New(session.New(), &aws.Config{Region: aws.String(region)}) //generate API query instance
	resp, err := ec2instance.DescribeInstances(nil)                                //get instance information from API

	if err != nil {
		fmt.Println(err)
		return
	}

	*instanceParamEC2 = append(*instanceParamEC2, *resp) //set response instanceParamEC2 array

	wg.Done()

}

func getEC2Param(region string) *ec2.DescribeInstancesOutput {

	ec2instance := ec2.New(session.New(), &aws.Config{Region: aws.String(region)}) //generate API query instance
	resp, err := ec2instance.DescribeInstances(nil)                                //get instance information from API

	if err != nil {
		fmt.Println(err)
		return nil
	}

	return resp //return response (json)
}

func createKey(region string) (string, string) {

	oclock := time.Now().Format("2006-01-02_15:04:05")
	name := "cq_" + oclock

	ec2instance := ec2.New(session.New(), &aws.Config{Region: aws.String(region)}) //generate API query instance
	resp, err := ec2instance.CreateKeyPair(&ec2.CreateKeyPairInput{
		KeyName: aws.String(name),
	})

	if err != nil {
		fmt.Println(err)
		return "", ""
	}

	return *resp.KeyMaterial, name //return secret-key

}

func getInstanceParam(region string, iid string) *ec2.DescribeInstancesOutput {

	ec2instance := ec2.New(session.New(), &aws.Config{Region: aws.String(region)}) //generate API query instance
	resp, err := ec2instance.DescribeInstances(&ec2.DescribeInstancesInput{
		InstanceIds: []*string{
			aws.String(iid),
		},
	})

	if err != nil {
		fmt.Println(err)
		return nil
	}

	return resp //return response (json)
}

func checkInstanceCreated(region string, iid string) *ec2.DescribeInstancesOutput {

	resp := getInstanceParam(region, iid)

	for i := 0; i < 60; i++ { //60 seconds

		for _, Reservations := range resp.Reservations {
			for _, Instances := range Reservations.Instances {
				if Instances.PublicIpAddress != nil {
					fmt.Printf("\n")
					return resp
				}
			}
		}

		time.Sleep(1000 * time.Millisecond)
		resp = getInstanceParam(region, iid)

	}

	return resp
}
<|endoftext|>


<commit_before>// Use SSM multicast to discover other processes on the same local network
// See RFC-3569 for SSM description
// See RFC-5771 for IANA IPv4 Multicast address assignments
// This implementation supports multicast failure detection, also disseminated
// via simple multicast.

package multicast

import (
	"log"
	"net"
	"time"
)

const (
	// Addresses for SSM multicasting are in the space 232/8
	// See https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml#multicast-addresses-10
	multicastIP = "232.77.77.77"
	multicastPort = "9864"
	multicastAddress = multicastIP + ":" + multicastPort
	defaultPeriod = 10
	defaultFailedTime = 60 // Seconds until a peer is considered failed
)

type Multicast struct {
	Conn                 *net.UDPConn
	Addr                 *net.UDPAddr
	Period               int // multicast period (in secs, 10 by default)
	FailedTime           int // timeout for peers' hello messages, 0 means no timeout
	AddPeerCallback      func(string) // Callback called when a peer is added
	RemovePeerCallback   func(string) // Callback called when a peer is removed

	quit                 chan bool
	helloTicker          *time.Ticker
	peers                map [string]time.Time
}

// Join the Lantern multicast group
func JoinMulticast() *Multicast {
        udpAddr, e := net.ResolveUDPAddr("udp4", multicastAddress)
        if e != nil {
		log.Fatal(e)
                return nil
        }

        c, e := net.ListenMulticastUDP("udp4", nil, udpAddr)
        if e != nil {
                return nil
        }
        return &Multicast{
		Conn: c,
		Addr: udpAddr,
		Period: defaultPeriod,
		FailedTime: defaultFailedTime,
		quit: make(chan bool, 1),
		peers: make(map[string]time.Time),
	}
}

// Initiate multicasting
func (mc *Multicast) StartMulticast() {
	// Periodically announce ourselves to the network
	go mc.sendHellos()

	// Listen multicasts by others
	go mc.listenPeers()
}

// Stop multicasting and leave the group. This should be called by the users of
// this library when the program exits or the discovery service is disabled by
// the end user
func (mc *Multicast) LeaveMulticast() error {
	// Stop sending hello
	if mc.helloTicker != nil {
		mc.helloTicker.Stop()
	}
	msg, e := MakeByeMessage().Serialize()
	if e != nil {
		log.Fatal(e)
	}
	mc.write(msg)

	// Leave the listening goroutine as soon as it timeouts
	mc.quit <- true

	return nil
}

func (mc *Multicast) write(b []byte) (int, error) {
        return mc.Conn.WriteTo(b, mc.Addr)
}

func (mc *Multicast) read(b []byte) (int, *net.UDPAddr, error) {
        return mc.Conn.ReadFromUDP(b)
}

func (mc *Multicast) sendHellos() {
	mc.helloTicker = time.NewTicker(time.Duration(mc.Period) * time.Second)
	msg, e := MakeHelloMessage().Serialize()
	if e != nil {
		log.Fatal(e)
		return
	}
	for range mc.helloTicker.C {
		mc.write(msg)
	}
}

func (mc *Multicast) listenPeers() error {
	b := make([]byte, messageMaxSize)
	// Set a deadline to avoid blocking on a read forever
	for {
		select {
		case <- mc.quit:
			return mc.Conn.Close()
		default:
			mc.Conn.SetReadDeadline(time.Now().Add(time.Duration(mc.Period) * time.Second))
			n, udpAddr, e := mc.read(b)
			udpAddrStr := udpAddr.String()
			if e != nil {
				// Just start over if any error happened when reading
				break
			}
			msg := b[:n]
			mcMsg, e := Deserialize(msg)
			if e != nil {
				break
			}
			switch mcMsg.mType {
			case TypeHello:
				// Test whether I'm the origin of this multicast
				otherPeer := true
				for _, ip := range getMyIPs() {
					if ip.Equal(udpAddr.IP) {
						otherPeer = false
						break
					}
				}
				if otherPeer {
					// Add/Update peer
					_, ok := mc.peers[udpAddrStr]
					if !ok && mc.AddPeerCallback != nil {
						mc.AddPeerCallback(udpAddrStr)
					}
					// A time in the future when that, if no hello message from the peer is
					// received, it will be considered failed. Update every time.
					mc.peers[udpAddrStr] = time.Now().Add(time.Second * time.Duration(mc.FailedTime))
				}
			case TypeBye:
				_, ok := mc.peers[udpAddrStr]
				if ok {
					// Remove peer
					if mc.RemovePeerCallback != nil {
						mc.RemovePeerCallback(udpAddrStr)
					}
					delete(mc.peers, udpAddrStr)
				}
			default:
				log.Fatal("Unrecognized message sent to Lantern multicast SSM address")
			}
			// We are checking here also that no peer is too old. If we don't
			// hear from peers soon enough, we consider them failed.
			for p, pt := range mc.peers {
				// FailedTime zero means no timeout
				if time.Now().After(pt) && mc.FailedTime != 0 {
					delete(mc.peers, p)
				}
			}
		}
	}
}

func getMyIPs() (ips []net.IP) {
	addrs, e := net.InterfaceAddrs()
	if e != nil {
		log.Fatal (e)
		return
	}
	for _, a := range addrs {
		if ipnet, ok := a.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
			ips = append(ips, ipnet.IP)
		}
	}
	return
}
<commit_msg>Multicast: SSM is not used, fix multicast address according to IANA<commit_after>// Use multicast to discover other processes on the same local network
// See RFC-5771 for IANA IPv4 Multicast address assignments
// See RFC-2365 for Administratively Scoped IP Multicast
// This implementation supports multicast failure detection, also disseminated
// via simple multicast.

package multicast

import (
	"log"
	"net"
	"time"
)

const (
	// Addresses for Administratively Scoped IP Multicast are in the space 239/8
	multicastIP = "239.77.77.77"
	multicastPort = "9864"
	multicastAddress = multicastIP + ":" + multicastPort
	defaultPeriod = 10
	defaultFailedTime = 60 // Seconds until a peer is considered failed
)

type Multicast struct {
	Conn                 *net.UDPConn
	Addr                 *net.UDPAddr
	Period               int // multicast period (in secs, 10 by default)
	FailedTime           int // timeout for peers' hello messages, 0 means no timeout
	AddPeerCallback      func(string) // Callback called when a peer is added
	RemovePeerCallback   func(string) // Callback called when a peer is removed

	quit                 chan bool
	helloTicker          *time.Ticker
	peers                map [string]time.Time
}

// Join the Lantern multicast group
func JoinMulticast() *Multicast {
        udpAddr, e := net.ResolveUDPAddr("udp4", multicastAddress)
        if e != nil {
		log.Fatal(e)
                return nil
        }

        c, e := net.ListenMulticastUDP("udp4", nil, udpAddr)
        if e != nil {
                return nil
        }
        return &Multicast{
		Conn: c,
		Addr: udpAddr,
		Period: defaultPeriod,
		FailedTime: defaultFailedTime,
		quit: make(chan bool, 1),
		peers: make(map[string]time.Time),
	}
}

// Initiate multicasting
func (mc *Multicast) StartMulticast() {
	// Periodically announce ourselves to the network
	go mc.sendHellos()

	// Listen multicasts by others
	go mc.listenPeers()
}

// Stop multicasting and leave the group. This should be called by the users of
// this library when the program exits or the discovery service is disabled by
// the end user
func (mc *Multicast) LeaveMulticast() error {
	// Stop sending hello
	if mc.helloTicker != nil {
		mc.helloTicker.Stop()
	}
	msg, e := MakeByeMessage().Serialize()
	if e != nil {
		log.Fatal(e)
	}
	mc.write(msg)

	// Leave the listening goroutine as soon as it timeouts
	mc.quit <- true

	return nil
}

func (mc *Multicast) write(b []byte) (int, error) {
        return mc.Conn.WriteTo(b, mc.Addr)
}

func (mc *Multicast) read(b []byte) (int, *net.UDPAddr, error) {
        return mc.Conn.ReadFromUDP(b)
}

func (mc *Multicast) sendHellos() {
	mc.helloTicker = time.NewTicker(time.Duration(mc.Period) * time.Second)
	msg, e := MakeHelloMessage().Serialize()
	if e != nil {
		log.Fatal(e)
		return
	}
	for range mc.helloTicker.C {
		mc.write(msg)
	}
}

func (mc *Multicast) listenPeers() error {
	b := make([]byte, messageMaxSize)
	// Set a deadline to avoid blocking on a read forever
	for {
		select {
		case <- mc.quit:
			return mc.Conn.Close()
		default:
			mc.Conn.SetReadDeadline(time.Now().Add(time.Duration(mc.Period) * time.Second))
			n, udpAddr, e := mc.read(b)
			udpAddrStr := udpAddr.String()
			if e != nil {
				// Just start over if any error happened when reading
				break
			}
			msg := b[:n]
			mcMsg, e := Deserialize(msg)
			if e != nil {
				break
			}
			switch mcMsg.mType {
			case TypeHello:
				// Test whether I'm the origin of this multicast
				otherPeer := true
				for _, ip := range getMyIPs() {
					if ip.Equal(udpAddr.IP) {
						otherPeer = false
						break
					}
				}
				if otherPeer {
					// Add/Update peer
					_, ok := mc.peers[udpAddrStr]
					if !ok && mc.AddPeerCallback != nil {
						mc.AddPeerCallback(udpAddrStr)
					}
					// A time in the future when that, if no hello message from the peer is
					// received, it will be considered failed. Update every time.
					mc.peers[udpAddrStr] = time.Now().Add(time.Second * time.Duration(mc.FailedTime))
				}
			case TypeBye:
				_, ok := mc.peers[udpAddrStr]
				if ok {
					// Remove peer
					if mc.RemovePeerCallback != nil {
						mc.RemovePeerCallback(udpAddrStr)
					}
					delete(mc.peers, udpAddrStr)
				}
			default:
				log.Fatal("Unrecognized message sent to Lantern multicast SSM address")
			}
			// We are checking here also that no peer is too old. If we don't
			// hear from peers soon enough, we consider them failed.
			for p, pt := range mc.peers {
				// FailedTime zero means no timeout
				if time.Now().After(pt) && mc.FailedTime != 0 {
					delete(mc.peers, p)
				}
			}
		}
	}
}

func getMyIPs() (ips []net.IP) {
	addrs, e := net.InterfaceAddrs()
	if e != nil {
		log.Fatal (e)
		return
	}
	for _, a := range addrs {
		if ipnet, ok := a.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
			ips = append(ips, ipnet.IP)
		}
	}
	return
}
<|endoftext|>


<commit_before>package drone

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
)

type Client struct {
	token      string
	url        string
	isServer04 bool

	Commits    *CommitService
	Repos      *RepoService
	Users      *UserService
	HttpClient *http.Client
}

func NewClient(token, url string, client *http.Client) *Client {
	c := Client{
		token: token,
		url:   url,
	}

	c.Commits = &CommitService{&c}
	c.Repos = &RepoService{&c}
	c.Users = &UserService{&c}
	if client == nil {
		client = http.DefaultClient
	}
	c.HttpClient = client
	return &c
}

func NewClient04(token string, url string, client *http.Client) *Client {
	c := NewClient(token, url, client)
	c.isServer04 = true
	return c
}

var (
	ErrNotFound       = errors.New("Not Found")
	ErrForbidden      = errors.New("Forbidden")
	ErrBadRequest     = errors.New("Bad Request")
	ErrNotAuthorized  = errors.New("Unauthorized")
	ErrInternalServer = errors.New("Internal Server Error")
)

// runs an http.Request and parses the JSON-encoded http.Response,
// storing the result in the value pointed to by v.
func (c *Client) run(method, path string, in, out interface{}) error {

	// create the URI
	uri, err := url.Parse(c.url + path)
	if err != nil {
		return err
	}

	if len(uri.Scheme) == 0 {
		uri.Scheme = "http"
	}

	if len(c.token) > 0 {
		params := uri.Query()
		params.Add("access_token", c.token)
		uri.RawQuery = params.Encode()
	}

	// create the request
	req, err := http.NewRequest(method, uri.String(), nil)
	if err != nil {
		return err
	}
	req.ProtoAtLeast(1, 1)
	req.Close = true
	req.ContentLength = 0

	// if data input is provided, serialize to JSON
	if in != nil {
		formIn, ok := in.(map[string]string)
		var buf *bytes.Buffer
		var contentType string
		if c.isServer04 && ok {
			contentType = "application/x-www-form-urlencoded"
			data := url.Values{}
			for key, val := range formIn {
				data.Set(key, val)
			}
			buf = bytes.NewBufferString(data.Encode())
		} else if bytesIn, ok := in.([]byte); c.isServer04 && ok {
			contentType = "text/plain"
			buf = bytes.NewBufferString(string(bytesIn[:]))
		} else {
			contentType = "application/json"
			inJson, err := json.Marshal(in)
			if err != nil {
				return err
			}
			buf = bytes.NewBuffer(inJson)
		}

		req.Body = ioutil.NopCloser(buf)
		req.ContentLength = int64(buf.Len())
		req.Header.Set("Content-Length", strconv.Itoa(buf.Len()))
		req.Header.Set("Content-Type", contentType)
	}

	// make the request using the default http client
	resp, err := c.HttpClient.Do(req)

	if err != nil {
		return err
	}

	// make sure we defer close the body
	defer resp.Body.Close()

	// Check for an http error status (ie not 200 StatusOK)
	switch resp.StatusCode {
	case 404:
		return ErrNotFound
	case 403:
		return ErrForbidden
	case 401:
		return ErrNotAuthorized
	case 400:
		return ErrBadRequest
	case 500:
		return ErrInternalServer
	}

	// Decode the JSON response
	if out != nil {
		respBody, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return errors.New(fmt.Sprintf("Error reading response body: %s", err))
		}
		err = json.Marshal(respBody, out)
		if err != nil {
			if outStr, ok := out.(*string); ok {
				*outStr = string(contents[:])
			} else {
				return err
			}
		}
	}

	return nil
}

// do makes an http.Request and returns the response
func (c *Client) do(method, path string) (*http.Response, error) {

	// create the URI
	uri, err := url.Parse(c.url + path)
	if err != nil {
		return nil, err
	}

	if len(uri.Scheme) == 0 {
		uri.Scheme = "http"
	}

	if len(c.token) > 0 {
		params := uri.Query()
		params.Add("access_token", c.token)
		uri.RawQuery = params.Encode()
	}

	// create the request
	req, err := http.NewRequest(method, uri.String(), nil)
	if err != nil {
		return nil, err
	}
	req.ProtoAtLeast(1, 1)
	req.Close = true
	req.ContentLength = 0

	// make the request using the default http client
	resp, err := c.HttpClient.Do(req)

	return resp, err
}
<commit_msg>Read response body only once when trying to read it as either json or a string<commit_after>package drone

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
)

type Client struct {
	token      string
	url        string
	isServer04 bool

	Commits    *CommitService
	Repos      *RepoService
	Users      *UserService
	HttpClient *http.Client
}

func NewClient(token, url string, client *http.Client) *Client {
	c := Client{
		token: token,
		url:   url,
	}

	c.Commits = &CommitService{&c}
	c.Repos = &RepoService{&c}
	c.Users = &UserService{&c}
	if client == nil {
		client = http.DefaultClient
	}
	c.HttpClient = client
	return &c
}

func NewClient04(token string, url string, client *http.Client) *Client {
	c := NewClient(token, url, client)
	c.isServer04 = true
	return c
}

var (
	ErrNotFound       = errors.New("Not Found")
	ErrForbidden      = errors.New("Forbidden")
	ErrBadRequest     = errors.New("Bad Request")
	ErrNotAuthorized  = errors.New("Unauthorized")
	ErrInternalServer = errors.New("Internal Server Error")
)

// runs an http.Request and parses the JSON-encoded http.Response,
// storing the result in the value pointed to by v.
func (c *Client) run(method, path string, in, out interface{}) error {

	// create the URI
	uri, err := url.Parse(c.url + path)
	if err != nil {
		return err
	}

	if len(uri.Scheme) == 0 {
		uri.Scheme = "http"
	}

	if len(c.token) > 0 {
		params := uri.Query()
		params.Add("access_token", c.token)
		uri.RawQuery = params.Encode()
	}

	// create the request
	req, err := http.NewRequest(method, uri.String(), nil)
	if err != nil {
		return err
	}
	req.ProtoAtLeast(1, 1)
	req.Close = true
	req.ContentLength = 0

	// if data input is provided, serialize to JSON
	if in != nil {
		formIn, ok := in.(map[string]string)
		var buf *bytes.Buffer
		var contentType string
		if c.isServer04 && ok {
			contentType = "application/x-www-form-urlencoded"
			data := url.Values{}
			for key, val := range formIn {
				data.Set(key, val)
			}
			buf = bytes.NewBufferString(data.Encode())
		} else if bytesIn, ok := in.([]byte); c.isServer04 && ok {
			contentType = "text/plain"
			buf = bytes.NewBufferString(string(bytesIn[:]))
		} else {
			contentType = "application/json"
			inJson, err := json.Marshal(in)
			if err != nil {
				return err
			}
			buf = bytes.NewBuffer(inJson)
		}

		req.Body = ioutil.NopCloser(buf)
		req.ContentLength = int64(buf.Len())
		req.Header.Set("Content-Length", strconv.Itoa(buf.Len()))
		req.Header.Set("Content-Type", contentType)
	}

	// make the request using the default http client
	resp, err := c.HttpClient.Do(req)

	if err != nil {
		return err
	}

	// make sure we defer close the body
	defer resp.Body.Close()

	// Check for an http error status (ie not 200 StatusOK)
	switch resp.StatusCode {
	case 404:
		return ErrNotFound
	case 403:
		return ErrForbidden
	case 401:
		return ErrNotAuthorized
	case 400:
		return ErrBadRequest
	case 500:
		return ErrInternalServer
	}

	// Decode the JSON response
	if out != nil {
		respBody, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return errors.New(fmt.Sprintf("Error reading response body: %s", err))
		}
		err = json.Unmarshal(respBody, out)
		if err != nil {
			if outStr, ok := out.(*string); ok {
				*outStr = string(respBody[:])
			} else {
				return err
			}
		}
	}

	return nil
}

// do makes an http.Request and returns the response
func (c *Client) do(method, path string) (*http.Response, error) {

	// create the URI
	uri, err := url.Parse(c.url + path)
	if err != nil {
		return nil, err
	}

	if len(uri.Scheme) == 0 {
		uri.Scheme = "http"
	}

	if len(c.token) > 0 {
		params := uri.Query()
		params.Add("access_token", c.token)
		uri.RawQuery = params.Encode()
	}

	// create the request
	req, err := http.NewRequest(method, uri.String(), nil)
	if err != nil {
		return nil, err
	}
	req.ProtoAtLeast(1, 1)
	req.Close = true
	req.ContentLength = 0

	// make the request using the default http client
	resp, err := c.HttpClient.Do(req)

	return resp, err
}
<|endoftext|>


<commit_before>package main

import (
	"testing"
	"io/ioutil"
	"encoding/json"
	"fmt"
	"github.com/kyokomi/quick-image-cli/dropbox"
)

func TestReadImageList(t *testing.T) {

	d := NewDropBox("aaaaaaaaaaaa")

	var meta dropbox.Metadata
	metaData, err := ioutil.ReadFile("test/meta.json")
	if err != nil {
		t.Error(err)
	}
	json.Unmarshal(metaData, &meta)

	var a dropbox.AccountInfo
	aData, err := ioutil.ReadFile("test/account_info.json")
	if err != nil {
		t.Error(err)
	}
	json.Unmarshal(aData, &a)

	images, err := d.readImageList(meta, a)
	if err != nil {
		t.Error(err)
	}

	for _, image := range images {
		fmt.Println(image.Name)
	}

	if len(images) != 3 {
		t.Error("images len error")
	}
}
<commit_msg>test: added test TestReplacePublicFileName and TestCreateImageUrl<commit_after>package main

import (
	"testing"
	"io/ioutil"
	"encoding/json"
	"fmt"
	"github.com/kyokomi/quick-image-cli/dropbox"
)

func TestReadImageList(t *testing.T) {

	d := NewDropBox("aaaaaaaaaaaa")

	var meta dropbox.Metadata
	metaData, err := ioutil.ReadFile("test/meta.json")
	if err != nil {
		t.Error(err)
	}
	json.Unmarshal(metaData, &meta)

	var a dropbox.AccountInfo
	aData, err := ioutil.ReadFile("test/account_info.json")
	if err != nil {
		t.Error(err)
	}
	json.Unmarshal(aData, &a)

	images, err := d.readImageList(meta, a)
	if err != nil {
		t.Error(err)
	}

	for _, image := range images {
		fmt.Println(image.Name)
	}

	if len(images) != 3 {
		t.Error("images len error")
	}
}

func TestReplacePublicFileName(t *testing.T) {
	fileName := replacePublicFileName("hogehoge/Public/fugafuga")
	if fileName != "hogehoge/fugafuga" {
		t.Errorf("replace error %s", fileName)
	}
}

func TestCreateImageUrl(t *testing.T) {
	imageUrl := createImageUrl("/User/kyokomi/hoge/image.png")
	if imageUrl != (addUrl + "/image.png") {
		t.Errorf("create image url error %s", imageUrl)
	}
}
<|endoftext|>


<commit_before>package pinocchio

import (
  "fmt"
  "math/big"
)

type ECCurve struct {
  N *big.Int
  A *big.Int
  B *big.Int
  Fp *big.Int
  P ECPoint
  Q ECPoint
}

type ECPoint struct {
  X *big.Int
  Y *big.Int
  Infinite bool
}

type DualECDRBG struct {
  curve *ECCurve

  Z *big.Int
  S *big.Int
  StateIndex uint64
  StateBit uint32
}

func NewECCurve(n, a, b, fp, px, py, qx, qy string) *ECCurve {
  curve := ECCurve{big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), ECPoint{}, ECPoint{}}

  curve.N.SetString(n, 10)
  curve.A.SetString(a, 10)
  curve.B.SetString(b, 16)
  curve.Fp.SetString(fp, 10)

  curve.P = ECPoint{big.NewInt(0), big.NewInt(0), false}
  curve.P.X.SetString(px, 16)
  curve.P.Y.SetString(py, 16)

  curve.Q = ECPoint{big.NewInt(0), big.NewInt(0), false}
  curve.Q.X.SetString(qx, 16)
  curve.Q.Y.SetString(qy, 16)

  fmt.Printf("%s\n\n%s\n\n%s\n\n%s\n\n%s\n\n%s\n\n%s\n\n%s\n\n", curve.N.String(), curve.A.String(), curve.B.String(), curve.Fp.String(), curve.P.X.String(), curve.P.Y.String(), curve.Q.X.String(), curve.Q.Y.String())

  return &curve
}

func NewDualECDRBG(curve *ECCurve) *DualECDRBG {
  g := DualECDRBG{curve, big.NewInt(0), big.NewInt(0), 0, 0}

  return &g
}

// Seed is twice security_strength bits long (at least 256)
func (g *DualECDRBG) Seed(seed *big.Int) {
  g.S = seed
  g.generate_number()
}

func (curve *ECCurve) OnCurve(p ECPoint) bool {
  // On curve if (y^2) - (x^3 + ax + b (mod p)) == 0

  // y^2
  y2 := big.NewInt(0)
  y2.Exp(p.Y, big.NewInt(2), nil)
  y2.Mod(y2, curve.Fp)

  // x^3
  x3 := big.NewInt(0)
  x3.Exp(p.X, big.NewInt(3), nil)

  // ax
  ax := big.NewInt(0)
  ax.Mul(p.X, curve.A)

  // x^3 + ax + b (mod p)
  rhs := big.NewInt(0)
  rhs.Add(x3, ax)
  rhs.Add(rhs, curve.B)
  rhs.Mod(rhs, curve.Fp)

  // (y^3 (mod p)) - (x^3 + ax + b (mod p))
  diff := big.NewInt(0)
  diff.Sub(y2, rhs)

  return diff.Cmp(big.NewInt(0)) == 0
}

func (g *DualECDRBG) generate_number() {
  g.StateIndex++
  g.StateBit = 0
  s := g.curve.ScalarMultEllipticalPoint(g.S, g.curve.P)
  if !g.curve.OnCurve(s) {
    fmt.Println("s not on curve")
  }
  z := g.curve.ScalarMultEllipticalPoint(s.X, g.curve.Q)
  if !g.curve.OnCurve(z) {
    fmt.Println("z not on curve")
  }
  g.S = s.X
  g.Z = z.X
}

func (curve *ECCurve) AddEllipticalPoints(p1 ECPoint, p2 ECPoint) ECPoint {
  if p1.X == p2.X && p1.Y == p2.Y {
    return curve.DoubleEllipticalPoint(p1)
  }

  st := big.NewInt(0)
  st.Sub(p2.Y, p1.Y)
  sb := big.NewInt(0)
  sb.Sub(p2.X, p1.X)

  // Multiply by multiplicative inverse, not integer division.
  mi := big.NewInt(0)
  mi.ModInverse(sb, curve.Fp)
  st.Mul(st, mi)

  p3 := ECPoint{big.NewInt(0), big.NewInt(0), false}

  p3.X.Exp(st, big.NewInt(2), nil)
  p3.X.Sub(p3.X, p1.X)
  p3.X.Sub(p3.X, p2.X)

  p3.Y.Sub(p1.X, p3.X)
  p3.Y.Mul(st, p3.Y)
  p3.Y.Sub(p3.Y, p1.Y)

  p3.X.Mod(p3.X, curve.Fp)
  p3.Y.Mod(p3.Y, curve.Fp)

  return p3
}

func (curve *ECCurve) DoubleEllipticalPoint(p1 ECPoint) ECPoint {
  p2 := ECPoint{big.NewInt(0), big.NewInt(0), false}
  s := big.NewInt(0)
  s.Exp(p1.X, big.NewInt(2), nil)
  s.Mul(s, big.NewInt(3))
  s.Add(s, curve.A)
  k := big.NewInt(0)
  k.Mul(big.NewInt(2), p1.Y)

  // Multiply by multiplicative inverse, not integer division.
  mi := big.NewInt(0)
  mi.ModInverse(k, curve.Fp)
  s.Mul(s, mi)

  p2.X.Exp(s, big.NewInt(2), nil)
  px2 := big.NewInt(0)
  px2.Mul(big.NewInt(2), p1.X)
  p2.X.Sub(p2.X, px2)

  p2.Y.Sub(p1.X, p2.X)
  p2.Y.Mul(p2.Y, s)
  p2.Y.Sub(p2.Y, p1.Y)

  p2.X.Mod(p2.X, curve.Fp)
  p2.Y.Mod(p2.Y, curve.Fp)

  return p2
}

func (curve *ECCurve) ScalarMultEllipticalPoint(scalar *big.Int, p1 ECPoint) ECPoint {
  //scalar.Mod(scalar, curve.Fp)

  r := ECPoint{big.NewInt(0), big.NewInt(0), false} // Point at infinity
  r.X.SetString(p1.X.String(), 10)
  r.Y.SetString(p1.Y.String(), 10)

  for i := 0; i < scalar.BitLen(); i++ {
    if curve.OnCurve(r) {
      fmt.Printf("%d on curve\n", i)
    } else {
      fmt.Printf("%d not on curve\n", i)
    }

    if scalar.Bit(i) == 1 {
      r = curve.AddEllipticalPoints(r, p1)
    }
    r = curve.DoubleEllipticalPoint(r)
  }

  return r
}

func (g *DualECDRBG) Bit() uint32 {
  bit := g.Z.Bit(int(g.StateBit))
  g.StateBit++
  if int(g.StateBit) >= g.Z.BitLen() - 16 {
    g.generate_number()
  }
  return uint32(bit)
}

func (g *DualECDRBG) Urand32() uint32 {
  fmt.Println(g.Z.String())
  v := uint32(0)
  for i := 0; i < 32; i++ {
    v = (v<<1) + g.Bit()
  }
  return v
}
<commit_msg>Tidied method names, debugging strange failure of scalar multiplication (operations seem to work outside it).<commit_after>package pinocchio

import (
  "fmt"
  "math/big"
)

type ECCurve struct {
  N *big.Int
  A *big.Int
  B *big.Int
  Fp *big.Int
  P ECPoint
  Q ECPoint
}

type ECPoint struct {
  X *big.Int
  Y *big.Int
  Infinite bool
}

type DualECDRBG struct {
  curve *ECCurve

  Z *big.Int
  S *big.Int
  StateIndex uint64
  StateBit uint32
}

func NewECCurve(n, a, b, fp, px, py, qx, qy string) *ECCurve {
  curve := ECCurve{big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), ECPoint{}, ECPoint{}}

  curve.N.SetString(n, 10)
  curve.A.SetString(a, 10)
  curve.B.SetString(b, 16)
  curve.Fp.SetString(fp, 10)

  curve.P = ECPoint{big.NewInt(0), big.NewInt(0), false}
  curve.P.X.SetString(px, 16)
  curve.P.Y.SetString(py, 16)

  curve.Q = ECPoint{big.NewInt(0), big.NewInt(0), false}
  curve.Q.X.SetString(qx, 16)
  curve.Q.Y.SetString(qy, 16)

  return &curve
}

func NewDualECDRBG(curve *ECCurve) *DualECDRBG {
  g := DualECDRBG{curve, big.NewInt(0), big.NewInt(0), 0, 0}
  // @TODO: Arrange Seed routines.

  return &g
}

// Seed is twice security_strength bits long (at least 256)
func (g *DualECDRBG) Seed(seed *big.Int) {
  g.S = seed
  g.generate_number()
}

func (curve *ECCurve) Satisfied(p ECPoint) bool {
  // On curve if (y^2) - (x^3 + ax + b (mod p)) == 0

  // y^2
  y2 := big.NewInt(0)
  y2.Exp(p.Y, big.NewInt(2), nil)
  y2.Mod(y2, curve.Fp)

  // x^3
  x3 := big.NewInt(0)
  x3.Exp(p.X, big.NewInt(3), nil)

  // ax
  ax := big.NewInt(0)
  ax.Mul(p.X, curve.A)

  // x^3 + ax + b (mod p)
  rhs := big.NewInt(0)
  rhs.Add(x3, ax)
  rhs.Add(rhs, curve.B)
  rhs.Mod(rhs, curve.Fp)

  // (y^3 (mod p)) - (x^3 + ax + b (mod p))
  diff := big.NewInt(0)
  diff.Sub(y2, rhs)

  fmt.Printf("Satisfied?:\nlhs = %d\nrhs = %d\ndiff = %d\n\n", y2, rhs, diff)

  return diff.Cmp(big.NewInt(0)) == 0
}

func (g *DualECDRBG) generate_number() {
  g.StateIndex++
  g.StateBit = 0
  s := g.curve.ScalarMultiply(g.S, g.curve.P)
  if !g.curve.Satisfied(s) {
    fmt.Println("s not on curve")
  }
  z := g.curve.ScalarMultiply(s.X, g.curve.Q)
  if !g.curve.Satisfied(z) {
    fmt.Println("z not on curve")
  }
  g.S = s.X
  g.Z = z.X
}

func (curve *ECCurve) Add(p1 ECPoint, p2 ECPoint) ECPoint {
  if p1.X == p2.X && p1.Y == p2.Y {
    return curve.Double(p1)
  }

  st := big.NewInt(0)
  st.Sub(p2.Y, p1.Y)
  sb := big.NewInt(0)
  sb.Sub(p2.X, p1.X)

  // Multiply by multiplicative inverse, not integer division.
  mi := big.NewInt(0)
  mi.ModInverse(sb, curve.Fp)
  st.Mul(st, mi)

  p3 := ECPoint{big.NewInt(0), big.NewInt(0), false}

  p3.X.Exp(st, big.NewInt(2), nil)
  p3.X.Sub(p3.X, p1.X)
  p3.X.Sub(p3.X, p2.X)

  p3.Y.Sub(p1.X, p3.X)
  p3.Y.Mul(st, p3.Y)
  p3.Y.Sub(p3.Y, p1.Y)

  p3.X.Mod(p3.X, curve.Fp)
  p3.Y.Mod(p3.Y, curve.Fp)

  return p3
}

func (curve *ECCurve) Double(p1 ECPoint) ECPoint {
  p2 := ECPoint{big.NewInt(0), big.NewInt(0), false}
  s := big.NewInt(0)
  s.Exp(p1.X, big.NewInt(2), nil)
  s.Mul(s, big.NewInt(3))
  s.Add(s, curve.A)
  k := big.NewInt(0)
  k.Mul(big.NewInt(2), p1.Y)

  // Multiply by multiplicative inverse, not integer division.
  mi := big.NewInt(0)
  mi.ModInverse(k, curve.Fp)
  s.Mul(s, mi)

  p2.X.Exp(s, big.NewInt(2), nil)
  px2 := big.NewInt(0)
  px2.Mul(big.NewInt(2), p1.X)
  p2.X.Sub(p2.X, px2)

  p2.Y.Sub(p1.X, p2.X)
  p2.Y.Mul(p2.Y, s)
  p2.Y.Sub(p2.Y, p1.Y)

  p2.X.Mod(p2.X, curve.Fp)
  p2.Y.Mod(p2.Y, curve.Fp)

  return p2
}

func (curve *ECCurve) ScalarMultiply(scalar *big.Int, p1 ECPoint) ECPoint {
  //scalar.Mod(scalar, curve.Fp)

  r := ECPoint{big.NewInt(0), big.NewInt(0), false} // Point at infinity
  r.X.SetString(p1.X.String(), 10)
  r.Y.SetString(p1.Y.String(), 10)

  // @TODO: Somehow these operations appear to work with r := p1 or when done
  // outside this method. Something memoryish is wrong?
  for i := 0; i < scalar.BitLen(); i++ {
    if curve.Satisfied(r) {
      fmt.Printf("%d on curve before %d\n", i, scalar.Bit(i))
    } else {
      fmt.Printf("%d not on curve before %d\n", i, scalar.Bit(i))
    }

    if scalar.Bit(i) == 1 {
      r = curve.Add(r, p1)
    }
    if curve.Satisfied(r) {
      fmt.Printf("%d on curve just after %d\n", i, scalar.Bit(i))
    } else {
      fmt.Printf("%d not on curve just after %d\n", i, scalar.Bit(i))
    }
    r = curve.Double(r)

    if curve.Satisfied(r) {
      fmt.Printf("%d on curve after %d\n", i, scalar.Bit(i))
    } else {
      fmt.Printf("%d not on curve after %d\n", i, scalar.Bit(i))
    }
  }

  return r
}

func (g *DualECDRBG) Bit() uint32 {
  bit := g.Z.Bit(int(g.StateBit))
  g.StateBit++
  if int(g.StateBit) >= g.Z.BitLen() - 16 {
    g.generate_number()
  }
  return uint32(bit)
}

func (g *DualECDRBG) Urand32() uint32 {
  fmt.Println(g.Z.String())
  v := uint32(0)
  for i := 0; i < 32; i++ {
    v = (v<<1) + g.Bit()
  }
  return v
}
<|endoftext|>


<commit_before>// Copyright © 2017 NAME HERE <EMAIL ADDRESS>
// 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 e2e

import (
	"context"
	"flag"
	"fmt"
	"os"
	"testing"

	"github.com/matt-tyler/elasticsearch-operator/e2e/suite"
	_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"

	"github.com/matt-tyler/elasticsearch-operator/e2e/gke"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
)

var Kubeconfig string
var Image string
var Up bool
var Down bool

func init() {
	flag.StringVar(&Kubeconfig, "kubeconfig", "", "Location of kubeconfig")
	flag.StringVar(&Image, "image", "gcr.io/schnauzer-163208/elasticsearch-operator:latest", "image under test")
	flag.BoolVar(&Up, "up", false, "")
	flag.BoolVar(&Down, "down", false, "")
}

func TestE2E(t *testing.T) {
	RunE2ETests(t)
}

func RunE2ETests(t *testing.T) {
	flag.Parse()

	clusterID := "e2e-test-cluster"
	ctx := context.Background()
	client := gke.GkeClient{}

	var config *rest.Config

	if Up || Down {
		if err := gke.NewGkeClient(&client, ctx, os.Getenv("PROJECT"), os.Getenv("ZONE")); err != nil {
			panic(err)
		}
	}

	if Up {
		createCluster(client, clusterID)
		cluster, err := client.GetCluster(clusterID)
		if err != nil {
			panic(err)
		}

		config, err = cluster.Config()
		if err != nil {
			panic(err)
		}
	}

	if Down {
		defer deleteCluster(client, clusterID)
	}

	if config == nil {
		var err error
		config, err = buildConfig(Kubeconfig)
		if err != nil {
			panic(err)
		}
	}

	suite.Setup(config, Image)

	RegisterFailHandler(Fail)

	r := make([]Reporter, 0)

	RunSpecsWithDefaultAndCustomReporters(t, "Elasticsearch Operator E2E Suite", r)
}

func buildConfig(kubeconfig string) (*rest.Config, error) {
	if kubeconfig != "" {
		return clientcmd.BuildConfigFromFlags("", kubeconfig)
	}
	return rest.InClusterConfig()
}

func deleteCluster(client gke.GkeClient, clusterID string) {
	fmt.Printf("Deleting Cluster: %v\n", clusterID)
	op, err := client.DeleteCluster(clusterID)
	if err != nil {
		panic(err)
	}
	client.Done(op)
	fmt.Printf("Cluster %v deleted\n", clusterID)
}

func createCluster(client gke.GkeClient, clusterID string) {
	fmt.Printf("Creating cluster: %v\n", clusterID)
	op, err := client.CreateCluster(clusterID)
	if err != nil {
		panic(err)
	}
	client.Done(op)
	fmt.Printf("Cluster %v created\n", clusterID)
}
<commit_msg>Creating a cluster populates kubeconfig<commit_after>// Copyright © 2017 NAME HERE <EMAIL ADDRESS>
// 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 e2e

import (
	"context"
	"encoding/base64"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"testing"

	"github.com/matt-tyler/elasticsearch-operator/e2e/suite"
	_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"

	clientcmdapi "k8s.io/client-go/tools/clientcmd/api"

	"github.com/matt-tyler/elasticsearch-operator/e2e/gke"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
)

var Kubeconfig string
var Image string
var Up bool
var Down bool
var Test bool

func init() {
	flag.StringVar(&Kubeconfig, "kubeconfig", "", "Location of kubeconfig")
	flag.StringVar(&Image, "image", "gcr.io/schnauzer-163208/elasticsearch-operator:latest", "image under test")
	flag.BoolVar(&Up, "up", false, "")
	flag.BoolVar(&Down, "down", false, "")
	flag.BoolVar(&Test, "test", false, "")
}

func TestE2E(t *testing.T) {
	RunE2ETests(t)
}

func RunE2ETests(t *testing.T) {
	flag.Parse()

	clusterID := "e2e-test-cluster"
	ctx := context.Background()
	client := gke.GkeClient{}

	var config *rest.Config

	if Up || Down {
		if err := gke.NewGkeClient(&client, ctx, os.Getenv("PROJECT"), os.Getenv("ZONE")); err != nil {
			panic(err)
		}
	}

	if Up {
		createCluster(client, clusterID)
		cluster, err := client.GetCluster(clusterID)
		if err != nil {
			panic(err)
		}

		config, err = cluster.Config()
		if err != nil {
			panic(err)
		}

		configAccess := clientcmd.NewDefaultClientConfigLoadingRules()
		clientcmd.ModifyConfig(configAccess, *(clientConfig(cluster)), false)
	}

	if Down {
		defer deleteCluster(client, clusterID)
	}

	if !Test {
		return
	}

	if config == nil {
		var err error
		config, err = buildConfig(Kubeconfig)
		if err != nil {
			panic(err)
		}
	}

	suite.Setup(config, Image)

	RegisterFailHandler(Fail)

	r := make([]Reporter, 0)

	RunSpecsWithDefaultAndCustomReporters(t, "Elasticsearch Operator E2E Suite", r)
}

func buildConfig(kubeconfig string) (*rest.Config, error) {
	if kubeconfig != "" {
		return clientcmd.BuildConfigFromFlags("", kubeconfig)
	}
	return rest.InClusterConfig()
}

func deleteCluster(client gke.GkeClient, clusterID string) {
	fmt.Printf("Deleting Cluster: %v\n", clusterID)
	op, err := client.DeleteCluster(clusterID)
	if err != nil {
		panic(err)
	}
	client.Done(op)
	fmt.Printf("Cluster %v deleted\n", clusterID)
}

func createCluster(client gke.GkeClient, clusterID string) {
	fmt.Printf("Creating cluster: %v\n", clusterID)
	op, err := client.CreateCluster(clusterID)
	if err != nil {
		panic(err)
	}
	client.Done(op)
	fmt.Printf("Cluster %v created\n", clusterID)
}

func clientConfig(gc *gke.Cluster) *clientcmdapi.Config {
	gcloudPath, err := exec.LookPath("gcloud")
	if err != nil {
		panic(err)
	}

	config := clientcmdapi.NewConfig()

	cluster := clientcmdapi.NewCluster()

	caCert, err := base64.StdEncoding.DecodeString(gc.Auth.ClusterCaCertificate)
	if err != nil {
		panic(err)
	}

	cluster.CertificateAuthorityData = []byte(caCert)
	cluster.Server = fmt.Sprintf("https://%v", gc.Endpoint)

	context := clientcmdapi.NewContext()
	context.Cluster = "e2e-test-cluster"
	context.AuthInfo = "e2e-test-cluster-user"

	authInfo := clientcmdapi.NewAuthInfo()
	authInfo.AuthProvider = &clientcmdapi.AuthProviderConfig{
		Name: "gcp",
		Config: map[string]string{
			"cmd-args":   "config config-helper --format=json",
			"cmd-path":   gcloudPath,
			"expiry-key": "{.credential.token_expiry}",
			"token-key":  "{.credential.access_token}",
		},
	}

	config.Clusters["e2e-test-cluster"] = cluster
	config.Contexts["e2e-test-cluster-user"] = context
	config.AuthInfos["e2e-test-cluster-user"] = authInfo

	config.CurrentContext = "e2e-test-cluster-user"

	return config
}
<|endoftext|>


<commit_before>/*
Copyright 2017 The Kubernetes Authors.

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 apiextensions

import (
	"fmt"
	"time"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// SetCRDCondition sets the status condition.  It either overwrites the existing one or
// creates a new one
func SetCRDCondition(crd *CustomResourceDefinition, newCondition CustomResourceDefinitionCondition) {
	existingCondition := FindCRDCondition(crd, newCondition.Type)
	if existingCondition == nil {
		newCondition.LastTransitionTime = metav1.NewTime(time.Now())
		crd.Status.Conditions = append(crd.Status.Conditions, newCondition)
		return
	}

	if existingCondition.Status != newCondition.Status {
		existingCondition.Status = newCondition.Status
		existingCondition.LastTransitionTime = newCondition.LastTransitionTime
	}

	existingCondition.Reason = newCondition.Reason
	existingCondition.Message = newCondition.Message
}

// RemoveCRDCondition removes the status condition.
func RemoveCRDCondition(crd *CustomResourceDefinition, conditionType CustomResourceDefinitionConditionType) {
	newConditions := []CustomResourceDefinitionCondition{}
	for _, condition := range crd.Status.Conditions {
		if condition.Type != conditionType {
			newConditions = append(newConditions, condition)
		}
	}
	crd.Status.Conditions = newConditions
}

// FindCRDCondition returns the condition you're looking for or nil
func FindCRDCondition(crd *CustomResourceDefinition, conditionType CustomResourceDefinitionConditionType) *CustomResourceDefinitionCondition {
	for i := range crd.Status.Conditions {
		if crd.Status.Conditions[i].Type == conditionType {
			return &crd.Status.Conditions[i]
		}
	}

	return nil
}

// IsCRDConditionTrue indicates if the condition is present and strictly true
func IsCRDConditionTrue(crd *CustomResourceDefinition, conditionType CustomResourceDefinitionConditionType) bool {
	return IsCRDConditionPresentAndEqual(crd, conditionType, ConditionTrue)
}

// IsCRDConditionFalse indicates if the condition is present and false true
func IsCRDConditionFalse(crd *CustomResourceDefinition, conditionType CustomResourceDefinitionConditionType) bool {
	return IsCRDConditionPresentAndEqual(crd, conditionType, ConditionFalse)
}

// IsCRDConditionPresentAndEqual indicates if the condition is present and equal to the arg
func IsCRDConditionPresentAndEqual(crd *CustomResourceDefinition, conditionType CustomResourceDefinitionConditionType, status ConditionStatus) bool {
	for _, condition := range crd.Status.Conditions {
		if condition.Type == conditionType {
			return condition.Status == status
		}
	}
	return false
}

// IsCRDConditionEquivalent returns true if the lhs and rhs are equivalent except for times
func IsCRDConditionEquivalent(lhs, rhs *CustomResourceDefinitionCondition) bool {
	if lhs == nil && rhs == nil {
		return true
	}
	if lhs == nil || rhs == nil {
		return false
	}

	return lhs.Message == rhs.Message && lhs.Reason == rhs.Reason && lhs.Status == rhs.Status && lhs.Type == rhs.Type
}

// CRDHasFinalizer returns true if the finalizer is in the list
func CRDHasFinalizer(crd *CustomResourceDefinition, needle string) bool {
	for _, finalizer := range crd.Finalizers {
		if finalizer == needle {
			return true
		}
	}

	return false
}

// CRDRemoveFinalizer removes the finalizer if present
func CRDRemoveFinalizer(crd *CustomResourceDefinition, needle string) {
	newFinalizers := []string{}
	for _, finalizer := range crd.Finalizers {
		if finalizer != needle {
			newFinalizers = append(newFinalizers, finalizer)
		}
	}
	crd.Finalizers = newFinalizers
}

// HasServedCRDVersion returns true if `version` is in the list of CRD's versions and the Served flag is set.
func HasServedCRDVersion(crd *CustomResourceDefinition, version string) bool {
	for _, v := range crd.Spec.Versions {
		if v.Name == version {
			return v.Served
		}
	}
	return false
}

// GetCRDStorageVersion returns the storage version for given CRD.
func GetCRDStorageVersion(crd *CustomResourceDefinition) (string, error) {
	for _, v := range crd.Spec.Versions {
		if v.Storage {
			return v.Name, nil
		}
	}
	// This should not happened if crd is valid
	return "", fmt.Errorf("invalid CustomResourceDefinition, no storage version")
}

func IsStoredVersion(crd *CustomResourceDefinition, version string) bool {
	for _, v := range crd.Status.StoredVersions {
		if version == v {
			return true
		}
	}
	return false
}
<commit_msg>UPSTREAM: 74067: apiextensions-apiserver: make API helpers reusable<commit_after>/*
Copyright 2017 The Kubernetes Authors.

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 apiextensions

import (
	"fmt"
	"time"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var swaggerMetadataDescriptions = metav1.ObjectMeta{}.SwaggerDoc()

// SetCRDCondition sets the status condition.  It either overwrites the existing one or
// creates a new one
func SetCRDCondition(crd *CustomResourceDefinition, newCondition CustomResourceDefinitionCondition) {
	existingCondition := FindCRDCondition(crd, newCondition.Type)
	if existingCondition == nil {
		newCondition.LastTransitionTime = metav1.NewTime(time.Now())
		crd.Status.Conditions = append(crd.Status.Conditions, newCondition)
		return
	}

	if existingCondition.Status != newCondition.Status {
		existingCondition.Status = newCondition.Status
		existingCondition.LastTransitionTime = newCondition.LastTransitionTime
	}

	existingCondition.Reason = newCondition.Reason
	existingCondition.Message = newCondition.Message
}

// RemoveCRDCondition removes the status condition.
func RemoveCRDCondition(crd *CustomResourceDefinition, conditionType CustomResourceDefinitionConditionType) {
	newConditions := []CustomResourceDefinitionCondition{}
	for _, condition := range crd.Status.Conditions {
		if condition.Type != conditionType {
			newConditions = append(newConditions, condition)
		}
	}
	crd.Status.Conditions = newConditions
}

// FindCRDCondition returns the condition you're looking for or nil
func FindCRDCondition(crd *CustomResourceDefinition, conditionType CustomResourceDefinitionConditionType) *CustomResourceDefinitionCondition {
	for i := range crd.Status.Conditions {
		if crd.Status.Conditions[i].Type == conditionType {
			return &crd.Status.Conditions[i]
		}
	}

	return nil
}

// IsCRDConditionTrue indicates if the condition is present and strictly true
func IsCRDConditionTrue(crd *CustomResourceDefinition, conditionType CustomResourceDefinitionConditionType) bool {
	return IsCRDConditionPresentAndEqual(crd, conditionType, ConditionTrue)
}

// IsCRDConditionFalse indicates if the condition is present and false true
func IsCRDConditionFalse(crd *CustomResourceDefinition, conditionType CustomResourceDefinitionConditionType) bool {
	return IsCRDConditionPresentAndEqual(crd, conditionType, ConditionFalse)
}

// IsCRDConditionPresentAndEqual indicates if the condition is present and equal to the arg
func IsCRDConditionPresentAndEqual(crd *CustomResourceDefinition, conditionType CustomResourceDefinitionConditionType, status ConditionStatus) bool {
	for _, condition := range crd.Status.Conditions {
		if condition.Type == conditionType {
			return condition.Status == status
		}
	}
	return false
}

// IsCRDConditionEquivalent returns true if the lhs and rhs are equivalent except for times
func IsCRDConditionEquivalent(lhs, rhs *CustomResourceDefinitionCondition) bool {
	if lhs == nil && rhs == nil {
		return true
	}
	if lhs == nil || rhs == nil {
		return false
	}

	return lhs.Message == rhs.Message && lhs.Reason == rhs.Reason && lhs.Status == rhs.Status && lhs.Type == rhs.Type
}

// CRDHasFinalizer returns true if the finalizer is in the list
func CRDHasFinalizer(crd *CustomResourceDefinition, needle string) bool {
	for _, finalizer := range crd.Finalizers {
		if finalizer == needle {
			return true
		}
	}

	return false
}

// CRDRemoveFinalizer removes the finalizer if present
func CRDRemoveFinalizer(crd *CustomResourceDefinition, needle string) {
	newFinalizers := []string{}
	for _, finalizer := range crd.Finalizers {
		if finalizer != needle {
			newFinalizers = append(newFinalizers, finalizer)
		}
	}
	crd.Finalizers = newFinalizers
}

// HasServedCRDVersion returns true if `version` is in the list of CRD's versions and the Served flag is set.
func HasServedCRDVersion(crd *CustomResourceDefinition, version string) bool {
	for _, v := range crd.Spec.Versions {
		if v.Name == version {
			return v.Served
		}
	}
	return false
}

// GetCRDStorageVersion returns the storage version for given CRD.
func GetCRDStorageVersion(crd *CustomResourceDefinition) (string, error) {
	for _, v := range crd.Spec.Versions {
		if v.Storage {
			return v.Name, nil
		}
	}
	// This should not happened if crd is valid
	return "", fmt.Errorf("invalid CustomResourceDefinition, no storage version")
}

func IsStoredVersion(crd *CustomResourceDefinition, version string) bool {
	for _, v := range crd.Status.StoredVersions {
		if version == v {
			return true
		}
	}
	return false
}

// GetSchemaForVersion returns the validation schema for given version in given CRD.
func GetSchemaForVersion(crd *CustomResourceDefinition, version string) (*CustomResourceValidation, error) {
	if !HasPerVersionSchema(crd.Spec.Versions) {
		return crd.Spec.Validation, nil
	}
	if crd.Spec.Validation != nil {
		return nil, fmt.Errorf("malformed CustomResourceDefinition %s version %s: top-level and per-version schemas must be mutual exclusive", crd.Name, version)
	}
	// for _, v := range crd.Spec.Versions {
	// 	if version == v.Name {
	// 		return v.Schema, nil
	// 	}
	// }
	return nil, fmt.Errorf("version %s not found in CustomResourceDefinition: %v", version, crd.Name)
}

// GetSubresourcesForVersion returns the subresources for given version in given CRD.
func GetSubresourcesForVersion(crd *CustomResourceDefinition, version string) (*CustomResourceSubresources, error) {
	if !HasPerVersionSubresources(crd.Spec.Versions) {
		return crd.Spec.Subresources, nil
	}
	if crd.Spec.Subresources != nil {
		return nil, fmt.Errorf("malformed CustomResourceDefinition %s version %s: top-level and per-version subresources must be mutual exclusive", crd.Name, version)
	}
	// for _, v := range crd.Spec.Versions {
	// 	if version == v.Name {
	// 		return v.Subresources, nil
	// 	}
	// }
	return nil, fmt.Errorf("version %s not found in CustomResourceDefinition: %v", version, crd.Name)
}

// GetColumnsForVersion returns the columns for given version in given CRD.
// NOTE: the newly logically-defaulted columns is not pointing to the original CRD object.
// One cannot mutate the original CRD columns using the logically-defaulted columns. Please iterate through
// the original CRD object instead.
func GetColumnsForVersion(crd *CustomResourceDefinition, version string) ([]CustomResourceColumnDefinition, error) {
	if !HasPerVersionColumns(crd.Spec.Versions) {
		return serveDefaultColumnsIfEmpty(crd.Spec.AdditionalPrinterColumns), nil
	}
	if len(crd.Spec.AdditionalPrinterColumns) > 0 {
		return nil, fmt.Errorf("malformed CustomResourceDefinition %s version %s: top-level and per-version additionalPrinterColumns must be mutual exclusive", crd.Name, version)
	}
	// for _, v := range crd.Spec.Versions {
	// 	if version == v.Name {
	// 		return serveDefaultColumnsIfEmpty(v.AdditionalPrinterColumns), nil
	// 	}
	// }
	return nil, fmt.Errorf("version %s not found in CustomResourceDefinition: %v", version, crd.Name)
}

// HasPerVersionSchema returns true if a CRD uses per-version schema.
func HasPerVersionSchema(versions []CustomResourceDefinitionVersion) bool {
	// for _, v := range versions {
	// 	if v.Schema != nil {
	// 		return true
	// 	}
	// }
	return false
}

// HasPerVersionSubresources returns true if a CRD uses per-version subresources.
func HasPerVersionSubresources(versions []CustomResourceDefinitionVersion) bool {
	// for _, v := range versions {
	// 	if v.Subresources != nil {
	// 		return true
	// 	}
	// }
	return false
}

// HasPerVersionColumns returns true if a CRD uses per-version columns.
func HasPerVersionColumns(versions []CustomResourceDefinitionVersion) bool {
	// for _, v := range versions {
	// 	if len(v.AdditionalPrinterColumns) > 0 {
	// 		return true
	// 	}
	// }
	return false
}

// serveDefaultColumnsIfEmpty applies logically defaulting to columns, if the input columns is empty.
// NOTE: in this way, the newly logically-defaulted columns is not pointing to the original CRD object.
// One cannot mutate the original CRD columns using the logically-defaulted columns. Please iterate through
// the original CRD object instead.
func serveDefaultColumnsIfEmpty(columns []CustomResourceColumnDefinition) []CustomResourceColumnDefinition {
	if len(columns) > 0 {
		return columns
	}
	return []CustomResourceColumnDefinition{
		{Name: "Age", Type: "date", Description: swaggerMetadataDescriptions["creationTimestamp"], JSONPath: ".metadata.creationTimestamp"},
	}
}

// HasVersionServed returns true if given CRD has given version served
func HasVersionServed(crd *CustomResourceDefinition, version string) bool {
	for _, v := range crd.Spec.Versions {
		if !v.Served || v.Name != version {
			continue
		}
		return true
	}
	return false
}
<|endoftext|>