예제 #1
0
func (command *DestroyPipelineCommand) Execute(args []string) error {
	client, err := rc.TargetClient(Fly.Target)
	if err != nil {
		return err
	}
	err = rc.ValidateClient(client, Fly.Target)
	if err != nil {
		return err
	}

	pipelineName := command.Pipeline
	fmt.Printf("!!! this will remove all data for pipeline `%s`\n\n", pipelineName)

	confirm := command.SkipInteractive
	if !confirm {
		err := interact.NewInteraction("are you sure?").Resolve(&confirm)
		if err != nil || !confirm {
			fmt.Println("bailing out")
			return err
		}
	}

	found, err := client.DeletePipeline(pipelineName)
	if err != nil {
		return err
	}

	if !found {
		fmt.Printf("`%s` does not exist\n", pipelineName)
	} else {
		fmt.Printf("`%s` deleted\n", pipelineName)
	}

	return nil
}
예제 #2
0
func (example Example) Run() {
	input := bytes.NewBufferString(example.Input)
	output := gbytes.NewBuffer()

	interaction := interact.NewInteraction(example.Prompt, choices...)
	interaction.Input = input
	interaction.Output = output

	resolveErr := interaction.Resolve(destination)

	if example.ExpectedErr != nil {
		Expect(resolveErr).To(Equal(example.ExpectedErr))
	} else {
		Expect(resolveErr).ToNot(HaveOccurred())
	}

	var finalDestination interface{}
	switch d := destination.(type) {
	case interact.RequiredDestination:
		finalDestination = d.Destination
	default:
		finalDestination = destination
	}

	Expect(reflect.Indirect(reflect.ValueOf(finalDestination)).Interface()).To(Equal(example.ExpectedAnswer))

	Expect(output.Contents()).To(Equal([]byte(example.ExpectedOutput)))
}
예제 #3
0
파일: ui.go 프로젝트: sebrandon1/cli
// DisplayBoolPrompt outputs the prompt and waits for user input. It only
// allows for a boolean response. A default boolean response can be set with
// defaultResponse.
func (ui *UI) DisplayBoolPrompt(prompt string, defaultResponse bool) (bool, error) {
	response := defaultResponse
	fullPrompt := fmt.Sprintf("%s%s", prompt, ui.colorize(">>", cyan, true))
	interactivePrompt := interact.NewInteraction(fullPrompt)
	interactivePrompt.Input = ui.In
	interactivePrompt.Output = ui.Out
	err := interactivePrompt.Resolve(&response)
	return response, err
}
예제 #4
0
파일: login.go 프로젝트: zankich/fly
func (command *LoginCommand) Execute(args []string) error {
	var connection concourse.Connection
	var err error

	if command.ATCURL != "" {
		connection, err = rc.NewConnection(command.ATCURL, command.Insecure)
	} else {
		connection, err = rc.CommandTargetConnection(Fly.Target, &command.Insecure)
	}

	if err != nil {
		return err
	}

	client := concourse.NewClient(connection)

	authMethods, err := client.ListAuthMethods()
	if err != nil {
		return err
	}

	var chosenMethod atc.AuthMethod
	switch len(authMethods) {
	case 0:
		fmt.Println("no auth methods configured; updating target data")
		err := rc.SaveTarget(
			Fly.Target,
			connection.URL(),
			command.Insecure,
			&rc.TargetToken{},
		)

		if err != nil {
			return err
		}
		return nil
	case 1:
		chosenMethod = authMethods[0]
	default:
		choices := make([]interact.Choice, len(authMethods))
		for i, method := range authMethods {
			choices[i] = interact.Choice{
				Display: method.DisplayName,
				Value:   method,
			}
		}

		err = interact.NewInteraction("choose an auth method", choices...).Resolve(&chosenMethod)
		if err != nil {
			return err
		}
	}

	return command.loginWith(chosenMethod, connection)
}
예제 #5
0
파일: atc_config.go 프로젝트: aemengo/fly
func (atcConfig ATCConfig) ApplyConfigInteraction() bool {
	if atcConfig.SkipInteraction {
		return true
	}

	confirm := false
	err := interact.NewInteraction("apply configuration?").Resolve(&confirm)
	if err != nil {
		return false
	}

	return confirm
}
예제 #6
0
파일: set_team.go 프로젝트: ArthurHlt/fly
func (command *SetTeamCommand) Execute([]string) error {
	client, err := rc.TargetClient(Fly.Target)
	if err != nil {
		return err
	}
	err = rc.ValidateClient(client, Fly.Target)
	if err != nil {
		return err
	}

	hasBasicAuth, hasGitHubAuth, err := command.ValidateFlags()
	if err != nil {
		return err
	}

	fmt.Println("Team Name:", command.TeamName)
	fmt.Println("Basic Auth:", authMethodStatusDescription(hasBasicAuth))
	fmt.Println("GitHub Auth:", authMethodStatusDescription(hasGitHubAuth))

	confirm := false
	err = interact.NewInteraction("apply configuration?").Resolve(&confirm)
	if err != nil {
		return err
	}

	if !confirm {
		displayhelpers.Failf("bailing out")
	}

	team := command.GetTeam(hasBasicAuth, hasGitHubAuth)

	_, _, _, err = client.SetTeam(command.TeamName, team)
	if err != nil {
		return err
	}

	fmt.Println("team created")
	return nil
}
예제 #7
0
파일: atc_config.go 프로젝트: mmb/fly
func diff(existingConfig atc.Config, newConfig atc.Config) {
	indent := gexec.NewPrefixedWriter("  ", os.Stdout)

	groupDiffs := diffIndices(GroupIndex(existingConfig.Groups), GroupIndex(newConfig.Groups))
	if len(groupDiffs) > 0 {
		fmt.Println("groups:")

		for _, diff := range groupDiffs {
			diff.Render(indent, "group")
		}
	}

	resourceDiffs := diffIndices(ResourceIndex(existingConfig.Resources), ResourceIndex(newConfig.Resources))
	if len(resourceDiffs) > 0 {
		fmt.Println("resources:")

		for _, diff := range resourceDiffs {
			diff.Render(indent, "resource")
		}
	}

	jobDiffs := diffIndices(JobIndex(existingConfig.Jobs), JobIndex(newConfig.Jobs))
	if len(jobDiffs) > 0 {
		fmt.Println("jobs:")

		for _, diff := range jobDiffs {
			diff.Render(indent, "job")
		}
	}

	confirm := false
	err := interact.NewInteraction("apply configuration?").Resolve(&confirm)
	if err != nil || !confirm {
		fmt.Println("bailing out")
		os.Exit(1)
	}
}
예제 #8
0
파일: main.go 프로젝트: vito/go-interact
func main() {
	// Well? [yN]:
	boolAnsFalseDefault := false
	err := interact.NewInteraction("Well?").Resolve(&boolAnsFalseDefault)
	if err != nil {
		fatal(err)
	}

	fmt.Println(boolAnsFalseDefault)

	// Well? [Yn]:
	boolAnsTrueDefault := true
	err = interact.NewInteraction("Well?").Resolve(&boolAnsTrueDefault)
	if err != nil {
		fatal(err)
	}

	fmt.Println(boolAnsTrueDefault)

	// Well? [yn]:
	var boolAnsNoDefault bool
	err = interact.NewInteraction("Well?").Resolve(interact.Required(&boolAnsNoDefault))
	if err != nil {
		fatal(err)
	}

	fmt.Println(boolAnsNoDefault)

	// Message (hello):
	strAnsDefault := "hello"
	err = interact.NewInteraction("Message").Resolve(&strAnsDefault)
	if err != nil {
		fatal(err)
	}

	fmt.Println(strAnsDefault)

	// Message ():
	var strAnsEmptyDefault string
	err = interact.NewInteraction("Message").Resolve(&strAnsEmptyDefault)
	if err != nil {
		fatal(err)
	}

	fmt.Println(strAnsEmptyDefault)

	// Message:
	var strAnsNoDefault string
	err = interact.NewInteraction("Message").Resolve(interact.Required(&strAnsNoDefault))
	if err != nil {
		fatal(err)
	}

	fmt.Println(strAnsNoDefault)

	numbers := []string{"uno", "dos", "tres"}

	// 1: One
	// 2: Two
	// 3: Three
	// Choose a number:
	var chosenFoo string
	err = interact.NewInteraction(
		"Choose a number",
		interact.Choice{Display: "One", Value: numbers[0]},
		interact.Choice{Display: "Two", Value: numbers[1]},
		interact.Choice{Display: "Three", Value: numbers[2]},
	).Resolve(&chosenFoo)
	if err != nil {
		fatal(err)
	}

	fmt.Println(chosenFoo)

	// 1: One
	// 2: Two
	// 3: Three
	// Choose a number (2):
	chosenFooWithDefault := "dos"
	err = interact.NewInteraction(
		"Choose a number",
		interact.Choice{Display: "One", Value: numbers[0]},
		interact.Choice{Display: "Two", Value: numbers[1]},
		interact.Choice{Display: "Three", Value: numbers[2]},
	).Resolve(&chosenFooWithDefault)
	if err != nil {
		fatal(err)
	}

	fmt.Println(chosenFooWithDefault)

	// 1. One
	// 2. Two
	// 3. Three
	// 4. none
	// Choose a number (4):
	var chosenFooOptional *string
	err = interact.NewInteraction(
		"Choose a number",
		interact.Choice{Display: "One", Value: &numbers[0]},
		interact.Choice{Display: "Two", Value: &numbers[1]},
		interact.Choice{Display: "Three", Value: &numbers[2]},
		interact.Choice{Display: "none", Value: nil},
	).Resolve(&chosenFooOptional)
	if err != nil {
		fatal(err)
	}

	fmt.Println(chosenFooOptional)

	// Username:
	var username string
	err = interact.NewInteraction("Username").Resolve(interact.Required(&username))
	if err != nil {
		fatal(err)
	}

	fmt.Println(username)

	// Password:
	var password interact.Password
	err = interact.NewInteraction("Password").Resolve(interact.Required(&password))
	if err != nil {
		fatal(err)
	}

	fmt.Println(password)

	// Interrupt:
	var ctrlCTest string
	err = interact.NewInteraction("Interrupt").Resolve(interact.Required(&ctrlCTest))
	if err != nil {
		fmt.Println(err)
	}
}
예제 #9
0
파일: hijack.go 프로젝트: mmb/fly
func (command *HijackCommand) Execute(args []string) error {
	target, err := rc.SelectTarget(Fly.Target)
	if err != nil {
		log.Fatalln(err)
		return nil
	}

	containers := getContainerIDs(command)

	var id string
	if len(containers) == 0 {
		fmt.Fprintln(os.Stderr, "no containers matched your search parameters! they may have expired if your build hasn't recently finished")
		os.Exit(1)
	} else if len(containers) > 1 {
		var choices []interact.Choice
		for _, container := range containers {
			var infos []string
			if container.PipelineName != "" {
				infos = append(infos, fmt.Sprintf("pipeline: %s", container.PipelineName))
			}

			if container.BuildID != 0 {
				infos = append(infos, fmt.Sprintf("build id: %d", container.BuildID))
			}

			infos = append(infos, fmt.Sprintf("type: %s", container.Type))
			infos = append(infos, fmt.Sprintf("name: %s", container.Name))

			choices = append(choices, interact.Choice{
				Display: strings.Join(infos, ", "),
				Value:   container.ID,
			})
		}

		err = interact.NewInteraction("choose a container", choices...).Resolve(&id)
		if err == io.EOF {
			os.Exit(0)
		}

		if err != nil {
			return err
		}
	} else {
		id = containers[0].ID
	}

	path, args := remoteCommand(args)
	privileged := true

	reqGenerator := rata.NewRequestGenerator(target.API, atc.Routes)
	tlsConfig := &tls.Config{InsecureSkipVerify: target.Insecure}

	var ttySpec *atc.HijackTTYSpec
	rows, cols, err := pty.Getsize(os.Stdin)
	if err == nil {
		ttySpec = &atc.HijackTTYSpec{
			WindowSize: atc.HijackWindowSize{
				Columns: cols,
				Rows:    rows,
			},
		}
	}

	spec := atc.HijackProcessSpec{
		Path: path,
		Args: args,
		Env:  []string{"TERM=" + os.Getenv("TERM")},
		User: "******",

		Privileged: privileged,
		TTY:        ttySpec,
	}

	hijackReq := constructRequest(reqGenerator, spec, id, target.Token)
	hijackResult := performHijack(hijackReq, tlsConfig)
	os.Exit(hijackResult)

	return nil
}
예제 #10
0
파일: login.go 프로젝트: zankich/fly
func (command *LoginCommand) loginWith(method atc.AuthMethod, connection concourse.Connection) error {
	var token atc.AuthToken

	switch method.Type {
	case atc.AuthTypeOAuth:
		fmt.Println("navigate to the following URL in your browser:")
		fmt.Println("")
		fmt.Printf("    %s\n", method.AuthURL)
		fmt.Println("")

		for {
			var tokenStr string

			err := interact.NewInteraction("enter token").Resolve(interact.Required(&tokenStr))
			if err != nil {
				return err
			}

			segments := strings.SplitN(tokenStr, " ", 2)
			if len(segments) != 2 {
				fmt.Println("token must be of the format 'TYPE VALUE', e.g. 'Bearer ...'")
				continue
			}

			token.Type = segments[0]
			token.Value = segments[1]

			break
		}

	case atc.AuthTypeBasic:
		var username string
		err := interact.NewInteraction("username").Resolve(interact.Required(&username))
		if err != nil {
			return err
		}

		var password interact.Password
		err = interact.NewInteraction("password").Resolve(interact.Required(&password))
		if err != nil {
			return err
		}

		newUnauthedClient, err := rc.NewConnection(connection.URL(), command.Insecure)
		if err != nil {
			return err
		}

		basicAuthClient, err := concourse.NewConnection(
			newUnauthedClient.URL(),
			&http.Client{
				Transport: basicAuthTransport{
					username: username,
					password: string(password),
					base:     newUnauthedClient.HTTPClient().Transport,
				},
			},
		)
		if err != nil {
			return err
		}

		client := concourse.NewClient(basicAuthClient)

		token, err = client.AuthToken()
		if err != nil {
			return err
		}
	}

	err := rc.SaveTarget(
		Fly.Target,
		connection.URL(),
		command.Insecure,
		&rc.TargetToken{
			Type:  token.Type,
			Value: token.Value,
		},
	)
	if err != nil {
		return err
	}

	fmt.Println("token saved")

	return nil
}
예제 #11
0
파일: hijack.go 프로젝트: ArthurHlt/fly
func (command *HijackCommand) Execute(args []string) error {
	target, err := rc.SelectTarget(Fly.Target)
	if err != nil {
		return err
	}

	containers, err := getContainerIDs(command)
	if err != nil {
		return err
	}

	var chosenContainer atc.Container
	if len(containers) == 0 {
		displayhelpers.Failf("no containers matched your search parameters!\n\nthey may have expired if your build hasn't recently finished.")
	} else if len(containers) > 1 {
		var choices []interact.Choice
		for _, container := range containers {
			var infos []string

			if container.BuildID != 0 {
				if container.JobName != "" {
					infos = append(infos, fmt.Sprintf("build #%s", container.BuildName))
				} else {
					infos = append(infos, fmt.Sprintf("build id: %d", container.BuildID))
				}
			}

			if container.StepType != "" {
				infos = append(infos, fmt.Sprintf("step: %s", container.StepName))
				infos = append(infos, fmt.Sprintf("type: %s", container.StepType))
			} else if container.ResourceName != "" {
				infos = append(infos, fmt.Sprintf("resource: %s", container.ResourceName))
				infos = append(infos, "type: check")
			} else {
				infos = append(infos, fmt.Sprintf("step: %s", container.StepName))
				infos = append(infos, "type: check")
			}

			if len(container.Attempts) != 0 {
				attempt := SliceItoa(container.Attempts)
				infos = append(infos, fmt.Sprintf("attempt: %s", attempt))
			}

			choices = append(choices, interact.Choice{
				Display: strings.Join(infos, ", "),
				Value:   container,
			})
		}

		err = interact.NewInteraction("choose a container", choices...).Resolve(&chosenContainer)
		if err == io.EOF {
			return nil
		}

		if err != nil {
			return err
		}
	} else {
		chosenContainer = containers[0]
	}

	path, args := remoteCommand(args)
	privileged := true

	reqGenerator := rata.NewRequestGenerator(target.API, atc.Routes)
	tlsConfig := &tls.Config{InsecureSkipVerify: target.Insecure}

	var ttySpec *atc.HijackTTYSpec
	rows, cols, err := pty.Getsize(os.Stdin)
	if err == nil {
		ttySpec = &atc.HijackTTYSpec{
			WindowSize: atc.HijackWindowSize{
				Columns: cols,
				Rows:    rows,
			},
		}
	}

	envVariables := append(chosenContainer.EnvironmentVariables, "TERM="+os.Getenv("TERM"))

	spec := atc.HijackProcessSpec{
		Path: path,
		Args: args,
		Env:  envVariables,
		User: chosenContainer.User,
		Dir:  chosenContainer.WorkingDirectory,

		Privileged: privileged,
		TTY:        ttySpec,
	}

	result, err := func() (int, error) { // so the term.Restore() can run before the os.Exit()
		var in io.Reader

		term, err := pty.OpenRawTerm()
		if err == nil {
			defer term.Restore()

			in = term
		} else {
			in = os.Stdin
		}

		io := hijacker.ProcessIO{
			In:  in,
			Out: os.Stdout,
			Err: os.Stderr,
		}

		h := hijacker.New(tlsConfig, reqGenerator, target.Token)

		return h.Hijack(chosenContainer.ID, spec, io)
	}()

	if err != nil {
		return err
	}

	os.Exit(result)

	return nil
}
예제 #12
0
파일: login.go 프로젝트: aemengo/fly
func (command *LoginCommand) Execute(args []string) error {
	if isURL(Fly.Target) {
		return errors.New("name for the target must be specified (--target/-t)")
	}

	var connection concourse.Connection
	var err error

	if command.ATCURL != "" {
		connection, err = rc.NewConnection(command.ATCURL, command.Insecure)
	} else {
		connection, err = rc.CommandTargetConnection(Fly.Target, &command.Insecure)
	}
	if err != nil {
		return err
	}

	client := concourse.NewClient(connection)

	authMethods, err := client.ListAuthMethods()
	if err != nil {
		return err
	}

	var chosenMethod atc.AuthMethod
	if command.Username != "" && command.Password != "" {
		for _, method := range authMethods {
			if method.Type == atc.AuthTypeBasic {
				chosenMethod = method
				break
			}
		}

		if chosenMethod.Type == "" {
			return errors.New("basic auth is not available")
		}
	} else {
		switch len(authMethods) {
		case 0:
			return command.saveTarget(
				connection.URL(),
				&rc.TargetToken{},
			)
		case 1:
			chosenMethod = authMethods[0]
		default:
			choices := make([]interact.Choice, len(authMethods))
			for i, method := range authMethods {
				choices[i] = interact.Choice{
					Display: method.DisplayName,
					Value:   method,
				}
			}

			err = interact.NewInteraction("choose an auth method", choices...).Resolve(&chosenMethod)
			if err != nil {
				return err
			}
		}
	}

	return command.loginWith(chosenMethod, connection)
}
예제 #13
0
import (
	"github.com/kr/pty"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"github.com/vito/go-interact/interact"
)

var _ = Describe("User IO", func() {
	Describe("fetching input from the user", func() {
		Context("when the terminal reports Ctrl-C was pressed", func() {
			It("returns ErrKeyboardInterrupt", func() {
				aPty, tty, err := pty.Open()
				Expect(err).NotTo(HaveOccurred())

				interaction := interact.NewInteraction("What is the air-speed of a Swallow?")
				interaction.Input = aPty
				interaction.Output = aPty

				go func() {
					defer GinkgoRecover()

					_, err = tty.Write([]byte{03})
					Expect(err).NotTo(HaveOccurred())
				}()

				var thing string
				err = interaction.Resolve(&thing)

				Expect(err).To(Equal(interact.ErrKeyboardInterrupt))
			})
예제 #14
0
파일: login.go 프로젝트: ArthurHlt/fly
func (command *LoginCommand) loginWith(method atc.AuthMethod, client concourse.Client) error {
	var token atc.AuthToken

	switch method.Type {
	case atc.AuthTypeOAuth:
		fmt.Println("navigate to the following URL in your browser:")
		fmt.Println("")
		fmt.Printf("    %s\n", method.AuthURL)
		fmt.Println("")

		for {
			var tokenStr string

			err := interact.NewInteraction("enter token").Resolve(interact.Required(&tokenStr))
			if err != nil {
				return err
			}

			segments := strings.SplitN(tokenStr, " ", 2)
			if len(segments) != 2 {
				fmt.Println("token must be of the format 'TYPE VALUE', e.g. 'Bearer ...'")
				continue
			}

			token.Type = segments[0]
			token.Value = segments[1]

			break
		}

	case atc.AuthTypeBasic:
		var username string
		if command.Username != "" {
			username = command.Username
		} else {
			err := interact.NewInteraction("username").Resolve(interact.Required(&username))
			if err != nil {
				return err
			}
		}

		var password string
		if command.Password != "" {
			password = command.Password
		} else {
			var interactivePassword interact.Password
			err := interact.NewInteraction("password").Resolve(interact.Required(&interactivePassword))
			if err != nil {
				return err
			}
			password = string(interactivePassword)
		}

		newUnauthedClient := rc.NewUnauthenticatedClient(client.URL(), command.Insecure)

		basicAuthClient := concourse.NewClient(
			newUnauthedClient.URL(),
			&http.Client{
				Transport: basicAuthTransport{
					username: username,
					password: password,
					base:     newUnauthedClient.HTTPClient().Transport,
				},
			},
		)

		var err error
		token, err = basicAuthClient.AuthToken()
		if err != nil {
			return err
		}
	}

	return command.saveTarget(
		client.URL(),
		&rc.TargetToken{
			Type:  token.Type,
			Value: token.Value,
		},
	)
}